Skip to content

Commit 72fc06c

Browse files
authored
Merge pull request #34922 from apple/QuietMisdreavus/overlay-symbol-graph
2 parents b2f63aa + bf9274d commit 72fc06c

File tree

9 files changed

+113
-10
lines changed

9 files changed

+113
-10
lines changed

lib/SymbolGraphGen/FormatVersion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515

1616
#define SWIFT_SYMBOLGRAPH_FORMAT_MAJOR 0
1717
#define SWIFT_SYMBOLGRAPH_FORMAT_MINOR 5
18-
#define SWIFT_SYMBOLGRAPH_FORMAT_PATCH 0
18+
#define SWIFT_SYMBOLGRAPH_FORMAT_PATCH 1
1919

2020
#endif // SWIFT_SYMBOLGRAPHGEN_FORMATVERSION_H

lib/SymbolGraphGen/SymbolGraph.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@ SymbolGraph::SymbolGraph(SymbolGraphASTWalker &Walker,
3939
M(M),
4040
ExtendedModule(ExtendedModule),
4141
Ctx(Ctx),
42-
ModuleVersion(ModuleVersion) {}
42+
ModuleVersion(ModuleVersion) {
43+
if (auto *DM = M.getDeclaringModuleIfCrossImportOverlay()) {
44+
DeclaringModule = DM;
45+
SmallVector<Identifier, 1> Bystanders;
46+
if (M.getRequiredBystandersIfCrossImportOverlay(DM, Bystanders)) {
47+
BystanderModules = Bystanders;
48+
}
49+
}
50+
}
4351

4452
// MARK: - Utilities
4553

@@ -499,7 +507,17 @@ void SymbolGraph::serialize(llvm::json::OStream &OS) {
499507
}); // end metadata:
500508

