@@ -304,6 +304,34 @@ static bool compareSwiftDecls(Decl *LHS, Decl *RHS) {
304
304
return LHS->getKind () < RHS->getKind ();
305
305
}
306
306
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
+
307
335
static std::pair<ArrayRef<Decl*>, ArrayRef<Decl*>>
308
336
getDeclsFromCrossImportOverlay (ModuleDecl *Overlay, ModuleDecl *Declaring,
309
337
SmallVectorImpl<Decl *> &Decls,
@@ -329,7 +357,8 @@ getDeclsFromCrossImportOverlay(ModuleDecl *Overlay, ModuleDecl *Declaring,
329
357
330
358
// Ignore imports of the underlying module, or any cross-import
331
359
// that would map back to it.
332
- if (Imported == Declaring || Imported->isCrossImportOverlayOf (Declaring))
360
+ if (!shouldPrintImport (ID, Declaring, nullptr ) ||
361
+ Imported->isCrossImportOverlayOf (Declaring))
333
362
return false ;
334
363
335
364
// Ignore an imports of modules also imported by the underlying module.
@@ -457,19 +486,40 @@ void swift::ide::printModuleInterface(
457
486
auto AdjustedOptions = Options;
458
487
adjustPrintOptions (AdjustedOptions);
459
488
489
+ llvm::DenseSet<const void *> SeenImportedDecls;
460
490
SmallVector<ModuleDecl *, 1 > ModuleList;
461
491
ModuleList.push_back (TargetMod);
492
+ SeenImportedDecls.insert (TargetMod);
462
493
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;
466
496
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
+ }
469
519
470
- // If we're printing recursively, find all of the submodules to print.
471
520
if (TargetClangMod) {
472
- if (TraversalOptions) {
521
+ // Add clang submodules if they're being visited
522
+ if (TraversalOptions & ModuleTraversal::VisitSubmodules) {
473
523
SmallVector<const clang::Module *, 8 > Worklist;
474
524
SmallPtrSet<const clang::Module *, 8 > Visited;
475
525
Worklist.push_back (TargetClangMod);
@@ -482,16 +532,15 @@ void swift::ide::printModuleInterface(
482
532
483
533
ClangDecls.insert ({ CM, {} });
484
534
485
- if (CM != TargetClangMod)
486
- if (auto *OwningModule = Importer.getWrapperForModule (CM))
535
+ if (CM != TargetClangMod) {
536
+ if (auto *OwningModule = Importer.getWrapperForModule (CM)) {
487
537
ModuleList.push_back (OwningModule);
538
+ }
539
+ }
488
540
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);
495
544
}
496
545
}
497
546
}
@@ -500,8 +549,7 @@ void swift::ide::printModuleInterface(
500
549
}
501
550
}
502
551
503
- SmallVector<Decl *, 1 > Decls;
504
-
552
+ SmallVector<Decl *, 0 > Decls;
505
553
for (ModuleDecl *M : ModuleList) {
506
554
swift::getTopLevelDeclsForDisplay (M, Decls);
507
555
}
@@ -527,42 +575,38 @@ void swift::ide::printModuleInterface(
527
575
continue ;
528
576
}
529
577
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 ;
533
581
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 ());
538
585
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.
548
589
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 ;
563
593
}
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 ;
565
606
}
607
+
608
+ ImportDecls.push_back (ID);
609
+
566
610
continue ;
567
611
}
568
612
@@ -684,9 +728,12 @@ void swift::ide::printModuleInterface(
684
728
685
729
// Imports from the stdlib are internal details that don't need to be exposed.
686
730
if (!TargetMod->isStdlibModule ()) {
687
- for (auto *D : ImportDecls)
731
+ for (auto *D : ImportDecls) {
688
732
PrintDecl (D);
689
- Printer.printNewline ();
733
+ }
734
+ if (!ImportDecls.empty ()) {
735
+ Printer.printNewline ();
736
+ }
690
737
}
691
738
692
739
{
0 commit comments