Skip to content

Commit 6bb3ac3

Browse files
authored
[SourceKit] Report synthesized protocol conformances for DocSupport request. rdar://36882292 (swiftlang#14248) (swiftlang#14287)
1 parent 8a7c44c commit 6bb3ac3

File tree

4 files changed

+103
-45
lines changed

4 files changed

+103
-45
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ StringRef getCodePlaceholder();
324324
void printEnumElementsAsCases(
325325
llvm::DenseSet<EnumElementDecl *> &UnhandledElements,
326326
llvm::raw_ostream &OS);
327+
328+
void getInheritedForPrinting(const Decl *decl,
329+
llvm::function_ref<bool(const Decl*)> shouldPrint,
330+
llvm::SmallVectorImpl<TypeLoc> &Results);
331+
327332
} // namespace swift
328333

329334
#endif // LLVM_SWIFT_AST_ASTPRINTER_H

lib/AST/ASTPrinter.cpp

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -594,12 +594,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
594594
bool openBracket = true, bool closeBracket = true);
595595
void printNominalDeclGenericParams(NominalTypeDecl *decl);
596596
void printNominalDeclGenericRequirements(NominalTypeDecl *decl);
597-
void printInherited(const Decl *decl, ArrayRef<TypeLoc> inherited);
598-
599-
void printInherited(const NominalTypeDecl *D);
600-
void printInherited(const ExtensionDecl *D);
601-
void printInherited(const GenericTypeParamDecl *D);
602-
void printInherited(const AssociatedTypeDecl *D);
597+
void printInherited(const Decl *decl);
603598

604599
void printEnumElement(EnumElementDecl *elt);
605600

@@ -1656,29 +1651,10 @@ void PrintAST::printNominalDeclGenericRequirements(NominalTypeDecl *decl) {
16561651
printGenericSignature(GenericSig, PrintRequirements | InnermostOnly);
16571652
}
16581653

1659-
void PrintAST::printInherited(const Decl *decl, ArrayRef<TypeLoc> inherited) {
1654+
void PrintAST::printInherited(const Decl *decl) {
16601655
SmallVector<TypeLoc, 6> TypesToPrint;
1661-
for (auto TL : inherited) {
1662-
if (auto Ty = TL.getType()) {
1663-
if (auto NTD = Ty->getAnyNominal())
1664-
if (!shouldPrint(NTD))
1665-
continue;
1666-
}
1667-
TypesToPrint.push_back(TL);
1668-
}
1669-
1670-
auto &ctx = decl->getASTContext();
1671-
for (auto attr : decl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
1672-
if (auto *proto = ctx.getProtocol(attr->getProtocolKind())) {
1673-
if (!shouldPrint(proto))
1674-
continue;
1675-
if (attr->getProtocolKind() == KnownProtocolKind::RawRepresentable &&
1676-
isa<EnumDecl>(decl) &&
1677-
cast<EnumDecl>(decl)->hasRawType())
1678-
continue;
1679-
TypesToPrint.push_back(TypeLoc::withoutLoc(proto->getDeclaredType()));
1680-
}
1681-
}
1656+
getInheritedForPrinting(decl, [this](const Decl* D) { return shouldPrint(D); },
1657+
TypesToPrint);
16821658
if (TypesToPrint.empty())
16831659
return;
16841660

@@ -1691,22 +1667,6 @@ void PrintAST::printInherited(const Decl *decl, ArrayRef<TypeLoc> inherited) {
16911667
});
16921668
}
16931669

