@@ -304,6 +304,34 @@ static bool compareSwiftDecls(Decl *LHS, Decl *RHS) {
304304 return LHS->getKind () < RHS->getKind ();
305305}
306306
307+ static bool shouldPrintImport (ImportDecl *ImportD, ModuleDecl *OrigMod,
308+ const clang::Module *OrigClangMod) {
309+ if (ImportD->getAttrs ().hasAttribute <ImplementationOnlyAttr>())
310+ return false ;
311+
312+ auto *ImportedMod = ImportD->getModule ();
313+ if (ImportedMod) {
314+ if (ImportedMod == OrigMod)
315+ return false ;
316+ if (ImportedMod->isOnoneSupportModule ())
317+ return false ;
318+ if (ImportedMod->getName ().hasUnderscoredNaming ())
319+ return false ;
320+ }
321+
322+ if (!OrigClangMod)
323+ return true ;
324+
325+ auto ImportedClangMod = ImportD->getClangModule ();
326+ if (!ImportedClangMod)
327+ return true ;
328+ if (!ImportedClangMod->isSubModule ())
329+ return true ;
330+ if (ImportedClangMod == OrigClangMod)
331+ return false ;
332+ return ImportedClangMod->isSubModuleOf (OrigClangMod);
333+ }
334+
307335static std::pair<ArrayRef<Decl*>, ArrayRef<Decl*>>
308336getDeclsFromCrossImportOverlay (ModuleDecl *Overlay, ModuleDecl *Declaring,
309337 SmallVectorImpl<Decl *> &Decls,
@@ -329,7 +357,8 @@ getDeclsFromCrossImportOverlay(ModuleDecl *Overlay, ModuleDecl *Declaring,
329357
330358 // Ignore imports of the underlying module, or any cross-import
331359 // that would map back to it.
332- if (Imported == Declaring || Imported->isCrossImportOverlayOf (Declaring))
360+ if (!shouldPrintImport (ID, Declaring, nullptr ) ||
361+ Imported->isCrossImportOverlayOf (Declaring))
333362 return false ;
334363
335364 // Ignore an imports of modules also imported by the underlying module.
@@ -457,19 +486,40 @@ void swift::ide::printModuleInterface(
457486 auto AdjustedOptions = Options;
458487 adjustPrintOptions (AdjustedOptions);
459488
489+ llvm::DenseSet<const void *> SeenImportedDecls;
460490 SmallVector<ModuleDecl *, 1 > ModuleList;
461491 ModuleList.push_back (TargetMod);
492+ SeenImportedDecls.insert (TargetMod);
462493
463- SmallVector<ImportDecl *, 1 > ImportDecls;
464- llvm::DenseSet<const clang::Module *> ClangModulesForImports;
465- SmallVector<Decl *, 1 > SwiftDecls;
494+ SmallVector<ImportDecl *, 0 > ImportDecls;
495+ SmallVector<Decl *, 0 > SwiftDecls;
466496 llvm::DenseMap<const clang::Module *,
467- SmallVector<std::pair<Decl *, clang::SourceLocation>, 1 >>
468- ClangDecls;
497+ SmallVector<std::pair<Decl *, clang::SourceLocation>, 0 >>
498+ ClangDecls;
499+
500+ // Add exported modules that have the same public module name as this module
501+ // (excluding the underlying clang module if there is one).
502+ if (TraversalOptions & ModuleTraversal::VisitMatchingExported) {
503+ SmallVector<ImportedModule> Imports;
504+ TargetMod->getImportedModules (Imports,
505+ ModuleDecl::ImportFilterKind::Exported);
506+ for (ImportedModule Import : Imports) {
507+ if (Import.importedModule ->getPublicModuleName (
508+ /* onlyIfImported=*/ false ) != TargetMod->getName ())
509+ continue ;
510+
511+ if (TargetClangMod != nullptr &&
512+ Import.importedModule ->findUnderlyingClangModule () == TargetClangMod)
513+ continue ;
514+
515+ ModuleList.push_back (Import.importedModule );
516+ SeenImportedDecls.insert (Import.importedModule );
517+ }
518+ }
469519
470- // If we're printing recursively, find all of the submodules to print.
471520 if (TargetClangMod) {
472- if (TraversalOptions) {
521+ // Add clang submodules if they're being visited
522+ if (TraversalOptions & ModuleTraversal::VisitSubmodules) {
473523 SmallVector<const clang::Module *, 8 > Worklist;
474524 SmallPtrSet<const clang::Module *, 8 > Visited;
475525 Worklist.push_back (TargetClangMod);
@@ -482,16 +532,15 @@ void swift::ide::printModuleInterface(
482532
483533 ClangDecls.insert ({ CM, {} });
484534
485- if (CM != TargetClangMod)
486- if (auto *OwningModule = Importer.getWrapperForModule (CM))
535+ if (CM != TargetClangMod) {
536+ if (auto *OwningModule = Importer.getWrapperForModule (CM)) {
487537 ModuleList.push_back (OwningModule);
538+ }
539+ }
488540
489- // If we're supposed to visit submodules, add them now.
490- if (TraversalOptions & ModuleTraversal::VisitSubmodules) {
491- for (clang::Module * submodule: CM->submodules ()) {
492- if (Visited.insert (submodule).second ) {
493- Worklist.push_back (submodule);
494- }
541+ for (clang::Module *submodule : CM->submodules ()) {
542+ if (Visited.insert (submodule).second ) {
543+ Worklist.push_back (submodule);
495544 }
496545 }
497546 }
@@ -500,8 +549,7 @@ void swift::ide::printModuleInterface(
500549 }
501550 }
502551
503- SmallVector<Decl *, 1 > Decls;
504-
552+ SmallVector<Decl *, 0 > Decls;
505553 for (ModuleDecl *M : ModuleList) {
506554 swift::getTopLevelDeclsForDisplay (M, Decls);
507555 }
@@ -527,42 +575,38 @@ void swift::ide::printModuleInterface(
527575 continue ;
528576 }
529577
530- auto ShouldPrintImport = [&]( ImportDecl *ImportD) -> bool {
531- if (ImportD-> getAttrs (). hasAttribute <ImplementationOnlyAttr>( ))
532- return false ;
578+ if ( auto ID = dyn_cast< ImportDecl>(D)) {
579+ if (! shouldPrintImport (ID, TargetMod, TargetClangMod ))
580+ continue ;
533581
534- if (!TargetClangMod)
535- return true ;
536- if (ImportD->getModule () == TargetMod)
537- return false ;
582+ // Erase submodules that are not missing
583+ if (ID->getClangModule ())
584+ NoImportSubModules.erase (ID->getClangModule ());
538585
539- auto ImportedMod = ImportD->getClangModule ();
540- if (!ImportedMod)
541- return true ;
542- if (!ImportedMod->isSubModule ())
543- return true ;
544- if (ImportedMod == TargetClangMod)
545- return false ;
546- return ImportedMod->isSubModuleOf (TargetClangMod);
547- };
586+ if (ID->getImportKind () == ImportKind::Module) {
587+ // Could have a duplicate import from a clang module's overlay or
588+ // because we're merging modules. Skip them.
548589
549- if (auto ID = dyn_cast<ImportDecl>(D)) {
550- if (ShouldPrintImport (ID)) {
551- if (ID->getClangModule ())
552- // Erase those submodules that are not missing.
553- NoImportSubModules.erase (ID->getClangModule ());
554- if (ID->getImportKind () == ImportKind::Module) {
555- // Make sure we don't print duplicate imports, due to getting imports
556- // for both a clang module and its overlay.
557- if (auto *ClangMod = getUnderlyingClangModuleForImport (ID)) {
558- auto P = ClangModulesForImports.insert (ClangMod);
559- bool IsNew = P.second ;
560- if (!IsNew)
561- continue ;
562- }
590+ if (auto *ClangMod = getUnderlyingClangModuleForImport (ID)) {
591+ if (!SeenImportedDecls.insert (ClangMod).second )
592+ continue ;
563593 }
564- ImportDecls.push_back (ID);
594+
595+ if (auto *ImportedMod = ID->getModule ()) {
596+ if (!SeenImportedDecls.insert (ImportedMod).second )
597+ continue ;
598+ }
599+ } else {
600+ bool AnyNewDecls = false ;
601+ for (auto *ImportedDecl : ID->getDecls ()) {
602+ AnyNewDecls |= SeenImportedDecls.insert (ImportedDecl).second ;
603+ }
604+ if (!AnyNewDecls)
605+ continue ;
565606 }
607+
608+ ImportDecls.push_back (ID);
609+
566610 continue ;
567611 }
568612
@@ -684,9 +728,12 @@ void swift::ide::printModuleInterface(
684728
685729 // Imports from the stdlib are internal details that don't need to be exposed.
686730 if (!TargetMod->isStdlibModule ()) {
687- for (auto *D : ImportDecls)
731+ for (auto *D : ImportDecls) {
688732 PrintDecl (D);
689- Printer.printNewline ();
733+ }
734+ if (!ImportDecls.empty ()) {
735+ Printer.printNewline ();
736+ }
690737 }
691738
692739 {
0 commit comments