diff --git a/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp b/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp index 7e74539228496..d4b4a2c6969fc 100644 --- a/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp +++ b/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp @@ -21,6 +21,20 @@ using namespace swift; using namespace symbolgraphgen; +namespace { + +/// Compare the two \c ModuleDecl instances to see whether they are the same. +/// +/// Pass \c true to the \c ignoreUnderlying argument to consider two modules the same even if +/// one is a Swift module and the other a non-Swift module. This allows a Swift module and its +/// underlying Clang module to compare as equal. +bool areModulesEqual(const ModuleDecl *lhs, const ModuleDecl *rhs, bool ignoreUnderlying = false) { + return lhs->getNameStr() == rhs->getNameStr() + && (ignoreUnderlying || lhs->isNonSwiftModule() == rhs->isNonSwiftModule()); +} + +} // anonymous namespace + SymbolGraphASTWalker::SymbolGraphASTWalker(ModuleDecl &M, const SmallPtrSet ExportedImportedModules, const SymbolGraphOptions &Options) @@ -45,10 +59,10 @@ SymbolGraph *SymbolGraphASTWalker::getModuleSymbolGraph(const Decl *D) { } } - if (this->M.getNameStr().equals(M->getNameStr())) { + if (areModulesEqual(&this->M, M, true)) { return &MainGraph; } else if (MainGraph.DeclaringModule.hasValue() && - MainGraph.DeclaringModule.getValue()->getNameStr().equals(M->getNameStr())) { + areModulesEqual(MainGraph.DeclaringModule.getValue(), M, true)) { // Cross-import overlay modules already appear as "extensions" of their declaring module; we // should put actual extensions of that module into the main graph return &MainGraph; @@ -220,6 +234,6 @@ bool SymbolGraphASTWalker::isFromExportedImportedModule(const Decl* D) const { auto *M = D->getModuleContext(); return llvm::any_of(ExportedImportedModules, [&M](const auto *MD) { - return M->getNameStr().equals(MD->getModuleContext()->getNameStr()); + return areModulesEqual(M, MD->getModuleContext()); }); } diff --git a/test/SymbolGraph/ClangImporter/ForeignExtensions.swift b/test/SymbolGraph/ClangImporter/ForeignExtensions.swift new file mode 100644 index 0000000000000..ee0cd45a0170f --- /dev/null +++ b/test/SymbolGraph/ClangImporter/ForeignExtensions.swift @@ -0,0 +1,23 @@ +// RUN: %empty-directory(%t) +// RUN: cp -r %S/Inputs/EmitWhileBuilding/EmitWhileBuilding.framework %t +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -emit-module-path %t/EmitWhileBuilding.framework/Modules/EmitWhileBuilding.swiftmodule/%target-swiftmodule-name -import-underlying-module -F %t -module-name EmitWhileBuilding -disable-objc-attr-requires-foundation-module %s %S/Inputs/EmitWhileBuilding/Extra.swift -emit-symbol-graph -emit-symbol-graph-dir %t +// RUN: %FileCheck %s --input-file %t/EmitWhileBuilding.symbols.json --check-prefix BASE +// RUN: %FileCheck %s --input-file %t/EmitWhileBuilding@Swift.symbols.json --check-prefix EXTENSION + +// RUN: %target-swift-symbolgraph-extract -sdk %clang-importer-sdk -module-name EmitWhileBuilding -F %t -output-dir %t -pretty-print -v +// RUN: %FileCheck %s --input-file %t/EmitWhileBuilding.symbols.json --check-prefix BASE +// RUN: %FileCheck %s --input-file %t/EmitWhileBuilding@Swift.symbols.json --check-prefix EXTENSION + +// REQUIRES: objc_interop + +// ensure that the symbol `String.Foo.bar` does not appear in the base module's symbol graph + +// BASE-NOT: "s:SS17EmitWhileBuildingE3FooO3baryA2CmF", +// EXTENSION: "s:SS17EmitWhileBuildingE3FooO3baryA2CmF", + +public extension String { + enum Foo { + case bar + } +} +