Skip to content

Commit e04092d

Browse files
don't crawl exported imports more than once
1 parent 1f7fe02 commit e04092d

File tree

4 files changed

+37
-14
lines changed

4 files changed

+37
-14
lines changed

include/swift/AST/SourceFile.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ class SourceFile final : public FileUnit {
288288

289289
~SourceFile();
290290

291+
bool hasImports() const {
292+
return Imports.hasValue();
293+
}
294+
291295
/// Retrieve an immutable view of the source file's imports.
292296
ArrayRef<AttributedImport<ImportedModule>> getImports() const {
293297
return *Imports;
@@ -393,8 +397,6 @@ class SourceFile final : public FileUnit {
393397
public:
394398
virtual void getTopLevelDecls(SmallVectorImpl<Decl*> &results) const override;
395399

396-
virtual void getDisplayDecls(SmallVectorImpl<Decl*> &results) const override;
397-
398400
virtual void
399401
getOperatorDecls(SmallVectorImpl<OperatorDecl *> &results) const override;
400402

lib/AST/Module.cpp

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,22 @@ void SourceFile::lookupObjCMethods(
780780
results.append(known->second.begin(), known->second.end());
781781
}
782782

783+
static void collectParsedExportedImports(const ModuleDecl *M, SmallPtrSetImpl<ModuleDecl *> &Imports) {
784+
for (const FileUnit *file : M->getFiles()) {
785+
if (const SourceFile *source = dyn_cast<SourceFile>(file)) {
786+
if (source->hasImports()) {
787+
for (auto import : source->getImports()) {
788+
if (import.options.contains(ImportFlags::Exported)) {
789+
if (!Imports.contains(import.module.importedModule)) {
790+
Imports.insert(import.module.importedModule);
791+
}
792+
}
793+
}
794+
}
795+
}
796+
}
797+
}
798+
783799
void ModuleDecl::getLocalTypeDecls(SmallVectorImpl<TypeDecl*> &Results) const {
784800
FORWARD(getLocalTypeDecls, (Results));
785801
}
@@ -822,17 +838,6 @@ void SourceFile::getTopLevelDecls(SmallVectorImpl<Decl*> &Results) const {
822838
Results.append(decls.begin(), decls.end());
823839
}
824840

825-
void SourceFile::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const {
826-
if (Imports.hasValue()) {
827-
for (auto import : *Imports) {
828-
if (import.options.contains(ImportFlags::Exported)) {
829-
import.module.importedModule->getDisplayDecls(Results);
830-
}
831-
}
832-
}
833-
getTopLevelDecls(Results);
834-
}
835-
836841
void ModuleDecl::getOperatorDecls(
837842
SmallVectorImpl<OperatorDecl *> &results) const {
838843
// For a parsed module, we can check the source cache on the module rather
@@ -937,8 +942,23 @@ SourceFile::getExternalRawLocsForDecl(const Decl *D) const {
937942
}
938943

939944
void ModuleDecl::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const {
945+
if (isParsedModule(this)) {
946+
SmallPtrSet<ModuleDecl *, 4> Modules;
947+
collectParsedExportedImports(this, Modules);
948+
for (const ModuleDecl *import : Modules) {
949+
import->getDisplayDecls(Results);
950+
}
951+
}
940952
// FIXME: Should this do extra access control filtering?
941953
FORWARD(getDisplayDecls, (Results));
954+
955+
#ifndef NDEBUG
956+
llvm::DenseSet<Decl *> visited;
957+
for (auto *D : Results) {
958+
auto inserted = visited.insert(D).second;
959+
assert(inserted && "there should be no duplicate decls");
960+
}
961+
#endif
942962
}
943963

944964
ProtocolConformanceRef

test/SymbolGraph/ClangImporter/EmitWhileBuilding.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22
// RUN: cp -r %S/Inputs/EmitWhileBuilding/EmitWhileBuilding.framework %t
3-
// 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 -emit-symbol-graph -emit-symbol-graph-dir %t
3+
// 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
44
// RUN: %{python} -m json.tool %t/EmitWhileBuilding.symbols.json %t/EmitWhileBuilding.formatted.symbols.json
55
// RUN: %FileCheck %s --input-file %t/EmitWhileBuilding.formatted.symbols.json
66
// RUN: %FileCheck %s --input-file %t/EmitWhileBuilding.formatted.symbols.json --check-prefix HEADER
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
public struct SomeStruct {}

0 commit comments

Comments
 (0)