1694-
void PrintAST::printInherited(const NominalTypeDecl *D) {
1695-
printInherited(D, D->getInherited());
1696-
}
1697-
1698-
void PrintAST::printInherited(const ExtensionDecl *D) {
1699-
printInherited(D, D->getInherited());
1700-
}
1701-
1702-
void PrintAST::printInherited(const GenericTypeParamDecl *D) {
1703-
printInherited(D, D->getInherited());
1704-
}
1705-
1706-
void PrintAST::printInherited(const AssociatedTypeDecl *D) {
1707-
printInherited(D, D->getInherited());
1708-
}
1709-
17101670
static void getModuleEntities(const clang::Module *ClangMod,
17111671
SmallVectorImpl<ModuleEntity> &ModuleEnts) {
17121672
if (!ClangMod)
@@ -4238,3 +4198,39 @@ void swift::printEnumElementsAsCases(
42384198
OS << ": " << getCodePlaceholder() << "\n";
42394199
});
42404200
}
4201+
4202+
void
4203+
swift::getInheritedForPrinting(const Decl *decl,
4204+
llvm::function_ref<bool(const Decl*)> shouldPrint,
4205+
llvm::SmallVectorImpl<TypeLoc> &Results) {
4206+
ArrayRef<TypeLoc> inherited;
4207+
if (auto td = dyn_cast<TypeDecl>(decl)) {
4208+
inherited = td->getInherited();
4209+
} else if (auto ed = dyn_cast<ExtensionDecl>(decl)) {
4210+
inherited = ed->getInherited();
4211+
}
4212+
4213+
// Collect explicit inheritted types.
4214+
for (auto TL: inherited) {
4215+
if (auto Ty = TL.getType()) {
4216+
if (auto NTD = Ty->getAnyNominal())
4217+
if (!shouldPrint(NTD))
4218+
continue;
4219+
}
4220+
Results.push_back(TL);
4221+
}
4222+
4223+
// Collect synthesized conformances.
4224+
auto &ctx = decl->getASTContext();
4225+
for (auto attr : decl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
4226+
if (auto *proto = ctx.getProtocol(attr->getProtocolKind())) {
4227+
if (!shouldPrint(proto))
4228+
continue;
4229+
if (attr->getProtocolKind() == KnownProtocolKind::RawRepresentable &&
4230+
isa<EnumDecl>(decl) &&
4231+
cast<EnumDecl>(decl)->hasRawType())
4232+
continue;
4233+
Results.push_back(TypeLoc::withoutLoc(proto->getDeclaredType()));
4234+
}
4235+
}
4236+
}

