Skip to content

Commit 4402113

Browse files
author
Nathan Hawes
authored
Merge pull request #31596 from nathawes/doc-info-missing-submodule-decls-5.3
[5.3][IDE][DocSupport] Fix DocInfo missing decls when generated for clang submodules.
2 parents 028795c + 6249410 commit 4402113

File tree

9 files changed

+545
-236
lines changed

9 files changed

+545
-236
lines changed

include/swift/IDE/ModuleInterfacePrinting.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,11 @@ bool printTypeInterface(ModuleDecl *M, Type Ty, ASTPrinter &Printer,
5454
bool printTypeInterface(ModuleDecl *M, StringRef TypeUSR, ASTPrinter &Printer,
5555
std::string &TypeName, std::string &Error);
5656

57-
void printModuleInterface(ModuleDecl *M, Optional<StringRef> Group,
57+
void printModuleInterface(ModuleDecl *M, ArrayRef<StringRef> GroupNames,
5858
ModuleTraversalOptions TraversalOptions,
5959
ASTPrinter &Printer, const PrintOptions &Options,
6060
const bool PrintSynthesizedExtensions);
6161

62-
// FIXME: this API should go away when Swift can represent Clang submodules as
63-
// 'swift::ModuleDecl *' objects.
64-
void printSubmoduleInterface(ModuleDecl *M, ArrayRef<StringRef> FullModuleName,
65-
ArrayRef<StringRef> GroupNames,
66-
ModuleTraversalOptions TraversalOptions,
67-
ASTPrinter &Printer, const PrintOptions &Options,
68-
const bool PrintSynthesizedExtensions);
69-
7062
/// Print the interface for a header that has been imported via the implicit
7163
/// objc header importing feature.
7264
void printHeaderInterface(StringRef Filename, ASTContext &Ctx,

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2398,7 +2398,7 @@ class FilteringDeclaredDeclConsumer : public swift::VisibleDeclConsumer {
23982398
FilteringDeclaredDeclConsumer(swift::VisibleDeclConsumer &consumer,
23992399
const ClangModuleUnit *CMU)
24002400
: NextConsumer(consumer), ModuleFilter(CMU) {
2401-
assert(CMU);
2401+
assert(CMU && CMU->isTopLevel() && "Only top-level modules supported");
24022402
}
24032403

24042404
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason,

lib/IDE/ModuleInterfacePrinting.cpp

Lines changed: 43 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,6 @@ printTypeInterface(ModuleDecl *M, StringRef TypeUSR, ASTPrinter &Printer,
189189
Printer, TypeName, Error);
190190
}
191191

192-
void swift::ide::printModuleInterface(ModuleDecl *M, Optional<StringRef> Group,
193-
ModuleTraversalOptions TraversalOptions,
194-
ASTPrinter &Printer,
195-
const PrintOptions &Options,
196-
const bool PrintSynthesizedExtensions) {
197-
printSubmoduleInterface(M, M->getName().str(),
198-
Group.hasValue() ? Group.getValue() : ArrayRef<StringRef>(),
199-
TraversalOptions, Printer, Options,
200-
PrintSynthesizedExtensions);
201-
}
202-
203192
static void adjustPrintOptions(PrintOptions &AdjustedOptions) {
204193
// Don't print empty curly braces while printing the module interface.
205194
AdjustedOptions.FunctionDefinitions = false;
@@ -230,7 +219,7 @@ static bool extensionHasClangNode(ExtensionDecl *ext) {
230219

231220
Optional<StringRef>
232221
swift::ide::findGroupNameForUSR(ModuleDecl *M, StringRef USR) {
233-
for (auto File : M->getFiles()) {
222+
for (auto File : M->getTopLevelModule()->getFiles()) {
234223
if (auto Name = File->getGroupNameByUSR(USR)) {
235224
return Name;
236225
}
@@ -539,53 +528,45 @@ static void printCrossImportOverlays(ModuleDecl *Declaring, ASTContext &Ctx,
539528
}
540529
}
541530

542-
void swift::ide::printSubmoduleInterface(
543-
ModuleDecl *M,
544-
ArrayRef<StringRef> FullModuleName,
531+
void swift::ide::printModuleInterface(
532+
ModuleDecl *TargetMod,
545533
ArrayRef<StringRef> GroupNames,
546534
ModuleTraversalOptions TraversalOptions,
547535
ASTPrinter &Printer,
548536
const PrintOptions &Options,
549537
const bool PrintSynthesizedExtensions) {
550-
auto &SwiftContext = M->getASTContext();
538+
539+
// Clang submodules aren't handled well by `getDisplayDecls()` (no decls are
540+
// returned), so map them to their top-level module and filter out the extra
541+
// results below.
542+
const clang::Module *TargetClangMod = TargetMod->findUnderlyingClangModule();
543+
ModuleDecl *TopLevelMod = TargetMod->getTopLevelModule();
544+
bool IsSubmodule = TargetMod != TopLevelMod;
545+
546+
auto &SwiftContext = TopLevelMod->getASTContext();
551547
auto &Importer =
552548
static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());
553549

554550
auto AdjustedOptions = Options;
555551
adjustPrintOptions(AdjustedOptions);
556552

557553
SmallVector<Decl *, 1> Decls;
558-
M->getDisplayDecls(Decls);
554+
TopLevelMod->getDisplayDecls(Decls);
559555

560-
const clang::Module *InterestingClangModule = nullptr;
561556
SmallVector<ImportDecl *, 1> ImportDecls;
562557
llvm::DenseSet<const clang::Module *> ClangModulesForImports;
563558
SmallVector<Decl *, 1> SwiftDecls;
564559
llvm::DenseMap<const clang::Module *,
565560
SmallVector<std::pair<Decl *, clang::SourceLocation>, 1>>
566561
ClangDecls;
567562

568-
// Drop top-level module name.
569-
FullModuleName = FullModuleName.slice(1);
570-
571-
InterestingClangModule = M->findUnderlyingClangModule();
572-
if (InterestingClangModule) {
573-
for (StringRef Name : FullModuleName) {
574-
InterestingClangModule = InterestingClangModule->findSubmodule(Name);
575-
if (!InterestingClangModule)
576-
return;
577-
}
578-
} else {
579-
assert(FullModuleName.empty());
580-
}
581-
582563
// If we're printing recursively, find all of the submodules to print.
583-
if (InterestingClangModule) {
564+
if (TargetClangMod) {
584565
if (TraversalOptions) {
585566
SmallVector<const clang::Module *, 8> Worklist;
586567
SmallPtrSet<const clang::Module *, 8> Visited;
587-
Worklist.push_back(InterestingClangModule);
588-
Visited.insert(InterestingClangModule);
568+
Worklist.push_back(TargetClangMod);
569+
Visited.insert(TargetClangMod);
589570
while (!Worklist.empty()) {
590571
const clang::Module *CM = Worklist.pop_back_val();
591572
if (!(TraversalOptions & ModuleTraversal::VisitHidden) &&
@@ -604,17 +585,17 @@ void swift::ide::printSubmoduleInterface(
604585
}
605586
}
606587
} else {
607-
ClangDecls.insert({ InterestingClangModule, {} });
588+
ClangDecls.insert({ TargetClangMod, {} });
608589
}
609590
}
610591

611-
// Collect those submodules that are actually imported but have no import decls
612-
// in the module.
592+
// Collect those submodules that are actually imported but have no import
593+
// decls in the module.
613594
llvm::SmallPtrSet<const clang::Module *, 16> NoImportSubModules;
614-
if (InterestingClangModule) {
595+
if (TargetClangMod) {
615596
// Assume all submodules are missing.
616-
for (auto It =InterestingClangModule->submodule_begin();
617-
It != InterestingClangModule->submodule_end(); It++) {
597+
for (auto It = TargetClangMod->submodule_begin();
598+
It != TargetClangMod->submodule_end(); It++) {
618599
NoImportSubModules.insert(*It);
619600
}
620601
}
@@ -631,18 +612,18 @@ void swift::ide::printSubmoduleInterface(
631612
}
632613

633614
auto ShouldPrintImport = [&](ImportDecl *ImportD) -> bool {
634-
if (!InterestingClangModule)
615+
if (!TargetClangMod)
635616
return true;
636-
auto ClangMod = ImportD->getClangModule();
637-
if (!ClangMod)
617+
auto ImportedMod = ImportD->getClangModule();
618+
if (!ImportedMod)
638619
return true;
639-
if (!ClangMod->isSubModule())
620+
if (!ImportedMod->isSubModule())
640621
return true;
641-
if (ClangMod == InterestingClangModule)
622+
if (ImportedMod == TargetClangMod)
642623
return false;
643624
// FIXME: const-ness on the clang API.
644-
return ClangMod->isSubModuleOf(
645-
const_cast<clang::Module*>(InterestingClangModule));
625+
return ImportedMod->isSubModuleOf(
626+
const_cast<clang::Module*>(TargetClangMod));
646627
};
647628

648629
if (auto ID = dyn_cast<ImportDecl>(D)) {
@@ -690,14 +671,16 @@ void swift::ide::printSubmoduleInterface(
690671
}
691672
}
692673

693-
if (FullModuleName.empty()) {
674+
if (!IsSubmodule) {
694675
// If group name is given and the decl does not belong to the group, skip it.
695676
if (!GroupNames.empty()){
696-
if (auto Target = D->getGroupName()) {
677+
if (auto TargetGroup = D->getGroupName()) {
697678
if (std::find(GroupNames.begin(), GroupNames.end(),
698-
Target.getValue()) != GroupNames.end()) {
699-
FileRangedDecls.insert(std::make_pair(D->getSourceFileName().getValue(),
700-
std::vector<Decl*>())).first->getValue().push_back(D);
679+
TargetGroup.getValue()) != GroupNames.end()) {
680+
FileRangedDecls.insert({
681+
D->getSourceFileName().getValue(),
682+
std::vector<Decl*>()
683+
}).first->getValue().push_back(D);
701684
}
702685
}
703686
continue;
@@ -725,8 +708,9 @@ void swift::ide::printSubmoduleInterface(
725708
}
726709

727710
// Create the missing import decls and add to the collector.
728-
for (auto *SM : NoImportSubModules) {
729-
ImportDecls.push_back(createImportDecl(M->getASTContext(), M, SM, {}));
711+
for (auto *SubMod : NoImportSubModules) {
712+
ImportDecls.push_back(createImportDecl(TopLevelMod->getASTContext(),
713+
TopLevelMod, SubMod, {}));
730714
}
731715

732716
// Sort imported clang declarations in source order *within a submodule*.
@@ -760,7 +744,7 @@ void swift::ide::printSubmoduleInterface(
760744
};
761745

762746
// Imports from the stdlib are internal details that don't need to be exposed.
763-
if (!M->isStdlibModule()) {
747+
if (!TargetMod->isStdlibModule()) {
764748
for (auto *D : ImportDecls)
765749
PrintDecl(D);
766750
Printer << "\n";
@@ -785,8 +769,7 @@ void swift::ide::printSubmoduleInterface(
785769
}
786770
}
787771

788-
if (!(TraversalOptions & ModuleTraversal::SkipOverlay) ||
789-
!InterestingClangModule) {
772+
if (!(TraversalOptions & ModuleTraversal::SkipOverlay) || !TargetClangMod) {
790773
for (auto *D : SwiftDecls) {
791774
if (PrintDecl(D))
792775
Printer << "\n";
@@ -796,8 +779,8 @@ void swift::ide::printSubmoduleInterface(
796779
// also print the decls from any underscored Swift cross-import overlays it
797780
// is the underlying module of, transitively.
798781
if (GroupNames.empty()) {
799-
printCrossImportOverlays(M, SwiftContext, *PrinterToUse, AdjustedOptions,
800-
PrintSynthesizedExtensions);
782+
printCrossImportOverlays(TargetMod, SwiftContext, *PrinterToUse,
783+
AdjustedOptions, PrintSynthesizedExtensions);
801784
}
802785
}
803786
}

test/SourceKit/DocSupport/doc_clang_module.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@
99
// RUN: %sourcekitd-test -req=doc-info -module Foo -- -F %S/../Inputs/libIDE-mock-sdk \
1010
// RUN: -target %target-triple %clang-importer-sdk-nosource -I %t | %sed_clean > %t.response
1111
// RUN: %diff -u %s.response %t.response
12+
13+
// RUN: %sourcekitd-test -req=doc-info -module Foo.FooSub -- -F %S/../Inputs/libIDE-mock-sdk \
14+
// RUN: -target %target-triple %clang-importer-sdk-nosource -I %t | %sed_clean > %t.response
15+
// RUN: %diff -u %s.sub.response %t.response

0 commit comments

Comments
 (0)