Skip to content

Commit 464223e

Browse files
authored
Merge pull request #81259 from bnbarham/cherry-merge-modules
[6.2][InterfaceGen] Merge exported modules with the same public name in generated interface
2 parents 8d86093 + d829fcf commit 464223e

File tree

35 files changed

+2854
-2994
lines changed

35 files changed

+2854
-2994
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,12 @@ struct PrintOptions {
234234
/// \see FileUnit::getExportedModuleName
235235
bool UseExportedModuleNames = false;
236236

237+
/// If true, printed module names will use the "public" (for documentation)
238+
/// name, which may be different from the regular name.
239+
///
240+
/// \see FileUnit::getPublicModuleName
241+
bool UsePublicModuleNames = false;
242+
237243
/// Use the original module name to qualify a symbol.
238244
bool UseOriginallyDefinedInModuleNames = false;
239245

@@ -704,6 +710,7 @@ struct PrintOptions {
704710
result.MapCrossImportOverlaysToDeclaringModule = true;
705711
result.PrintCurrentMembersOnly = false;
706712
result.SuppressExpandedMacros = true;
713+
result.UsePublicModuleNames = true;
707714
return result;
708715
}
709716

include/swift/IDE/ModuleInterfacePrinting.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@ namespace ide {
3838
/// Flags used when traversing a module for printing.
3939
enum class ModuleTraversal : unsigned {
4040
/// Visit modules even if their contents wouldn't be visible to name lookup.
41-
VisitHidden = 0x01,
41+
VisitHidden = 0x01,
4242
/// Visit submodules.
4343
VisitSubmodules = 0x02,
4444
/// Skip the declarations in a Swift overlay module.
45-
SkipOverlay = 0x04,
45+
SkipOverlay = 0x04,
46+
/// Visit exported modules where their public module name matches the current
47+
/// module.
48+
VisitMatchingExported = 0x08,
4649
};
4750

4851
/// Options used to describe the traversal of a module for printing.

lib/AST/ASTPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6009,6 +6009,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
60096009
Name = Mod->getASTContext().getIdentifier(ExportedModuleName);
60106010
}
60116011

6012+
StringRef PublicModuleName = File->getPublicModuleName();
6013+
if (Options.UsePublicModuleNames && !PublicModuleName.empty()) {
6014+
Name = Mod->getASTContext().getIdentifier(PublicModuleName);
6015+
}
6016+
60126017
if (Options.UseOriginallyDefinedInModuleNames) {
60136018
Decl *D = Ty->getDecl();
60146019
for (auto attr: D->getAttrs().getAttributes<OriginallyDefinedInAttr>()) {

lib/IDE/ModuleInterfacePrinting.cpp

Lines changed: 98 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
307335
static std::pair<ArrayRef<Decl*>, ArrayRef<Decl*>>
308336
getDeclsFromCrossImportOverlay(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
{

test/IDE/Inputs/foo_swift_module.printed.comments.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import SwiftOnoneSupport
2-
31
func %%% (lhs: Int, rhs: Int) -> Int
42
postfix func =-> (lhs: Int) -> Int
53
postfix func => (lhs: Int) -> Int

test/IDE/print_clang_framework_with_overlay.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,5 @@ import FooOverlay
1010
// CHECK: @_exported import Foo
1111
// CHECK: @_exported import struct Foo.FooStruct1
1212
// CHECK: @_exported import Foo.FooSub
13-
// CHECK: @_exported import func Foo.FooSub.fooSubFunc1
14-
// FIXME: this duplicate import is silly, but not harmful.
1513
// CHECK: @_exported import func Foo.fooSubFunc1
1614
// CHECK: func fooSubOverlayFunc1(x: Int32) -> Int32

test/SourceKit/CursorInfo/cursor_generated_interface.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class ASwiftType {
4141
}
4242

4343
// LibA is a mixed framework with no source info and a submodule
44-
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=12:36 -print-raw-response | %FileCheck %s --check-prefix=CHECKA
44+
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=11:36 -print-raw-response | %FileCheck %s --check-prefix=CHECKA
4545
// CHECKA: key.name: "ASwiftType"
4646
// CHECKA: key.modulename: "LibA"
4747
// CHECKA: key.decl_lang: source.lang.swift
@@ -60,7 +60,7 @@ framework module LibA {
6060
@interface AObjcType
6161
@end
6262

63-
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=12:54 -print-raw-response | %FileCheck %s --check-prefix=CHECKAOBJ
63+
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=11:54 -print-raw-response | %FileCheck %s --check-prefix=CHECKAOBJ
6464
// CHECKAOBJ: key.name: "AObjcType"
6565
// CHECKAOBJ: key.line: [[@LINE-5]]
6666
// CHECKAOBJ: key.column: 12
@@ -72,7 +72,7 @@ framework module LibA {
7272
@interface ASubType
7373
@end
7474

75-
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=12:70 -print-raw-response | %FileCheck %s --check-prefix=CHECKASUB
75+
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=11:70 -print-raw-response | %FileCheck %s --check-prefix=CHECKASUB
7676
// CHECKASUB: key.name: "ASubType"
7777
// CHECKASUB: key.line: [[@LINE-5]]
7878
// CHECKASUB: key.column: 12
@@ -84,7 +84,7 @@ framework module LibA {
8484
public class BType {}
8585

8686
// LibB has source info
87-
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=14:32 -print-raw-response | %FileCheck %s --check-prefix=CHECKB
87+
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=13:32 -print-raw-response | %FileCheck %s --check-prefix=CHECKB
8888
// CHECKB: key.name: "BType"
8989
// CHECKB: key.line: [[@LINE-5]]
9090
// CHECKB: key.column: 14
@@ -96,7 +96,7 @@ public class BType {}
9696
public class CType {}
9797

9898
// LibC has no source info
99-
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=14:47 -print-raw-response | %FileCheck %s --check-prefix=CHECKC
99+
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=13:47 -print-raw-response | %FileCheck %s --check-prefix=CHECKC
100100
// CHECKC: key.name: "CType"
101101
// CHECKC: key.modulename: "LibC"
102102
// CHECKC: key.decl_lang: source.lang.swift
@@ -105,7 +105,7 @@ public class CType {}
105105
@interface DType
106106
@end
107107
108-
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=14:57 -print-raw-response | %FileCheck %s --check-prefix=CHECKD
108+
// RUN: %sourcekitd-test -req=interface-gen-open -module LibA -- -F %t/frameworks -target %target-triple == -req=cursor -pos=13:57 -print-raw-response | %FileCheck %s --check-prefix=CHECKD
109109
// CHECKD: key.name: "DType"
110110
// CHECKD: key.line: [[@LINE-5]]
111111
// CHECKD: key.column: 12

0 commit comments

Comments
 (0)