@@ -25,12 +25,10 @@ namespace {
2525
2626// / Compare the two \c ModuleDecl instances to see whether they are the same.
2727// /
28- // / Pass \c true to the \c ignoreUnderlying argument to consider two modules the same even if
29- // / one is a Swift module and the other a non-Swift module. This allows a Swift module and its
30- // / underlying Clang module to compare as equal.
31- bool areModulesEqual (const ModuleDecl *lhs, const ModuleDecl *rhs, bool ignoreUnderlying = false ) {
32- return lhs->getNameStr () == rhs->getNameStr ()
33- && (ignoreUnderlying || lhs->isNonSwiftModule () == rhs->isNonSwiftModule ());
28+ // / This does a by-name comparison to consider a module's underlying Clang module to be equivalent
29+ // / to the wrapping module of the same name.
30+ bool areModulesEqual (const ModuleDecl *lhs, const ModuleDecl *rhs) {
31+ return lhs->getNameStr () == rhs->getNameStr ();
3432}
3533
3634} // anonymous namespace
@@ -50,11 +48,13 @@ SymbolGraphASTWalker::SymbolGraphASTWalker(ModuleDecl &M,
5048SymbolGraph *SymbolGraphASTWalker::getModuleSymbolGraph (const Decl *D) {
5149 auto *M = D->getModuleContext ();
5250 const auto *DC = D->getDeclContext ();
51+ SmallVector<const NominalTypeDecl *, 2 > ParentTypes = {};
5352 const Decl *ExtendedNominal = nullptr ;
5453 while (DC) {
5554 M = DC->getParentModule ();
5655 if (const auto *NTD = dyn_cast_or_null<NominalTypeDecl>(DC->getAsDecl ())) {
5756 DC = NTD->getDeclContext ();
57+ ParentTypes.push_back (NTD);
5858 } else if (const auto *Ext = dyn_cast_or_null<ExtensionDecl>(DC->getAsDecl ())) {
5959 DC = Ext->getExtendedNominal ()->getDeclContext ();
6060 if (!ExtendedNominal)
@@ -64,10 +64,10 @@ SymbolGraph *SymbolGraphASTWalker::getModuleSymbolGraph(const Decl *D) {
6464 }
6565 }
6666
67- if (areModulesEqual (&this ->M , M, true )) {
67+ if (areModulesEqual (&this ->M , M)) {
6868 return &MainGraph;
6969 } else if (MainGraph.DeclaringModule .hasValue () &&
70- areModulesEqual (MainGraph.DeclaringModule .getValue (), M, true )) {
70+ areModulesEqual (MainGraph.DeclaringModule .getValue (), M)) {
7171 // Cross-import overlay modules already appear as "extensions" of their declaring module; we
7272 // should put actual extensions of that module into the main graph
7373 return &MainGraph;
@@ -79,9 +79,8 @@ SymbolGraph *SymbolGraphASTWalker::getModuleSymbolGraph(const Decl *D) {
7979 return &MainGraph;
8080 }
8181
82- if (ExtendedNominal && isFromExportedImportedModule (ExtendedNominal)) {
83- return &MainGraph;
84- } else if (!ExtendedNominal && isConsideredExportedImported (D)) {
82+ // If this type is the child of a type which was re-exported in a qualified export, use the main graph.
83+ if (llvm::any_of (ParentTypes, [&](const NominalTypeDecl *NTD){ return isQualifiedExportedImport (NTD); })) {
8584 return &MainGraph;
8685 }
8786
@@ -230,7 +229,7 @@ bool SymbolGraphASTWalker::walkToDeclPre(Decl *D, CharSourceRange Range) {
230229 if (const auto *ExtendedNominal = Extension->getExtendedNominal ()) {
231230 auto ExtendedModule = ExtendedNominal->getModuleContext ();
232231 auto ExtendedSG = getModuleSymbolGraph (ExtendedNominal);
233- if (ExtendedModule != &M ) {
232+ if (! isOurModule (ExtendedModule) ) {
234233 ExtendedSG->recordNode (Symbol (ExtendedSG, VD, nullptr ));
235234 return true ;
236235 }
@@ -244,22 +243,10 @@ bool SymbolGraphASTWalker::walkToDeclPre(Decl *D, CharSourceRange Range) {
244243}
245244
246245bool SymbolGraphASTWalker::isConsideredExportedImported (const Decl *D) const {
247- // First check the decl itself to see if it was directly re-exported.
248- if (isFromExportedImportedModule (D))
249- return true ;
250-
251- const auto *DC = D->getDeclContext ();
252-
253- // Next, see if the decl is a child symbol of another decl that was re-exported.
254- if (DC) {
255- if (const auto *VD = dyn_cast_or_null<ValueDecl>(DC->getAsDecl ())) {
256- if (isFromExportedImportedModule (VD))
257- return true ;
258- }
259- }
260-
261- // Finally, check to see if this decl is an extension of something else that was re-exported.
246+ // Check to see if this decl is an extension of something else that was re-exported.
247+ // Do this first in case there's a chain of extensions that leads somewhere that's not a re-export.
262248 // FIXME: this considers synthesized members of extensions to be valid
249+ const auto *DC = D->getDeclContext ();
263250 const Decl *ExtendedNominal = nullptr ;
264251 while (DC && !ExtendedNominal) {
265252 if (const auto *ED = dyn_cast_or_null<ExtensionDecl>(DC->getAsDecl ())) {
@@ -269,10 +256,23 @@ bool SymbolGraphASTWalker::isConsideredExportedImported(const Decl *D) const {
269256 }
270257 }
271258
272- if (ExtendedNominal && isFromExportedImportedModule (ExtendedNominal)) {
259+ if (ExtendedNominal && isConsideredExportedImported (ExtendedNominal)) {
273260 return true ;
274261 }
275262
263+ // Check to see if the decl is a child symbol of another decl that was re-exported.
264+ DC = D->getDeclContext ();
265+ if (DC) {
266+ if (const auto *VD = dyn_cast_or_null<ValueDecl>(DC->getAsDecl ())) {
267+ if (isConsideredExportedImported (VD))
268+ return true ;
269+ }
270+ }
271+
272+ // Check the decl itself to see if it was directly re-exported.
273+ if (isFromExportedImportedModule (D) || isQualifiedExportedImport (D))
274+ return true ;
275+
276276 // If none of the other checks passed, this wasn't from a re-export.
277277 return false ;
278278}
@@ -293,3 +293,7 @@ bool SymbolGraphASTWalker::isExportedImportedModule(const ModuleDecl *M) const {
293293 return areModulesEqual (M, MD->getModuleContext ());
294294 });
295295}
296+
297+ bool SymbolGraphASTWalker::isOurModule (const ModuleDecl *M) const {
298+ return areModulesEqual (M, &this ->M ) || isExportedImportedModule (M);
299+ }
0 commit comments