Skip to content

Commit 27003e3

Browse files
committed
Allow for emission of swift.extension symbols for extensions to external types in swiftSymbolGraphGen
This includes: - introduction of the "swift.extension" symbol and "extensionTo" relationship - adding support for ExtensionDecl to the Symbol class - adding a "typeKind" field to the symbol's extension mixin which indicates what kind of symbol was extended - intoduction of the -emit-extension-block-symbols flag, which enables the behavior outlined below - adaptions to SymbolGraphASTWalker that ensure a swift.extension symbol is emitted for each extension to a type that does not exist in the local symbol graph - adaptions to SymbolGraph and SymbolGraphASTWalker that ensure relationships are correctly associated with the swift.extension symbol instead of the original type declaration's (extended nominal's) symbol where applicable - adaptions to SymbolGraphASTWalker that ensure swift.extension symbols are connected to their respective extended nominal's symbol using an extensionTo relationship Testing: - adds SymbolGraph tests that test behavior only relevant in -emit-extension-block-symbols mode - adapts some SymbolGraph tests to additionally test similar behavior for extensions to external types in -emit-extension-block-symbols mode - adapts some SymbolGraph tests to (additionally or exclusively) test the behavior with -emit-extension-block-symbols mode enabled Bugfixes: - fixes a bug where some conformsTo relationships implicated by the conformances declared on an extension to an external type were not emitted (see test/SymbolGraph/Relationships/ConformsTo/Indirect.swift) Further changes: - documents the strategy for naming and associating children declared in extensions to typealiases (see test/SymbolGraph/Relationships/MemberOf/Typealias.swift, test/SymbolGraph/Symbols/Names.swift)
1 parent b9afb79 commit 27003e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+893
-241
lines changed

include/swift/Option/Options.td

+5
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,11 @@ def pretty_print: Flag<["-"], "pretty-print">,
13301330
Flags<[SwiftAPIExtractOption, SwiftSymbolGraphExtractOption]>,
13311331
HelpText<"Pretty-print the output JSON">;
13321332

1333+
def emit_extension_block_symbols: Flag<["-"], "emit-extension-block-symbols">,
1334+
Flags<[SwiftSymbolGraphExtractOption, FrontendOption,
1335+
NoInteractiveOption, SupplementaryOutput, HelpHidden]>,
1336+
HelpText<"Emit 'swift.extension' symbols for extensions to external types instead of directly associating members and conformances with the extended nominal when generating symbol graphs">;
1337+
13331338
// swift-symbolgraph-extract-only options
13341339
def output_dir : Separate<["-"], "output-dir">,
13351340
Flags<[NoDriverOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption,

include/swift/SymbolGraphGen/SymbolGraphOptions.h

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ struct SymbolGraphOptions {
4848

4949
/// Whether to include documentation for clang nodes or not.
5050
bool IncludeClangDocs = false;
51+
52+
/// Whether to emit "swift.extension" symbols for extensions to external types
53+
/// along with "extensionTo" relationships instead of directly associating
54+
/// members and conformances with the extended nominal.
55+
bool EmitExtensionBlockSymbols = false;
5156
};
5257

5358
} // end namespace symbolgraphgen

lib/Driver/ToolChains.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ ToolChain::constructInvocation(const CompileJobAction &job,
616616
context.Args.AddLastArg(Arguments, options::OPT_emit_symbol_graph_dir);
617617
}
618618
context.Args.AddLastArg(Arguments, options::OPT_include_spi_symbols);
619+
context.Args.AddLastArg(Arguments, options::OPT_emit_extension_block_symbols);
619620
context.Args.AddLastArg(Arguments, options::OPT_symbol_graph_minimum_access_level);
620621

621622
return II;
@@ -1110,6 +1111,7 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job,
11101111
context.Args.AddLastArg(Arguments, options::OPT_emit_symbol_graph);
11111112
context.Args.AddLastArg(Arguments, options::OPT_emit_symbol_graph_dir);
11121113
context.Args.AddLastArg(Arguments, options::OPT_include_spi_symbols);
1114+
context.Args.AddLastArg(Arguments, options::OPT_emit_extension_block_symbols);
11131115
context.Args.AddLastArg(Arguments, options::OPT_symbol_graph_minimum_access_level);
11141116

11151117
context.Args.AddLastArg(Arguments, options::OPT_import_objc_header);

lib/DriverTool/swift_symbolgraph_extract_main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args,
171171
ParsedArgs.hasArg(OPT_skip_inherited_docs),
172172
ParsedArgs.hasArg(OPT_include_spi_symbols),
173173
/*IncludeClangDocs=*/false,
174+
ParsedArgs.hasArg(OPT_emit_extension_block_symbols),
174175
};
175176

176177
if (auto *A = ParsedArgs.getLastArg(OPT_minimum_access_level)) {

lib/Frontend/CompilerInvocation.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,8 @@ static void ParseSymbolGraphArgs(symbolgraphgen::SymbolGraphOptions &Opts,
12401240

12411241
Opts.SkipInheritedDocs = Args.hasArg(OPT_skip_inherited_docs);
12421242
Opts.IncludeSPISymbols = Args.hasArg(OPT_include_spi_symbols);
1243+
Opts.EmitExtensionBlockSymbols =
1244+
Args.hasArg(OPT_emit_extension_block_symbols);
12431245

12441246
if (auto *A = Args.getLastArg(OPT_symbol_graph_minimum_access_level)) {
12451247
Opts.MinimumAccessLevel =

lib/SymbolGraphGen/Edge.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,20 @@ struct RelationshipKind {
104104
static inline RelationshipKind OptionalRequirementOf() {
105105
return RelationshipKind { "optionalRequirementOf" };
106106
}
107-
107+
108+
/**
109+
A symbol A extends a symbol B with members or conformances.
110+
111+
This relationship describes the connection between extension blocks
112+
(swift.extension symbols) and the type they extend.
113+
114+
The implied inverse of this relationship is a symbol B that is extended
115+
by an extension block symbol A.
116+
*/
117+
static inline RelationshipKind ExtensionTo() {
118+
return RelationshipKind{"extensionTo"};
119+
}
120+
108121
bool operator==(const RelationshipKind &Other) const {
109122
return Name == Other.Name;
110123
}

lib/SymbolGraphGen/JSON.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ void swift::symbolgraphgen::serialize(const ExtensionDecl *Extension,
7272
if (const auto *ExtendedModule = ExtendedNominal->getModuleContext()) {
7373
OS.attribute("extendedModule", ExtendedModule->getNameStr());
7474
}
75+
76+
StringRef Kind;
77+
switch (ExtendedNominal->getKind()) {
78+
case DeclKind::Class:
79+
Kind = "class";
80+
break;
81+
case DeclKind::Struct:
82+
Kind = "struct";
83+
break;
84+
case DeclKind::Enum:
85+
Kind = "enum";
86+
break;
87+
case DeclKind::Protocol:
88+
Kind = "protocol";
89+
break;
90+
default:
91+
Kind = "unknown";
92+
break;
93+
}
94+
95+
OS.attribute("typeKind", Kind);
7596
}
7697

7798
SmallVector<Requirement, 4> FilteredRequirements;

0 commit comments

Comments
 (0)