Skip to content

Commit 0d7bc4d

Browse files
committed
[Frontend] Add some printing/vistation options to swift-synthesize-interface.
The `-include-submodules` flag causes the synthesized interface to include implicit Clang submodules of the module being printed. Since these are automatically made visible when importing the corresponding top-level module, it's often useful to have them present in the same synthesized Swift interface instead of having to make separate invocations to get each submodule separately. The `-print-fully-qualified-types` causes type names to be printed with full module qualification. This is useful when using the synthesized interface for some other kind of analysis, because it ensures that all type references explicitly indicate which module they came from, instead of having to guess scoping and import resolution rules to figure out which module a reference comes from.
1 parent aab880d commit 0d7bc4d

File tree

8 files changed

+90
-3
lines changed

8 files changed

+90
-3
lines changed

include/swift/Option/Options.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,15 @@ def omit_extension_block_symbols: Flag<["-"], "omit-extension-block-symbols">,
16701670
NoInteractiveOption, SupplementaryOutput, HelpHidden]>,
16711671
HelpText<"Directly associate members and conformances with the extended nominal when generating symbol graphs instead of emitting 'swift.extension' symbols for extensions to external types">;
16721672

1673+
// swift-synthesize-interface-only options
1674+
def include_submodules : Flag<["-"], "include-submodules">,
1675+
Flags<[NoDriverOption, SwiftSynthesizeInterfaceOption]>,
1676+
HelpText<"Also print the declarations synthesized for any Clang submodules">;
1677+
1678+
def print_fully_qualified_types : Flag<["-"], "print-fully-qualified-types">,
1679+
Flags<[NoDriverOption, SwiftSynthesizeInterfaceOption]>,
1680+
HelpText<"Always print fully qualified type names">;
1681+
16731682
// swift-symbolgraph-extract-only options
16741683
def output_dir : Separate<["-"], "output-dir">,
16751684
Flags<[NoDriverOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption,

lib/DriverTool/swift_synthesize_interface_main.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,19 @@ int swift_synthesize_interface_main(ArrayRef<const char *> Args,
200200
return EXIT_FAILURE;
201201
}
202202

203-
StreamPrinter printer(fs);
204203
PrintOptions printOpts =
205204
PrintOptions::printModuleInterface(/*printFullConvention=*/true);
206-
ide::printModuleInterface(M, /*GroupNames=*/{},
207-
/*TraversalOptions=*/std::nullopt, printer,
205+
if (ParsedArgs.hasArg(OPT_print_fully_qualified_types)) {
206+
printOpts.FullyQualifiedTypes = true;
207+
}
208+
209+
swift::OptionSet<swift::ide::ModuleTraversal> traversalOpts = std::nullopt;
210+
if (ParsedArgs.hasArg(OPT_include_submodules)) {
211+
traversalOpts = swift::ide::ModuleTraversal::VisitSubmodules;
212+
}
213+
214+
StreamPrinter printer(fs);
215+
ide::printModuleInterface(M, /*GroupNames=*/{}, traversalOpts, printer,
208216
printOpts, /*PrintSynthesizedExtensions=*/false);
209217

210218
return EXIT_SUCCESS;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct ExplicitSubmoduleStruct {
2+
int value;
3+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct ImplicitSubmoduleStruct {
2+
int value;
3+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct TopLevelModuleStruct {
2+
int value;
3+
};

test/SynthesizeInterfaceTool/Inputs/module.modulemap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,15 @@ module mcxx {
66
requires cplusplus
77
header "mcxx.h"
88
}
9+
10+
module TopLevelModule {
11+
header "TopLevelModule.h"
12+
13+
module ImplicitSubmodule {
14+
header "ImplicitSubmodule.h"
15+
}
16+
17+
explicit module ExplicitSubmodule {
18+
header "ExplicitSubmodule.h"
19+
}
20+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-synthesize-interface -module-name m1 -print-fully-qualified-types -I %S/Inputs -o - | %FileCheck %s
2+
3+
// CHECK: public struct MyStruct {
4+
// CHECK-DAG: public init()
5+
// CHECK-DAG: public init(value: Swift.Int32)
6+
// CHECK-DAG: public var value: Swift.Int32
7+
// CHECK-DAG: }
8+
// CHECK-DAG: extension m1.MyStruct {
9+
// CHECK-DAG: public func printValue()
10+
// CHECK-DAG: }
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %target-swift-synthesize-interface -module-name TopLevelModule -I %S/Inputs -o - | %FileCheck %s
2+
// RUN: %target-swift-synthesize-interface -module-name TopLevelModule -include-submodules -I %S/Inputs -o - | %FileCheck %s --check-prefix=IMPLICIT
3+
// RUN: %target-swift-synthesize-interface -module-name TopLevelModule.ExplicitSubmodule -I %S/Inputs -o - | %FileCheck %s --check-prefix=EXPLICIT
4+
5+
// CHECK: import TopLevelModule.ExplicitSubmodule
6+
// CHECK-DAG: import TopLevelModule.ImplicitSubmodule
7+
// CHECK-DAG: public struct TopLevelModuleStruct {
8+
// CHECK-DAG: public init()
9+
// CHECK-DAG: public init(value: Int32)
10+
// CHECK-DAG: public var value: Int32
11+
// CHECK-DAG: }
12+
13+
// CHECK-NOT: ImplicitModuleStruct
14+
// CHECK-NOT: ExplicitModuleStruct
15+
16+
// IMPLICIT: import TopLevelModule.ExplicitSubmodule
17+
// IMPLICIT-DAG: import TopLevelModule.ImplicitSubmodule
18+
// IMPLICIT-DAG: public struct TopLevelModuleStruct {
19+
// IMPLICIT-DAG: public init()
20+
// IMPLICIT-DAG: public init(value: Int32)
21+
// IMPLICIT-DAG: public var value: Int32
22+
// IMPLICIT-DAG: }
23+
// IMPLICIT-DAG: public struct ImplicitSubmoduleStruct {
24+
// IMPLICIT-DAG: public init()
25+
// IMPLICIT-DAG: public init(value: Int32)
26+
// IMPLICIT-DAG: public var value: Int32
27+
// IMPLICIT-DAG: }
28+
29+
// IMPLICIT-NOT: ExplicitSubmoduleStruct
30+
31+
// EXPLICIT: public struct ExplicitSubmoduleStruct {
32+
// EXPLICIT-DAG: public init()
33+
// EXPLICIT-DAG: public init(value: Int32)
34+
// EXPLICIT-DAG: public var value: Int32
35+
// EXPLICIT-DAG: }
36+
37+
// EXPLICIT-NOT: import TopLevelModule{{.*}}
38+
// EXPLICIT-NOT: TopLevelModuleStruct
39+
// EXPLICIT-NOT: ImplicitModuleStruct

0 commit comments

Comments
 (0)