Skip to content

Commit d747ee9

Browse files
authored
Merge pull request #38521 from rintaro/astprinter-introducerkeyword
[ASTPrinter] Intorduce 'IntroducerKeyword' name kind
2 parents 043bc46 + 6e69a44 commit d747ee9

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)