Skip to content

Commit 477af9f

Browse files
authored
Merge pull request #31162 from bitjammer/acgarland/rdar-62040714-type-abridged-subheading-fragments
[SymbolGraph] Type subheadings: don't print generics/inheritance
2 parents c0b5cb9 + 115a8de commit 477af9f

File tree

4 files changed

+160
-11
lines changed

4 files changed

+160
-11
lines changed

lib/SymbolGraphGen/DeclarationFragmentPrinter.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/AST/USRGeneration.h"
14+
#include "swift/Syntax/TokenKinds.h"
1415
#include "DeclarationFragmentPrinter.h"
1516
#include "SymbolGraphASTWalker.h"
1617

@@ -146,3 +147,39 @@ void DeclarationFragmentPrinter::printText(StringRef Text) {
146147
}
147148
Spelling.append(Text);
148149
}
150+
151+
void DeclarationFragmentPrinter::printAbridgedType(const GenericTypeDecl *TD) {
152+
// Subheadings for types are abridged, omitting generics and inheritance.
153+
openFragment(DeclarationFragmentPrinter::FragmentKind::Keyword);
154+
switch (TD->getKind()) {
155+
case DeclKind::Struct:
156+
printText(getTokenText(tok::kw_struct));
157+
break;
158+
case DeclKind::Enum:
159+
printText(getTokenText(tok::kw_enum));
160+
break;
161+
case DeclKind::Protocol:
162+
printText(getTokenText(tok::kw_protocol));
163+
break;
164+
case DeclKind::Class:
165+
printText(getTokenText(tok::kw_class));
166+
break;
167+
case DeclKind::TypeAlias:
168+
printText(getTokenText(tok::kw_typealias));
169+
break;
170+
case DeclKind::OpaqueType:
171+
llvm_unreachable("OpaqueType should not be in symbol graphs!");
172+
default:
173+
llvm_unreachable("GenericTypeDecl kind not handled in DeclarationFragmentPrinter!");
174+
}
175+
176+
openFragment(DeclarationFragmentPrinter::FragmentKind::Text);
177+
printText(" ");
178+
179+
openFragment(DeclarationFragmentPrinter::FragmentKind::TypeIdentifier);
180+
printText(TD->getNameStr());
181+
182+
USR.clear();
183+
llvm::raw_svector_ostream USROS(USR);
184+
ide::printDeclUSR(TD, USROS);
185+
}

