Skip to content

Commit 6e69a44

Browse files
committed
[ASTPrinter] Intorduce 'IntroducerKeyword' name kind
For more fine grained annoations. For now, it's handled as the same as 'Keyword' name kind. Fix an issue where 'extension' wasn't marked as "keyword". Also, move 'static' priting out of 'SkipIntroducerKeywords' guard because 'static' is not an declaration introducer.
1 parent 43776ce commit 6e69a44

12 files changed

+131
-91
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ enum class PrintNameContext {
4848
Normal,
4949
/// Keyword context, where no keywords are escaped.
5050
Keyword,
51+
/// Keyword for introducing a declarations e.g. 'func', 'struct'.
52+
IntroducerKeyword,
5153
/// Type member context, e.g. properties or enum cases.
5254
TypeMember,
5355
/// Generic parameter context, where 'Self' is not escaped.
@@ -217,6 +219,17 @@ class ASTPrinter {
217219
*this << Suffix;
218220
}
219221

222+
void printIntroducerKeyword(StringRef name,
223+
const PrintOptions &Opts,
224+
StringRef Suffix = "") {
225+
if (Opts.SkipIntroducerKeywords)
226+
return;
227+
callPrintNamePre(PrintNameContext::IntroducerKeyword);
228+
*this << name;
229+
printNamePost(PrintNameContext::IntroducerKeyword);
230+
*this << Suffix;
231+
}
232+
220233
void printAttrName(StringRef name, bool needAt = false) {
221234
callPrintNamePre(PrintNameContext::Attribute);
222235
if (needAt)

include/swift/AST/PrintOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@ struct PrintOptions {
346346
/// Whether to print 'static' or 'class' on static decls.
347347
bool PrintStaticKeyword = true;
348348

349+
/// Whether to print 'mutating', 'nonmutating', or '__consuming' keyword on
350+
/// specified decls.
351+
bool PrintSelfAccessKindKeyword = true;
352+
349353
/// Whether to print 'override' keyword on overridden decls.
350354
bool PrintOverrideKeyword = true;
351355

lib/AST/ASTPrinter.cpp

Lines changed: 56 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ static bool escapeKeywordInContext(StringRef keyword, PrintNameContext context){
476476
case PrintNameContext::Attribute:
477477
return isKeyword;
478478
case PrintNameContext::Keyword:
479+
case PrintNameContext::IntroducerKeyword:
479480
return false;
480481

481482
case PrintNameContext::ClassDynamicSelf:
@@ -877,7 +878,7 @@ class PrintAST : public ASTVisitor<PrintAST> {
877878
bool shouldPrintPattern(const Pattern *P);
878879
void printPatternType(const Pattern *P);
879880
void printAccessors(const AbstractStorageDecl *ASD);
880-
void printMutabilityModifiersIfNeeded(const FuncDecl *FD);
881+
void printSelfAccessKindModifiersIfNeeded(const FuncDecl *FD);
881882
void printMembersOfDecl(Decl * NTD, bool needComma = false,
882883
bool openBracket = true, bool closeBracket = true);
883884
void printMembers(ArrayRef<Decl *> members, bool needComma = false,
@@ -1143,6 +1144,7 @@ void PrintAST::printAttributes(const Decl *D) {
11431144
if (isa<FuncDecl>(D)) {
11441145
Options.ExcludeAttrList.push_back(DAK_Mutating);
11451146
Options.ExcludeAttrList.push_back(DAK_NonMutating);
1147+
Options.ExcludeAttrList.push_back(DAK_Consuming);
11461148
}
11471149

11481150
D->getAttrs().print(Printer, Options, D);
@@ -1291,10 +1293,9 @@ void PrintAST::printPattern(const Pattern *pattern) {
12911293
break;
12921294

12931295
case PatternKind::Binding:
1294-
if (!Options.SkipIntroducerKeywords)
1295-
Printer << (cast<BindingPattern>(pattern)->isLet() ? tok::kw_let
1296-
: tok::kw_var)
1297-
<< " ";
1296+
Printer.printIntroducerKeyword(
1297+
cast<BindingPattern>(pattern)->isLet() ? "let" : "var",
1298+
Options, " ");
12981299
printPattern(cast<BindingPattern>(pattern)->getSubPattern());
12991300
}
13001301
}
@@ -1901,16 +1902,27 @@ void PrintAST::printBodyIfNecessary(const AbstractFunctionDecl *decl) {
19011902
printBraceStmt(decl->getBody(), /*newlineIfEmpty*/!isa<AccessorDecl>(decl));
19021903
}
19031904

1904-
void PrintAST::printMutabilityModifiersIfNeeded(const FuncDecl *FD) {
1905+
void PrintAST::printSelfAccessKindModifiersIfNeeded(const FuncDecl *FD) {
1906+
if (!Options.PrintSelfAccessKindKeyword)
1907+
return;
1908+
19051909
const auto *AD = dyn_cast<AccessorDecl>(FD);
19061910

1907-
if (FD->isMutating()) {
1908-
if (AD == nullptr || AD->isAssumedNonMutating())
1909-
if (!Options.excludeAttrKind(DAK_Mutating))
1910-
Printer.printKeyword("mutating", Options, " ");
1911-
} else if (AD && AD->isExplicitNonMutating() &&
1912-
!Options.excludeAttrKind(DAK_Mutating)) {
1913-
Printer.printKeyword("nonmutating", Options, " ");
1911+
switch (FD->getSelfAccessKind()) {
1912+
case SelfAccessKind::Mutating:
1913+
if ((!AD || AD->isAssumedNonMutating()) &&
1914+
!Options.excludeAttrKind(DAK_Mutating))
1915+
Printer.printKeyword("mutating", Options, " ");
1916+
break;
1917+
case SelfAccessKind::NonMutating:
1918+
if (AD && AD->isExplicitNonMutating() &&
1919+
!Options.excludeAttrKind(DAK_NonMutating))
1920+
Printer.printKeyword("nonmutating", Options, " ");
1921+
break;
1922+
case SelfAccessKind::Consuming:
1923+
if (!Options.excludeAttrKind(DAK_Consuming))
1924+
Printer.printKeyword("__consuming", Options, " ");
1925+
break;
19141926
}
19151927
}
19161928

@@ -2037,7 +2049,7 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
20372049
return true;
20382050
if (!PrintAccessorBody) {
20392051
Printer << " ";
2040-
printMutabilityModifiersIfNeeded(Accessor);
2052+
printSelfAccessKindModifiersIfNeeded(Accessor);
20412053

20422054
Printer.printKeyword(getAccessorLabel(Accessor->getAccessorKind()), Options);
20432055

@@ -2271,7 +2283,7 @@ static void getModuleEntities(ImportDecl *Import,
22712283

22722284
void PrintAST::visitImportDecl(ImportDecl *decl) {
22732285
printAttributes(decl);
2274-
Printer << tok::kw_import << " ";
2286+
Printer.printIntroducerKeyword("import", Options, " ");
22752287

22762288
switch (decl->getImportKind()) {
22772289
case ImportKind::Module:
@@ -2391,7 +2403,7 @@ void PrintAST::printSynthesizedExtension(Type ExtendedType,
23912403
if (Options.BracketOptions.shouldOpenExtension(ExtDecl)) {
23922404
printDocumentationComment(ExtDecl);
23932405
printAttributes(ExtDecl);
2394-
Printer << tok::kw_extension << " ";
2406+
Printer.printIntroducerKeyword("extension", Options, " ");
23952407

23962408
printExtendedTypeName(TypeLoc::withoutLoc(ExtendedType));
23972409
printInherited(ExtDecl);
@@ -2429,7 +2441,7 @@ void PrintAST::printExtension(ExtensionDecl *decl) {
24292441
if (Options.BracketOptions.shouldOpenExtension(decl)) {
24302442
printDocumentationComment(decl);
24312443
printAttributes(decl);
2432-
Printer << "extension ";
2444+
Printer.printIntroducerKeyword("extension", Options, " ");
24332445
recordDeclLoc(decl, [&]{
24342446
// We cannot extend sugared types.
24352447
Type extendedType = decl->getExtendedType();
@@ -2961,8 +2973,7 @@ void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
29612973
printDocumentationComment(decl);
29622974
printAttributes(decl);
29632975
printAccess(decl);
2964-
if (!Options.SkipIntroducerKeywords)
2965-
Printer << tok::kw_typealias << " ";
2976+
Printer.printIntroducerKeyword("typealias", Options, " ");
29662977
printContextIfNeeded(decl);
29672978
recordDeclLoc(decl,
29682979
[&]{
@@ -3005,8 +3016,7 @@ void PrintAST::visitGenericTypeParamDecl(GenericTypeParamDecl *decl) {
30053016
void PrintAST::visitAssociatedTypeDecl(AssociatedTypeDecl *decl) {
30063017
printDocumentationComment(decl);
30073018
printAttributes(decl);
3008-
if (!Options.SkipIntroducerKeywords)
3009-
Printer << tok::kw_associatedtype << " ";
3019+
Printer.printIntroducerKeyword("associatedtype", Options, " ");
30103020
recordDeclLoc(decl,
30113021
[&]{
30123022
Printer.printName(decl->getName(), PrintNameContext::TypeMember);
@@ -3035,8 +3045,7 @@ void PrintAST::visitEnumDecl(EnumDecl *decl) {
30353045
printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
30363046
decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
30373047
} else {
3038-
if (!Options.SkipIntroducerKeywords)
3039-
Printer << tok::kw_enum << " ";
3048+
Printer.printIntroducerKeyword("enum", Options, " ");
30403049
printContextIfNeeded(decl);
30413050
recordDeclLoc(decl,
30423051
[&]{
@@ -3063,8 +3072,7 @@ void PrintAST::visitStructDecl(StructDecl *decl) {
30633072
printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
30643073
decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
30653074
} else {
3066-
if (!Options.SkipIntroducerKeywords)
3067-
Printer << tok::kw_struct << " ";
3075+
Printer.printIntroducerKeyword("struct", Options, " ");
30683076
printContextIfNeeded(decl);
30693077
recordDeclLoc(decl,
30703078
[&]{
@@ -3091,13 +3099,8 @@ void PrintAST::visitClassDecl(ClassDecl *decl) {
30913099
printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
30923100
decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
30933101
} else {
3094-
if (!Options.SkipIntroducerKeywords) {
3095-
if (decl->isExplicitActor()) {
3096-
Printer.printKeyword("actor", Options, " ");
3097-
} else {
3098-
Printer << tok::kw_class << " ";
3099-
}
3100-
}
3102+
Printer.printIntroducerKeyword(
3103+
decl->isExplicitActor() ? "actor" : "class", Options, " ");
31013104
printContextIfNeeded(decl);
31023105
recordDeclLoc(decl,
31033106
[&]{
@@ -3126,8 +3129,7 @@ void PrintAST::visitProtocolDecl(ProtocolDecl *decl) {
31263129
printSourceRange(CharSourceRange(Ctx.SourceMgr, decl->getStartLoc(),
31273130
decl->getBraces().Start.getAdvancedLoc(-1)), Ctx);
31283131
} else {
3129-
if (!Options.SkipIntroducerKeywords)
3130-
Printer << tok::kw_protocol << " ";
3132+
Printer.printIntroducerKeyword("protocol", Options, " ");
31313133
printContextIfNeeded(decl);
31323134
recordDeclLoc(decl,
31333135
[&]{
@@ -3207,20 +3209,12 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
32073209
Printer << "@_hasStorage ";
32083210
printAttributes(decl);
32093211
printAccess(decl);
3210-
if (!Options.SkipIntroducerKeywords) {
3211-
if (decl->isStatic() && Options.PrintStaticKeyword)
3212-
printStaticKeyword(decl->getCorrectStaticSpelling());
3213-
if (decl->getKind() == DeclKind::Var
3214-
|| Options.PrintParameterSpecifiers) {
3215-
// Map all non-let specifiers to 'var'. This is not correct, but
3216-
// SourceKit relies on this for info about parameter decls.
3217-
if (decl->isLet())
3218-
Printer << tok::kw_let;
3219-
else
3220-
Printer << tok::kw_var;
3221-
3222-
Printer << " ";
3223-
}
3212+
if (decl->isStatic() && Options.PrintStaticKeyword)
3213+
printStaticKeyword(decl->getCorrectStaticSpelling());
3214+
if (decl->getKind() == DeclKind::Var || Options.PrintParameterSpecifiers) {
3215+
// Map all non-let specifiers to 'var'. This is not correct, but
3216+
// SourceKit relies on this for info about parameter decls.
3217+
Printer.printIntroducerKeyword(decl->isLet() ? "let" : "var", Options, " ");
32243218
}
32253219
printContextIfNeeded(decl);
32263220
recordDeclLoc(decl,
@@ -3431,10 +3425,8 @@ void PrintAST::visitAccessorDecl(AccessorDecl *decl) {
34313425
printDocumentationComment(decl);
34323426
printAttributes(decl);
34333427
// Explicitly print 'mutating' and 'nonmutating' if needed.
3434-
printMutabilityModifiersIfNeeded(decl);
3435-
if (decl->isConsuming()) {
3436-
Printer.printKeyword("__consuming", Options, " ");
3437-
}
3428+
printSelfAccessKindModifiersIfNeeded(decl);
3429+
34383430
switch (auto kind = decl->getAccessorKind()) {
34393431
case AccessorKind::Get:
34403432
case AccessorKind::Address:
@@ -3492,16 +3484,12 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
34923484
SourceRange(StartLoc, EndLoc));
34933485
printSourceRange(Range, Ctx);
34943486
} else {
3495-
if (!Options.SkipIntroducerKeywords) {
3496-
if (decl->isStatic() && Options.PrintStaticKeyword)
3497-
printStaticKeyword(decl->getCorrectStaticSpelling());
3487+
if (decl->isStatic() && Options.PrintStaticKeyword)
3488+
printStaticKeyword(decl->getCorrectStaticSpelling());
3489+
3490+
printSelfAccessKindModifiersIfNeeded(decl);
3491+
Printer.printIntroducerKeyword("func", Options, " ");
34983492

3499-
printMutabilityModifiersIfNeeded(decl);
3500-
if (decl->isConsuming() && !decl->getAttrs().hasAttribute<ConsumingAttr>()) {
3501-
Printer.printKeyword("__consuming", Options, " ");
3502-
}
3503-
Printer << tok::kw_func << " ";
3504-
}
35053493
printContextIfNeeded(decl);
35063494
recordDeclLoc(decl,
35073495
[&]{ // Name
@@ -3659,7 +3647,7 @@ void PrintAST::visitEnumCaseDecl(EnumCaseDecl *decl) {
36593647
printDocumentationComment(elems[0]);
36603648
printAttributes(elems[0]);
36613649
}
3662-
Printer << tok::kw_case << " ";
3650+
Printer.printIntroducerKeyword("case", Options, " ");
36633651

36643652
llvm::interleave(elems.begin(), elems.end(),
36653653
[&](EnumElementDecl *elt) {
@@ -3673,16 +3661,15 @@ void PrintAST::visitEnumElementDecl(EnumElementDecl *decl) {
36733661
// In cases where there is no parent EnumCaseDecl (such as imported or
36743662
// deserialized elements), print the element independently.
36753663
printAttributes(decl);
3676-
Printer << tok::kw_case << " ";
3664+
Printer.printIntroducerKeyword("case", Options, " ");
36773665
printEnumElement(decl);
36783666
}
36793667

36803668
void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) {
36813669
printDocumentationComment(decl);
36823670
printAttributes(decl);
36833671
printAccess(decl);
3684-
if (!Options.SkipIntroducerKeywords && decl->isStatic() &&
3685-
Options.PrintStaticKeyword)
3672+
if (decl->isStatic() && Options.PrintStaticKeyword)
36863673
printStaticKeyword(decl->getCorrectStaticSpelling());
36873674
printContextIfNeeded(decl);
36883675
recordDeclLoc(decl, [&]{
@@ -3782,7 +3769,7 @@ void PrintAST::visitDestructorDecl(DestructorDecl *decl) {
37823769

37833770
void PrintAST::visitInfixOperatorDecl(InfixOperatorDecl *decl) {
37843771
Printer.printKeyword("infix", Options, " ");
3785-
Printer << tok::kw_operator << " ";
3772+
Printer.printIntroducerKeyword("operator", Options, " ");
37863773
recordDeclLoc(decl,
37873774
[&]{
37883775
Printer.printName(decl->getName());
@@ -3801,7 +3788,7 @@ void PrintAST::visitInfixOperatorDecl(InfixOperatorDecl *decl) {
38013788
}
38023789

38033790
void PrintAST::visitPrecedenceGroupDecl(PrecedenceGroupDecl *decl) {
3804-
Printer << tok::kw_precedencegroup << " ";
3791+
Printer.printIntroducerKeyword("precedencegroup", Options, " ");
38053792
recordDeclLoc(decl,
38063793
[&]{
38073794
Printer.printName(decl->getName());
@@ -3861,7 +3848,7 @@ void PrintAST::visitPrecedenceGroupDecl(PrecedenceGroupDecl *decl) {
38613848

38623849
void PrintAST::visitPrefixOperatorDecl(PrefixOperatorDecl *decl) {
38633850
Printer.printKeyword("prefix", Options, " ");
3864-
Printer << tok::kw_operator << " ";
3851+
Printer.printIntroducerKeyword("operator", Options, " ");
38653852
recordDeclLoc(decl,
38663853
[&]{
38673854
Printer.printName(decl->getName());
@@ -3879,7 +3866,7 @@ void PrintAST::visitPrefixOperatorDecl(PrefixOperatorDecl *decl) {
38793866

38803867
void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) {
38813868
Printer.printKeyword("postfix", Options, " ");
3882-
Printer << tok::kw_operator << " ";
3869+
Printer.printIntroducerKeyword("operator", Options, " ");
38833870
recordDeclLoc(decl,
38843871
[&]{
38853872
Printer.printName(decl->getName());

lib/SymbolGraphGen/DeclarationFragmentPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ void
9696
DeclarationFragmentPrinter::printNamePre(PrintNameContext Context) {
9797
switch (Context) {
9898
case PrintNameContext::Keyword:
99+
case PrintNameContext::IntroducerKeyword:
99100
openFragment(FragmentKind::Keyword);
100101
break;
101102
case PrintNameContext::GenericParameter:
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
struct S {
2+
mutating func foo(x: Int) {}
3+
__consuming func foo(x: String) {}
4+
}
5+
6+
// RUN: %sourcekitd-test -req=cursor -pos=2:19 %s -- %s -module-name MyMod | %FileCheck -check-prefix=CHECK1 %s
7+
8+
// CHECK1: source.lang.swift.decl.function.method.instance (2:19-2:30)
9+
// CHECK1: foo(x:)
10+
// CHECK1: s:5MyMod1SV3foo1xySi_tF
11+
// CHECK1: source.lang.swift
12+
// CHECK1: (inout S) -> (Int) -> ()
13+
// CHECK1: $s1xySi_tcD
14+
// CHECK1: <Declaration>mutating func foo(x: <Type usr="s:Si">Int</Type>)</Declaration>
15+
// CHECK1: <decl.function.method.instance><syntaxtype.keyword>mutating</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>foo</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>x</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr="s:Si">Int</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.method.instance>
16+
// CHECK1: RELATED BEGIN
17+
// CHECK1: <RelatedName usr="s:5MyMod1SV3foo1xySS_tF">foo(x: String)</RelatedName>
18+
// CHECK1: RELATED END
19+
20+
// RUN: %sourcekitd-test -req=cursor -pos=3:22 %s -- %s -module-name MyMod | %FileCheck -check-prefix=CHECK2 %s
21+
22+
// CHECK2: source.lang.swift.decl.function.method.instance (3:22-3:36)
23+
// CHECK2: foo(x:)
24+
// CHECK2: s:5MyMod1SV3foo1xySS_tF
25+
// CHECK2: source.lang.swift
26+
// CHECK2: (__owned S) -> (String) -> ()
27+
// CHECK2: $s1xySS_tcD
28+
// CHECK2: <Declaration>func foo(x: <Type usr="s:SS">String</Type>)</Declaration>
29+
// CHECK2: <decl.function.method.instance><syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>foo</decl.name>(<decl.var.parameter><decl.var.parameter.argument_label>x</decl.var.parameter.argument_label>: <decl.var.parameter.type><ref.struct usr="s:SS">String</ref.struct></decl.var.parameter.type></decl.var.parameter>)</decl.function.method.instance>
30+
// CHECK2: RELATED BEGIN
31+
// CHECK2: <RelatedName usr="s:5MyMod1SV3foo1xySi_tF">foo(x: Int)</RelatedName>
32+
// CHECK2: RELATED END

0 commit comments

Comments
 (0)