501509
OS.attributeObject("module", [&](){
502-
OS.attribute("name", M.getNameStr());
510+
if (DeclaringModule) {
511+
// A cross-import overlay can be considered part of its declaring module
512+
OS.attribute("name", (*DeclaringModule)->getNameStr());
513+
std::vector<StringRef> B;
514+
for (auto BModule : BystanderModules) {
515+
B.push_back(BModule.str());
516+
}
517+
OS.attribute("bystanders", B);
518+
} else {
519+
OS.attribute("name", M.getNameStr());
520+
}
503521
AttributeRAII Platform("platform", OS);
504522

505523
auto *MainFile = M.getFiles().front();

lib/SymbolGraphGen/SymbolGraph.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ struct SymbolGraph {
4242
The module whose types were extended in `M`.
4343
*/
4444
Optional<ModuleDecl *> ExtendedModule;
45+
46+
/**
47+
The module declaring `M`, if `M` is a cross-import overlay.
48+
*/
49+
Optional<ModuleDecl *> DeclaringModule;
50+
51+
/**
52+
The modules that must be imported alongside `DeclaringModule` for `M` to be imported, if `M` is a cross-import overlay.
53+
*/
54+
SmallVector<Identifier, 1> BystanderModules;
4555

4656
/**
4757
A context for allocations.

lib/SymbolGraphGen/SymbolGraphGen.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,27 @@ using namespace symbolgraphgen;
2222
namespace {
2323
int serializeSymbolGraph(SymbolGraph &SG,
2424
const SymbolGraphOptions &Options) {
25-
SmallString<256> FileName(SG.M.getNameStr());
26-
if (SG.ExtendedModule.hasValue()) {
25+
SmallString<256> FileName;
26+
if (SG.DeclaringModule.hasValue()) {
27+
// Save a cross-import overlay symbol graph as `MainModule@BystandingModule[@BystandingModule...]@OverlayModule.symbols.json`
28+
//
29+
// The overlay module's name is added as a disambiguator in case an overlay
30+
// declares multiple modules for the same set of imports.
31+
FileName.append(SG.DeclaringModule.getValue()->getNameStr());
32+
for (auto BystanderModule : SG.BystanderModules) {
33+
FileName.push_back('@');
34+
FileName.append(BystanderModule.str());
35+
}
36+
2737
FileName.push_back('@');
28-
FileName.append(SG.ExtendedModule.getValue()->getNameStr());
38+
FileName.append(SG.M.getNameStr());
39+
} else {
40+
FileName.append(SG.M.getNameStr());
41+
42+
if (SG.ExtendedModule.hasValue()) {
43+
FileName.push_back('@');
44+
FileName.append(SG.ExtendedModule.getValue()->getNameStr());
45+
}
2946
}
3047
FileName.append(".symbols.json");
3148

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %S/Inputs/CrossImport/A.swift -I %t -module-name A -emit-module -emit-module-path %t/
3+
// RUN: %target-build-swift %S/Inputs/CrossImport/B.swift -I %t -module-name B -emit-module -emit-module-path %t/
4+
// RUN: %target-build-swift %s -module-name _A_B -I %t -emit-module -emit-module-path %t/
5+
// RUN: cp -r %S/Inputs/CrossImport/A.swiftcrossimport %t/
6+
// RUN: %target-swift-symbolgraph-extract -module-name A -I %t -pretty-print -output-dir %t
7+
// RUN: %FileCheck %s --input-file %t/A@B@_A_B.symbols.json
8+
9+
@_exported import A
10+
import B
11+
12+
extension A {
13+
public func transmogrify() -> B {
14+
return B(y: self.x);
15+
}
16+
}
17+
18+
// CHECK: module
19+
// CHECK-NEXT: "name": "A"
20+
// CHECK-NEXT: bystanders
21+
// CHECK-NEXT: B
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public struct A {
2+
public var x: Int
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
%YAML 1.2
2+
---
3+
version: 1
4+
modules:
5+
- name: _A_B
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public struct B {
2+
public var y: Int
3+
4+
public init(y: Int) {
5+
self.y = y
6+
}
7+
}

tools/driver/swift_symbolgraph_extract_main.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,12 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args, const char *Argv
217217
}
218218

219219
auto M = CI.getASTContext().getModuleByName(options::ModuleName);
220+
SmallVector<Identifier, 32> VisibleModuleNames;
221+
CI.getASTContext().getVisibleTopLevelModuleNames(VisibleModuleNames);
220222
if (!M) {
221223
llvm::errs()
222224
<< "Couldn't load module '" << options::ModuleName << '\''
223225
<< " in the current SDK and search paths.\n";
224-
SmallVector<Identifier, 32> VisibleModuleNames;
225-
CI.getASTContext().getVisibleTopLevelModuleNames(VisibleModuleNames);
226226

227227
if (VisibleModuleNames.empty()) {
228228
llvm::errs() << "Could not find any modules.\n";
@@ -241,7 +241,29 @@ int swift_symbolgraph_extract_main(ArrayRef<const char *> Args, const char *Argv
241241

242242
const auto &MainFile = M->getMainFile(FileUnitKind::SerializedAST);
243243
llvm::errs() << "Emitting symbol graph for module file: " << MainFile.getModuleDefiningPath() << '\n';
244+
245+
int Success = symbolgraphgen::emitSymbolGraphForModule(M, Options);
246+
247+
// Look for cross-import overlays that the given module imports.
248+
249+
// Clear out the diagnostic printer before looking for cross-import overlay modules,
250+
// since some SDK modules can cause errors in the getModuleByName() call. The call
251+
// itself will properly return nullptr after this failure, so for our purposes we
252+
// don't need to print these errors.
253+
CI.removeDiagnosticConsumer(&DiagPrinter);
254+
255+
for (const auto &ModuleName : VisibleModuleNames) {
256+
if (ModuleName.str().startswith("_")) {
257+
auto CIM = CI.getASTContext().getModuleByName(ModuleName.str());
258+
if (CIM && CIM->isCrossImportOverlayOf(M)) {
259+
const auto &CIMainFile = CIM->getMainFile(FileUnitKind::SerializedAST);
260+
llvm::errs() << "Emitting symbol graph for cross-import overlay module file: "
261+
<< CIMainFile.getModuleDefiningPath() << '\n';
262+
263+
Success |= symbolgraphgen::emitSymbolGraphForModule(CIM, Options);
264+
}
265+
}
266+
}
244267

245-
return symbolgraphgen::emitSymbolGraphForModule(M,
246-
Options);
268+
return Success;
247269
}

0 commit comments

Comments
 (0)