lib/SymbolGraphGen/DeclarationFragmentPrinter.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace swift {
2222
class Decl;
2323
class Type;
2424
class TypeDecl;
25+
class GenericTypeDecl;
2526

2627
namespace symbolgraphgen {
2728

@@ -43,6 +44,7 @@ struct SymbolGraph;
4344
///
4445
/// Will have fragments representing the `func foo()` part.
4546
class DeclarationFragmentPrinter : public ASTPrinter {
47+
public:
4648
enum class FragmentKind {
4749
None,
4850
Keyword,
@@ -56,7 +58,7 @@ class DeclarationFragmentPrinter : public ASTPrinter {
5658
InternalParam,
5759
Text,
5860
};
59-
61+
private:
6062
/// The output stream to print fragment objects to.
6163
llvm::json::OStream &OS;
6264

@@ -92,6 +94,13 @@ class DeclarationFragmentPrinter : public ASTPrinter {
9294
}
9395
}
9496

97+
/// Print an abridged form of a nominal type declaration, as:
98+
/// keyword text(" ") typeIdentifier.
99+
///
100+
/// Subheadings for types don't include the complete declaration line
101+
/// including generics and inheritance.
102+
void printAbridgedType(const GenericTypeDecl *TD);
103+
95104
void printDeclLoc(const Decl *D) override;
96105

97106
void printDeclNameEndLoc(const Decl *D) override {
@@ -109,6 +118,8 @@ class DeclarationFragmentPrinter : public ASTPrinter {
109118
void printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name,
110119
PrintNameContext NameContext) override;
111120

121+
/// Print plain text to the current fragment, opening a new text fragment
122+
/// if there isn't an open fragment.
112123
void printText(StringRef Text) override;
113124

114125
~DeclarationFragmentPrinter() {

lib/SymbolGraphGen/SymbolGraph.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -476,17 +476,22 @@ SymbolGraph::serializeSubheadingDeclarationFragments(StringRef Key,
476476
const Symbol &S,
477477
llvm::json::OStream &OS) {
478478
DeclarationFragmentPrinter Printer(OS, Key);
479-
auto Options = getDeclarationFragmentsPrintOptions();
480-
Options.ArgAndParamPrinting =
481-
PrintOptions::ArgAndParamPrintingMode::ArgumentOnly;
482-
Options.VarInitializers = false;
483-
Options.PrintDefaultArgumentValue = false;
484-
Options.PrintEmptyArgumentNames = false;
485-
Options.PrintOverrideKeyword = false;
486-
if (S.getSynthesizedBaseType()) {
487-
Options.setBaseType(S.getSynthesizedBaseType());
479+
480+
if (const auto *TD = dyn_cast<GenericTypeDecl>(S.getSymbolDecl())) {
481+
Printer.printAbridgedType(TD);
482+
} else {
483+
auto Options = getDeclarationFragmentsPrintOptions();
484+
Options.ArgAndParamPrinting =
485+
PrintOptions::ArgAndParamPrintingMode::ArgumentOnly;
486+
Options.VarInitializers = false;
487+
Options.PrintDefaultArgumentValue = false;
488+
Options.PrintEmptyArgumentNames = false;
489+
Options.PrintOverrideKeyword = false;
490+
if (S.getSynthesizedBaseType()) {
491+
Options.setBaseType(S.getSynthesizedBaseType());
492+
}
493+
S.getSymbolDecl()->print(Printer, Options);
488494
}
489-
S.getSymbolDecl()->print(Printer, Options);
490495
}
491496

492497
void
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -module-name SubheadingDeclarationFragmentsTypes -emit-module -emit-module-path %t/
3+
// RUN: %target-swift-symbolgraph-extract -module-name SubheadingDeclarationFragmentsTypes -I %t -pretty-print -output-dir %t
4+
// RUN: %FileCheck %s --input-file %t/SubheadingDeclarationFragmentsTypes.symbols.json --check-prefix=STRUCT
5+
// RUN: %FileCheck %s --input-file %t/SubheadingDeclarationFragmentsTypes.symbols.json --check-prefix=ENUM
6+
// RUN: %FileCheck %s --input-file %t/SubheadingDeclarationFragmentsTypes.symbols.json --check-prefix=PROTOCOL
7+
// RUN: %FileCheck %s --input-file %t/SubheadingDeclarationFragmentsTypes.symbols.json --check-prefix=CLASS
8+
// RUN: %FileCheck %s --input-file %t/SubheadingDeclarationFragmentsTypes.symbols.json --check-prefix=TYPEALIAS
9+
10+
// STRUCT-LABEL: "precise": "s:35SubheadingDeclarationFragmentsTypes6StructV"
11+
// STRUCT: subHeading
12+
// STRUCT-NEXT {
13+
// STRUCT-NEXT "kind": "keyword",
14+
// STRUCT-NEXT "spelling": "struct"
15+
// STRUCT-NEXT }
16+
// STRUCT-NEXT {
17+
// STRUCT-NEXT "kind": "text",
18+
// STRUCT-NEXT "spelling": " "
19+
// STRUCT-NEXT }
20+
// STRUCT-NEXT {
21+
// STRUCT-NEXT "kind": "typeIdentifier",
22+
// STRUCT-NEXT "spelling": "Struct",
23+
// STRUCT-NEXT "preciseIdentifier": "s:35SubheadingDeclarationFragmentsTypes6StructV"
24+
// STRUCT-NEXT }
25+
public struct Struct<T> where T: Sequence {}
26+
27+
// ENUM-LABEL: "precise": "s:35SubheadingDeclarationFragmentsTypes4EnumO"
28+
// ENUM: subHeading
29+
// ENUM-NEXT: {
30+
// ENUM-NEXT: "kind": "keyword",
31+
// ENUM-NEXT: "spelling": "enum"
32+
// ENUM-NEXT: }
33+
// ENUM-NEXT: {
34+
// ENUM-NEXT: "kind": "text",
35+
// ENUM-NEXT: "spelling": " "
36+
// ENUM-NEXT: }
37+
// ENUM-NEXT: {
38+
// ENUM-NEXT: "kind": "typeIdentifier",
39+
// ENUM-NEXT: "spelling": "Enum",
40+
// ENUM-NEXT: "preciseIdentifier": "s:35SubheadingDeclarationFragmentsTypes4EnumO"
41+
// ENUM-NEXT: }
42+
public enum Enum<T> where T: Sequence {}
43+
44+
// PROTOCOL-LABEL: "precise": "s:35SubheadingDeclarationFragmentsTypes8ProtocolP"
45+
// PROTOCOL: subHeading
46+
// PROTOCOL-NEXT: {
47+
// PROTOCOL-NEXT: "kind": "keyword",
48+
// PROTOCOL-NEXT: "spelling": "protocol"
49+
// PROTOCOL-NEXT: }
50+
// PROTOCOL-NEXT: {
51+
// PROTOCOL-NEXT: "kind": "text",
52+
// PROTOCOL-NEXT: "spelling": " "
53+
// PROTOCOL-NEXT: }
54+
// PROTOCOL-NEXT: {
55+
// PROTOCOL-NEXT: "kind": "typeIdentifier",
56+
// PROTOCOL-NEXT: "spelling": "Protocol",
57+
// PROTOCOL-NEXT: "preciseIdentifier": "s:35SubheadingDeclarationFragmentsTypes8ProtocolP"
58+
// PROTOCOL-NEXT: }
59+
public protocol Protocol where T: Sequence {
60+
associatedtype T
61+
}
62+
63+
// CLASS-LABEL: "precise": "s:35SubheadingDeclarationFragmentsTypes5ClassC"
64+
// CLASS: subHeading
65+
// CLASS-NEXT {
66+
// CLASS-NEXT "kind": "keyword",
67+
// CLASS-NEXT "spelling": "class"
68+
// CLASS-NEXT },
69+
// CLASS-NEXT {
70+
// CLASS-NEXT "kind": "text",
71+
// CLASS-NEXT "spelling": " "
72+
// CLASS-NEXT },
73+
// CLASS-NEXT {
74+
// CLASS-NEXT "kind": "typeIdentifier",
75+
// CLASS-NEXT "spelling": "Class",
76+
// CLASS-NEXT "preciseIdentifier": "s:35SubheadingDeclarationFragmentsTypes5ClassC"
77+
// CLASS-NEXT }
78+
public class Class<T> where T: Sequence {}
79+
80+
// TYPEALIAS-LABEL: "precise": "s:35SubheadingDeclarationFragmentsTypes9TypeAliasa"
81+
// TYPEALIAS: subHeading
82+
// TYPEALIAS-NEXT: {
83+
// TYPEALIAS-NEXT: "kind": "keyword",
84+
// TYPEALIAS-NEXT: "spelling": "typealias"
85+
// TYPEALIAS-NEXT: },
86+
// TYPEALIAS-NEXT: {
87+
// TYPEALIAS-NEXT: "kind": "text",
88+
// TYPEALIAS-NEXT: "spelling": " "
89+
// TYPEALIAS-NEXT: },
90+
// TYPEALIAS-NEXT: {
91+
// TYPEALIAS-NEXT: "kind": "typeIdentifier",
92+
// TYPEALIAS-NEXT: "spelling": "TypeAlias",
93+
// TYPEALIAS-NEXT: "preciseIdentifier": "s:35SubheadingDeclarationFragmentsTypes9TypeAliasa"
94+
// TYPEALIAS-NEXT: }
95+
public typealias TypeAlias<T> = Struct<T> where T: Collection
96+

0 commit comments

Comments
 (0)