test/SourceKit/DocSupport/doc_clang_module.swift.response

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4550,6 +4550,18 @@ var FooSubUnnamedEnumeratorA1: Int { get }
45504550
key.offset: 36,
45514551
key.length: 205,
45524552
key.fully_annotated_decl: "<decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>FooEnum1</decl.name> : <ref.protocol usr=\"s:s9EquatableP\">Equatable</ref.protocol>, <ref.protocol usr=\"s:s16RawRepresentableP\">RawRepresentable</ref.protocol></decl.struct>",
4553+
key.conforms: [
4554+
{
4555+
key.kind: source.lang.swift.ref.protocol,
4556+
key.name: "Equatable",
4557+
key.usr: "s:s9EquatableP"
4558+
},
4559+
{
4560+
key.kind: source.lang.swift.ref.protocol,
4561+
key.name: "RawRepresentable",
4562+
key.usr: "s:s16RawRepresentableP"
4563+
}
4564+
],
45534565
key.entities: [
45544566
{
45554567
key.kind: source.lang.swift.decl.function.constructor,
@@ -4651,6 +4663,18 @@ var FooSubUnnamedEnumeratorA1: Int { get }
46514663
key.offset: 274,
46524664
key.length: 205,
46534665
key.fully_annotated_decl: "<decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>FooEnum2</decl.name> : <ref.protocol usr=\"s:s9EquatableP\">Equatable</ref.protocol>, <ref.protocol usr=\"s:s16RawRepresentableP\">RawRepresentable</ref.protocol></decl.struct>",
4666+
key.conforms: [
4667+
{
4668+
key.kind: source.lang.swift.ref.protocol,
4669+
key.name: "Equatable",
4670+
key.usr: "s:s9EquatableP"
4671+
},
4672+
{
4673+
key.kind: source.lang.swift.ref.protocol,
4674+
key.name: "RawRepresentable",
4675+
key.usr: "s:s16RawRepresentableP"
4676+
}
4677+
],
46544678
key.entities: [
46554679
{
46564680
key.kind: source.lang.swift.decl.function.constructor,
@@ -4759,6 +4783,18 @@ var FooSubUnnamedEnumeratorA1: Int { get }
47594783
key.offset: 544,
47604784
key.length: 205,
47614785
key.fully_annotated_decl: "<decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>FooEnum3</decl.name> : <ref.protocol usr=\"s:s9EquatableP\">Equatable</ref.protocol>, <ref.protocol usr=\"s:s16RawRepresentableP\">RawRepresentable</ref.protocol></decl.struct>",
4786+
key.conforms: [
4787+
{
4788+
key.kind: source.lang.swift.ref.protocol,
4789+
key.name: "Equatable",
4790+
key.usr: "s:s9EquatableP"
4791+
},
4792+
{
4793+
key.kind: source.lang.swift.ref.protocol,
4794+
key.name: "RawRepresentable",
4795+
key.usr: "s:s16RawRepresentableP"
4796+
}
4797+
],
47624798
key.entities: [
47634799
{
47644800
key.kind: source.lang.swift.decl.function.constructor,
@@ -4936,6 +4972,13 @@ var FooSubUnnamedEnumeratorA1: Int { get }
49364972
key.offset: 1011,
49374973
key.length: 337,
49384974
key.fully_annotated_decl: "<decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>FooRuncingOptions</decl.name> : <ref.protocol usr=\"s:s9OptionSetP\">OptionSet</ref.protocol></decl.struct>",
4975+
key.conforms: [
4976+
{
4977+
key.kind: source.lang.swift.ref.protocol,
4978+
key.name: "OptionSet",
4979+
key.usr: "s:s9OptionSetP"
4980+
}
4981+
],
49394982
key.entities: [
49404983
{
49414984
key.kind: source.lang.swift.decl.function.constructor,
@@ -7059,6 +7102,18 @@ var FooSubUnnamedEnumeratorA1: Int { get }
70597102
key.offset: 7408,
70607103
key.length: 214,
70617104
key.fully_annotated_decl: "<decl.struct><syntaxtype.keyword>struct</syntaxtype.keyword> <decl.name>FooSubEnum1</decl.name> : <ref.protocol usr=\"s:s9EquatableP\">Equatable</ref.protocol>, <ref.protocol usr=\"s:s16RawRepresentableP\">RawRepresentable</ref.protocol></decl.struct>",
7105+
key.conforms: [
7106+
{
7107+
key.kind: source.lang.swift.ref.protocol,
7108+
key.name: "Equatable",
7109+
key.usr: "s:s9EquatableP"
7110+
},
7111+
{
7112+
key.kind: source.lang.swift.ref.protocol,
7113+
key.name: "RawRepresentable",
7114+
key.usr: "s:s16RawRepresentableP"
7115+
}
7116+
],
70627117
key.entities: [
70637118
{
70647119
key.kind: source.lang.swift.decl.function.constructor,

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,9 @@ static void reportRelated(ASTContext &Ctx,
549549
// Otherwise, report the inheritance of the type alias itself.
550550
passInheritsAndConformancesForValueDecl(TAD, Consumer);
551551
} else if (const auto *TD = dyn_cast<TypeDecl>(D)) {
552-
passInherits(TD->getInherited(), Consumer);
552+
llvm::SmallVector<TypeLoc, 4> AllInherits;
553+
getInheritedForPrinting(TD, [](const Decl* d) { return true; }, AllInherits);
554+
passInherits(AllInherits, Consumer);
553555
passConforms(TD->getSatisfiedProtocolRequirements(/*Sorted=*/true),
554556
Consumer);
555557
} else if (auto *VD = dyn_cast<ValueDecl>(D)) {

0 commit comments

Comments
 (0)