@@ -304,6 +304,33 @@ 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, const clang::Module *OrigClangMod) {
308
+ if (ImportD->getAttrs ().hasAttribute <ImplementationOnlyAttr>())
309
+ return false ;
310
+
311
+ auto *ImportedMod = ImportD->getModule ();
312
+ if (ImportedMod) {
313
+ if (ImportedMod == OrigMod)
314
+ return false ;
315
+ if (ImportedMod->isOnoneSupportModule ())
316
+ return false ;
317
+ if (ImportedMod->getName ().hasUnderscoredNaming ())
318
+ return false ;
319
+ }
320
+
321
+ if (!OrigClangMod)
322
+ return true ;
323
+
324
+ auto ImportedClangMod = ImportD->getClangModule ();
325
+ if (!ImportedClangMod)
326
+ return true ;
327
+ if (!ImportedClangMod->isSubModule ())
328
+ return true ;
329
+ if (ImportedClangMod == OrigClangMod)
330
+ return false ;
331
+ return ImportedClangMod->isSubModuleOf (OrigClangMod);
332
+ }
333
+
307
334
static std::pair<ArrayRef<Decl*>, ArrayRef<Decl*>>
308
335
getDeclsFromCrossImportOverlay (ModuleDecl *Overlay, ModuleDecl *Declaring,
309
336
SmallVectorImpl<Decl *> &Decls,
@@ -329,7 +356,8 @@ getDeclsFromCrossImportOverlay(ModuleDecl *Overlay, ModuleDecl *Declaring,
329
356
330
357
// Ignore imports of the underlying module, or any cross-import
331
358
// that would map back to it.
332
- if (Imported == Declaring || Imported->isCrossImportOverlayOf (Declaring))
359
+ if (!shouldPrintImport (ID, Declaring, nullptr ) ||
360
+ Imported->isCrossImportOverlayOf (Declaring))
333
361
return false ;
334
362
335
363
// Ignore an imports of modules also imported by the underlying module.
@@ -457,19 +485,40 @@ void swift::ide::printModuleInterface(
457
485
auto AdjustedOptions = Options;
458
486
adjustPrintOptions (AdjustedOptions);
459
487
488
+ llvm::DenseSet<const void *> SeenImportedDecls;
460
489
SmallVector<ModuleDecl *, 1 > ModuleList;
461
490
ModuleList.push_back (TargetMod);
491
+ SeenImportedDecls.insert (TargetMod);
462
492
463
- SmallVector<ImportDecl *, 1 > ImportDecls;
464
- llvm::DenseSet<const clang::Module *> ClangModulesForImports;
465
- SmallVector<Decl *, 1 > SwiftDecls;
493
+ SmallVector<ImportDecl *, 0 > ImportDecls;
494
+ SmallVector<Decl *, 0 > SwiftDecls;
466
495
llvm::DenseMap<const clang::Module *,
467
- SmallVector<std::pair<Decl *, clang::SourceLocation>, 1 >>
468
- ClangDecls;
496
+ SmallVector<std::pair<Decl *, clang::SourceLocation>, 0 >>
497
+ ClangDecls;
498
+
499
+ // Add exported modules that have the same public module name as this module
500
+ // (excluding the underlying clang module if there is one).
501
+ if (TraversalOptions & ModuleTraversal::VisitMatchingExported) {
502
+ SmallVector<ImportedModule> Imports;
503
+ TargetMod->getImportedModules (Imports,
504
+ ModuleDecl::ImportFilterKind::Exported);
505
+ for (ImportedModule Import : Imports) {
506
+ if (Import.importedModule ->getPublicModuleName (
507
+ /* onlyIfImported=*/ false ) != TargetMod->getName ())
508
+ continue ;
509
+
510
+ if (TargetClangMod != nullptr &&
511
+ Import.importedModule ->findUnderlyingClangModule () != TargetClangMod)
512
+ continue ;
513
+
514
+ ModuleList.push_back (Import.importedModule );
515
+ SeenImportedDecls.insert (Import.importedModule );
516
+ }
517
+ }
469
518
470
- // If we're printing recursively, find all of the submodules to print.
471
519
if (TargetClangMod) {
472
- if (TraversalOptions) {
520
+ // Add clang submodules if they're being visited
521
+ if (TraversalOptions & ModuleTraversal::VisitSubmodules) {
473
522
SmallVector<const clang::Module *, 8 > Worklist;
474
523
SmallPtrSet<const clang::Module *, 8 > Visited;
475
524
Worklist.push_back (TargetClangMod);
@@ -482,16 +531,15 @@ void swift::ide::printModuleInterface(
482
531
483
532
ClangDecls.insert ({ CM, {} });
484
533
485
- if (CM != TargetClangMod)
486
- if (auto *OwningModule = Importer.getWrapperForModule (CM))
534
+ if (CM != TargetClangMod) {
535
+ if (auto *OwningModule = Importer.getWrapperForModule (CM)) {
487
536
ModuleList.push_back (OwningModule);
537
+ }
538
+ }
488
539
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
- }
540
+ for (clang::Module *submodule : CM->submodules ()) {
541
+ if (Visited.insert (submodule).second ) {
542
+ Worklist.push_back (submodule);
495
543
}
496
544
}
497
545
}
@@ -500,8 +548,7 @@ void swift::ide::printModuleInterface(
500
548
}
501
549
}
502
550
503
- SmallVector<Decl *, 1 > Decls;
504
-
551
+ SmallVector<Decl *, 0 > Decls;
505
552
for (ModuleDecl *M : ModuleList) {
506
553
swift::getTopLevelDeclsForDisplay (M, Decls);
507
554
}
@@ -527,42 +574,38 @@ void swift::ide::printModuleInterface(
527
574
continue ;
528
575
}
529
576
530
- auto ShouldPrintImport = [&]( ImportDecl *ImportD) -> bool {
531
- if (ImportD-> getAttrs (). hasAttribute <ImplementationOnlyAttr>( ))
532
- return false ;
577
+ if ( auto ID = dyn_cast< ImportDecl>(D)) {
578
+ if (! shouldPrintImport (ID, TargetMod, TargetClangMod ))
579
+ continue ;
533
580
534
- if (!TargetClangMod)
535
- return true ;
536
- if (ImportD->getModule () == TargetMod)
537
- return false ;
581
+ // Erase submodules that are not missing
582
+ if (ID->getClangModule ())
583
+ NoImportSubModules.erase (ID->getClangModule ());
538
584
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
- };
585
+ if (ID->getImportKind () == ImportKind::Module) {
586
+ // Could have a duplicate import from a clang module's overlay or
587
+ // because we're merging modules. Skip them.
548
588
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
- }
589
+ if (auto *ClangMod = getUnderlyingClangModuleForImport (ID)) {
590
+ if (!SeenImportedDecls.insert (ClangMod).second )
591
+ continue ;
563
592
}
564
- ImportDecls.push_back (ID);
593
+
594
+ if (auto *ImportedMod = ID->getModule ()) {
595
+ if (!SeenImportedDecls.insert (ImportedMod).second )
596
+ continue ;
597
+ }
598
+ } else {
599
+ bool AnyNewDecls = false ;
600
+ for (auto *ImportedDecl : ID->getDecls ()) {
601
+ AnyNewDecls |= SeenImportedDecls.insert (ImportedDecl).second ;
602
+ }
603
+ if (!AnyNewDecls)
604
+ continue ;
565
605
}
606
+
607
+ ImportDecls.push_back (ID);
608
+
566
609
continue ;
567
610
}
568
611
@@ -684,9 +727,12 @@ void swift::ide::printModuleInterface(
684
727
685
728
// Imports from the stdlib are internal details that don't need to be exposed.
686
729
if (!TargetMod->isStdlibModule ()) {
687
- for (auto *D : ImportDecls)
730
+ for (auto *D : ImportDecls) {
688
731
PrintDecl (D);
689
- Printer.printNewline ();
732
+ }
733
+ if (!ImportDecls.empty ()) {
734
+ Printer.printNewline ();
735
+ }
690
736
}
691
737
692
738
{
0 commit comments