Skip to content

Commit 9cd44ca

Browse files
committed
[SymbolGraphGen] Emit symbols from exported modules
When emitting a symbol graph file for a module that import modules via `@_exported import`, emits those modules' symbols as well. SR-15753 rdar://89547374
1 parent c9e3699 commit 9cd44ca

File tree

9 files changed

+79
-15
lines changed

9 files changed

+79
-15
lines changed

include/swift/AST/Module.h

+3
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,9 @@ inline SourceLoc extractNearestSourceLoc(const ModuleDecl *mod) {
939939
return extractNearestSourceLoc(static_cast<const Decl *>(mod));
940940
}
941941

942+
/// Collects modules that this module imports via `@_exported import`.
943+
void collectParsedExportedImports(const ModuleDecl *M, SmallPtrSetImpl<ModuleDecl *> &Imports);
944+
942945
} // end namespace swift
943946

944947
#endif

lib/AST/Module.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ bool ModuleDecl::shouldCollectDisplayDecls() const {
788788
return true;
789789
}
790790

791-
static void collectParsedExportedImports(const ModuleDecl *M, SmallPtrSetImpl<ModuleDecl *> &Imports) {
791+
void swift::collectParsedExportedImports(const ModuleDecl *M, SmallPtrSetImpl<ModuleDecl *> &Imports) {
792792
for (const FileUnit *file : M->getFiles()) {
793793
if (const SourceFile *source = dyn_cast<SourceFile>(file)) {
794794
if (source->hasImports()) {

lib/SymbolGraphGen/SymbolGraph.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -674,12 +674,12 @@ bool SymbolGraph::isUnconditionallyUnavailableOnAllPlatforms(const Decl *D) cons
674674

675675
/// Returns `true` if the symbol should be included as a node in the graph.
676676
bool SymbolGraph::canIncludeDeclAsNode(const Decl *D) const {
677-
// If this decl isn't in this module, don't record it,
677+
// If this decl isn't in this module or module that this module imported with `@_exported`, don't record it,
678678
// as it will appear elsewhere in its module's symbol graph.
679-
if (D->getModuleContext()->getName() != M.getName()) {
679+
if (D->getModuleContext()->getName() != M.getName() && !Walker.isFromExportedImportedModule(D)) {
680680
return false;
681681
}
682-
682+
683683
if (!isa<ValueDecl>(D)) {
684684
return false;
685685
}

lib/SymbolGraphGen/SymbolGraphASTWalker.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ using namespace swift;
2222
using namespace symbolgraphgen;
2323

2424
SymbolGraphASTWalker::SymbolGraphASTWalker(ModuleDecl &M,
25+
const SmallPtrSet<ModuleDecl *, 4> ExportedImportedModules,
2526
const SymbolGraphOptions &Options)
2627
: Options(Options),
2728
M(M),
29+
ExportedImportedModules(ExportedImportedModules),
2830
MainGraph(*this, M, None, Ctx) {}
2931

3032
/// Get a "sub" symbol graph for the parent module of a type that
@@ -51,6 +53,11 @@ SymbolGraph *SymbolGraphASTWalker::getModuleSymbolGraph(const Decl *D) {
5153
// should put actual extensions of that module into the main graph
5254
return &MainGraph;
5355
}
56+
57+
if (isFromExportedImportedModule(D)) {
58+
return &MainGraph;
59+
}
60+
5461
auto Found = ExtendedModuleGraphs.find(M->getNameStr());
5562
if (Found != ExtendedModuleGraphs.end()) {
5663
return Found->getValue();
@@ -208,3 +215,11 @@ bool SymbolGraphASTWalker::walkToDeclPre(Decl *D, CharSourceRange Range) {
208215

209216
return true;
210217
}
218+
219+
bool SymbolGraphASTWalker::isFromExportedImportedModule(const Decl* D) const {
220+
auto *M = D->getModuleContext();
221+
222+
return llvm::any_of(ExportedImportedModules, [&M](const auto *MD) {
223+
return M->getNameStr().equals(MD->getModuleContext()->getNameStr());
224+
});
225+
}

lib/SymbolGraphGen/SymbolGraphASTWalker.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ struct SymbolGraphASTWalker : public SourceEntityWalker {
4646

4747
/// The module that this symbol graph will represent.
4848
const ModuleDecl &M;
49+
50+
const SmallPtrSet<ModuleDecl *, 4> ExportedImportedModules;
4951

5052
/// The symbol graph for the main module of interest.
5153
SymbolGraph MainGraph;
@@ -55,7 +57,9 @@ struct SymbolGraphASTWalker : public SourceEntityWalker {
5557

5658
// MARK: - Initialization
5759

58-
SymbolGraphASTWalker(ModuleDecl &M, const SymbolGraphOptions &Options);
60+
SymbolGraphASTWalker(ModuleDecl &M,
61+
const SmallPtrSet<ModuleDecl *, 4> ExportedImportedModules,
62+
const SymbolGraphOptions &Options);
5963
virtual ~SymbolGraphASTWalker() {}
6064

6165
// MARK: - Utilities
@@ -87,6 +91,11 @@ struct SymbolGraphASTWalker : public SourceEntityWalker {
8791
// MARK: - SourceEntityWalker
8892

8993
virtual bool walkToDeclPre(Decl *D, CharSourceRange Range) override;
94+
95+
// MARK: - Utilities
96+
97+
/// Returns whether the given declaration comes from an `@_exported import` module.
98+
virtual bool isFromExportedImportedModule(const Decl *D) const;
9099
};
91100

92101
} // end namespace symbolgraphgen

lib/SymbolGraphGen/SymbolGraphGen.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,17 @@ int serializeSymbolGraph(SymbolGraph &SG,
5555
int
5656
symbolgraphgen::emitSymbolGraphForModule(ModuleDecl *M,
5757
const SymbolGraphOptions &Options) {
58-
SymbolGraphASTWalker Walker(*M, Options);
5958
SmallVector<Decl *, 64> ModuleDecls;
6059
swift::getTopLevelDeclsForDisplay(M, ModuleDecls, /*recursive*/true);
60+
61+
SmallPtrSet<ModuleDecl *, 4> ExportedImportedModules;
62+
swift::collectParsedExportedImports(M, ExportedImportedModules);
6163

6264
if (Options.PrintMessages)
6365
llvm::errs() << ModuleDecls.size()
6466
<< " top-level declarations in this module.\n";
67+
68+
SymbolGraphASTWalker Walker(*M, ExportedImportedModules, Options);
6569

6670
for (auto *Decl : ModuleDecls) {
6771
Walker.walk(Decl);
@@ -98,7 +102,7 @@ printSymbolGraphForDecl(const ValueDecl *D, Type BaseTy,
98102

99103
llvm::json::OStream JOS(OS, Options.PrettyPrint ? 2 : 0);
100104
ModuleDecl *MD = D->getModuleContext();
101-
SymbolGraphASTWalker Walker(*MD, Options);
105+
SymbolGraphASTWalker Walker(*MD, {}, Options);
102106
markup::MarkupContext MarkupCtx;
103107
SymbolGraph Graph(Walker, *MD, None, MarkupCtx, None,
104108
/*IsForSingleNode=*/true);
+23-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-build-swift %s -module-name BasicExtension -emit-module -emit-module-path %t/
33
// RUN: %target-swift-symbolgraph-extract -module-name BasicExtension -I %t -pretty-print -output-dir %t
4-
// RUN: %FileCheck %s --input-file %t/BasicExtension@Swift.symbols.json
4+
// RUN: %FileCheck %s --input-file %t/BasicExtension@Swift.symbols.json --check-prefix EXTRACT
5+
6+
// RUN: %empty-directory(%t)
7+
// RUN: %target-build-swift %s -module-name BasicExtension -emit-module -emit-module-path %t/ -emit-symbol-graph -emit-symbol-graph-dir %t
8+
// RUN: %FileCheck %s --input-file %t/BasicExtension@Swift.symbols.json --check-prefix BUILD
59

610
extension String {
711
/// Return something.
@@ -10,17 +14,28 @@ extension String {
1014
}
1115
}
1216

13-
// CHECK: module
14-
// CHECK-NEXT: "name": "BasicExtension"
17+
// EXTRACT: module
18+
// EXTRACT-NEXT: "name": "BasicExtension"
19+
20+
// BUILD: module
21+
// BUILD: "name":"BasicExtension"
1522

16-
// CHECK: "precise": "s:SS14BasicExtensionE9somethingSSvp"
23+
// EXTRACT: "precise": "s:SS14BasicExtensionE9somethingSSvp"
1724

18-
// CHECK: "kind": "memberOf"
19-
// CHECK-NEXT: "source": "s:SS14BasicExtensionE9somethingSSvp"
20-
// CHECK-NEXT: "target": "s:SS"
25+
// BUILD: "precise":"s:SS14BasicExtensionE9somethingSSvp"
26+
27+
// EXTRACT: "kind": "memberOf"
28+
// EXTRACT-NEXT: "source": "s:SS14BasicExtensionE9somethingSSvp"
29+
// EXTRACT-NEXT: "target": "s:SS"
30+
31+
// BUILD: "kind":"memberOf"
32+
// BUILD: "source":"s:SS14BasicExtensionE9somethingSSvp"
33+
// BUILD: "target":"s:SS"
2134

2235
// Extending `String` creates a memberOf relationship above.
2336
// However, it should not be included as a node because `String`
2437
// is owned by the Swift module.
2538
// rdar://58876107
26-
// CHECK-NOT: "precise": "s:SS"
39+
// EXTRACT-NOT: "precise": "s:SS"
40+
41+
// BUILD-NOT: "precise":"s:SS"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %S/Inputs/ExportedImport/A.swift -module-name A -emit-module -emit-module-path %t/A.swiftmodule
3+
// RUN: %target-swift-frontend %s -module-name ExportedImport -emit-module -emit-module-path /dev/null -I %t -emit-symbol-graph -emit-symbol-graph-dir %t/
4+
// RUN: %FileCheck %s --input-file %t/ExportedImport.symbols.json
5+
// RUN: ls %t | %FileCheck %s --check-prefix FILES
6+
7+
@_exported import A
8+
9+
// CHECK: "precise":"s:1A11SymbolFromAV"
10+
// CHECK-NOT: InternalSymbolFromA
11+
12+
// FIXME: Symbols from `@_exported import` do not get emitted when using swift-symbolgraph-extract
13+
// This is tracked by https://bugs.swift.org/browse/SR-15921.
14+
15+
// FILES-NOT: ExportedImport@A.symbols.json
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public struct SymbolFromA {}
2+
3+
struct InternalSymbolFromA {}

0 commit comments

Comments
 (0)