Skip to content

Commit 9857055

Browse files
authored
[SourceKit] Report synthesized protocol conformances for DocSupport request. rdar://36882292 (#14248)
1 parent b1092f8 commit 9857055

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
@@ -606,12 +606,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
606606
bool openBracket = true, bool closeBracket = true);
607607
void printNominalDeclGenericParams(NominalTypeDecl *decl);
608608
void printNominalDeclGenericRequirements(NominalTypeDecl *decl);
609-
void printInherited(const Decl *decl, ArrayRef<TypeLoc> inherited);
610-
611-
void printInherited(const NominalTypeDecl *D);
612-
void printInherited(const ExtensionDecl *D);
613-
void printInherited(const GenericTypeParamDecl *D);
614-
void printInherited(const AssociatedTypeDecl *D);
609+
void printInherited(const Decl *decl);
615610

616611
void printEnumElement(EnumElementDecl *elt);
617612

@@ -1665,29 +1660,10 @@ void PrintAST::printNominalDeclGenericRequirements(NominalTypeDecl *decl) {
16651660
printGenericSignature(GenericSig, PrintRequirements | InnermostOnly);
16661661
}
16671662

1668-
void PrintAST::printInherited(const Decl *decl, ArrayRef<TypeLoc> inherited) {
1663+
void PrintAST::printInherited(const Decl *decl) {
16691664
SmallVector<TypeLoc, 6> TypesToPrint;
1670-
for (auto TL : inherited) {
1671-
if (auto Ty = TL.getType()) {
1672-
if (auto NTD = Ty->getAnyNominal())
1673-
if (!shouldPrint(NTD))
1674-
continue;
1675-
}
1676-
TypesToPrint.push_back(TL);
1677-
}
1678-
1679-
auto &ctx = decl->getASTContext();
1680-
for (auto attr : decl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
1681-
if (auto *proto = ctx.getProtocol(attr->getProtocolKind())) {
1682-
if (!shouldPrint(proto))
1683-
continue;
1684-
if (attr->getProtocolKind() == KnownProtocolKind::RawRepresentable &&
1685-
isa<EnumDecl>(decl) &&
1686-
cast<EnumDecl>(decl)->hasRawType())
1687-
continue;
1688-
TypesToPrint.push_back(TypeLoc::withoutLoc(proto->getDeclaredType()));
1689-
}
1690-
}
1665+
getInheritedForPrinting(decl, [this](const Decl* D) { return shouldPrint(D); },
1666+
TypesToPrint);
16911667
if (TypesToPrint.empty())
16921668
return;
16931669

@@ -1700,22 +1676,6 @@ void PrintAST::printInherited(const Decl *decl, ArrayRef<TypeLoc> inherited) {
17001676
});
17011677
}
17021678

1703-
void PrintAST::printInherited(const NominalTypeDecl *D) {
1704-
printInherited(D, D->getInherited());
1705-
}
1706-
1707-
void PrintAST::printInherited(const ExtensionDecl *D) {
1708-
printInherited(D, D->getInherited());
1709-
}
1710-
1711-
void PrintAST::printInherited(const GenericTypeParamDecl *D) {
1712-
printInherited(D, D->getInherited());
1713-
}
1714-
1715-
void PrintAST::printInherited(const AssociatedTypeDecl *D) {
1716-
printInherited(D, D->getInherited());
1717-
}
1718-
17191679
static void getModuleEntities(const clang::Module *ClangMod,
17201680
SmallVectorImpl<ModuleEntity> &ModuleEnts) {
17211681
if (!ClangMod)
@@ -4308,3 +4268,39 @@ void swift::printEnumElementsAsCases(
43084268
OS << ": " << getCodePlaceholder() << "\n";
43094269
});
43104270
}
4271+
4272+
void
4273+
swift::getInheritedForPrinting(const Decl *decl,
4274+
llvm::function_ref<bool(const Decl*)> shouldPrint,
4275+
llvm::SmallVectorImpl<TypeLoc> &Results) {
4276+
ArrayRef<TypeLoc> inherited;
4277+
if (auto td = dyn_cast<TypeDecl>(decl)) {
4278+
inherited = td->getInherited();
4279+
} else if (auto ed = dyn_cast<ExtensionDecl>(decl)) {
4280+
inherited = ed->getInherited();
4281+
}
4282+
4283+
// Collect explicit inheritted types.
4284+
for (auto TL: inherited) {
4285+
if (auto Ty = TL.getType()) {
4286+
if (auto NTD = Ty->getAnyNominal())
4287+
if (!shouldPrint(NTD))
4288+
continue;
4289+
}
4290+
Results.push_back(TL);
4291+
}
4292+
4293+
// Collect synthesized conformances.
4294+
auto &ctx = decl->getASTContext();
4295+
for (auto attr : decl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
4296+
if (auto *proto = ctx.getProtocol(attr->getProtocolKind())) {
4297+
if (!shouldPrint(proto))
4298+
continue;
4299+
if (attr->getProtocolKind() == KnownProtocolKind::RawRepresentable &&
4300+
isa<EnumDecl>(decl) &&
4301+
cast<EnumDecl>(decl)->hasRawType())
4302+
continue;
4303+
Results.push_back(TypeLoc::withoutLoc(proto->getDeclaredType()));
4304+
}
4305+
}
4306+
}

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)