Skip to content

Commit ba702b8

Browse files
committed
[SourceKit] Add tags for attribute names
As a first foray into annotating attribute, add tags around attribute names. For now, treat any decl-modifiers as keywords. We will also want to wrap the whole attribute (including any parameters) into tags as well, but that will require more work in the callback hanlding. Also factor the attribute printing to handle any special cases early, which will simplify wrapping attributes in tags, since we can then just put the whole switch intside the pre/post callbacks. rdar://problem/24292226
1 parent f61a241 commit ba702b8

File tree

8 files changed

+115
-49
lines changed

8 files changed

+115
-49
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ enum class PrintNameContext {
4343
/// not escaped.
4444
FunctionParameterExternal,
4545
FunctionParameterLocal,
46+
/// Attributes, which are escaped as 'Normal', but differentiated for
47+
/// the purposes of printName* callbacks.
48+
Attribute,
4649
};
4750

4851
/// Describes the kind of structured entity being printed.
@@ -160,6 +163,14 @@ class ASTPrinter {
160163
printNamePost(PrintNameContext::Keyword);
161164
}
162165

166+
void printAttrName(StringRef Name, bool needAt = false) {
167+
callPrintNamePre(PrintNameContext::Attribute);
168+
if (needAt)
169+
*this << "@";
170+
*this << Name;
171+
printNamePost(PrintNameContext::Attribute);
172+
}
173+
163174
void printName(Identifier Name,
164175
PrintNameContext Context = PrintNameContext::Normal);
165176

include/swift/AST/Attr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ class DeclAttribute : public AttributeBase {
361361
return getOptions(getKind());
362362
}
363363

364+
/// Prints this attribute (if applicable), returning `true` if anything was
365+
/// printed.
366+
bool printImpl(ASTPrinter &Printer, const PrintOptions &Options) const;
367+
364368
public:
365369
DeclAttrKind getKind() const {
366370
return static_cast<DeclAttrKind>(DeclAttrBits.Kind);

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,7 @@ ASTPrinter &operator<<(ASTPrinter &printer, tok keyword) {
574574
static bool escapeKeywordInContext(StringRef keyword, PrintNameContext context){
575575
switch (context) {
576576
case PrintNameContext::Normal:
577+
case PrintNameContext::Attribute:
577578
return true;
578579
case PrintNameContext::Keyword:
579580
return false;

lib/AST/Attr.cpp

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,27 @@ SourceLoc DeclAttributes::getStartLoc(bool forModifiers) const {
266266
return lastAttr ? lastAttr->getRangeWithAt().Start : SourceLoc();
267267
}
268268

269-
void DeclAttribute::print(ASTPrinter &Printer,
270-
const PrintOptions &Options) const {
269+
bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options) const {
270+
271+
// Handle any attributes that are not printed at all before we make printer
272+
// callbacks.
273+
switch (getKind()) {
274+
case DAK_ObjC:
275+
if (Options.PrintForSIL && isImplicit())
276+
return false;
277+
break;
278+
case DAK_RawDocComment:
279+
case DAK_ObjCBridged:
280+
case DAK_SynthesizedProtocol:
281+
return false;
282+
default:
283+
break;
284+
}
285+
286+
// Handle any decl-modifiers.
287+
// FIXME: Ideally we would handle decl modifiers as a special kind of
288+
// attribute, but for now it's simpler to treat them as a keyword in the
289+
// printer.
271290
switch (getKind()) {
272291
// Handle all of the SIMPLE_DECL_ATTRs.
273292
#define SIMPLE_DECL_ATTR(X, CLASS, ...) case DAK_##CLASS:
@@ -276,25 +295,41 @@ void DeclAttribute::print(ASTPrinter &Printer,
276295
case DAK_Accessibility:
277296
case DAK_Ownership:
278297
case DAK_Effects:
279-
if (!DeclAttribute::isDeclModifier(getKind()))
280-
Printer << "@";
281-
Printer << getAttrName();
298+
if (DeclAttribute::isDeclModifier(getKind())) {
299+
Printer.printKeyword(getAttrName());
300+
} else {
301+
Printer.printAttrName(getAttrName(), /*needAt=*/true);
302+
}
303+
return true;
304+
305+
case DAK_SetterAccessibility:
306+
Printer.printKeyword(getAttrName());
307+
Printer << "(set)";
308+
return true;
309+
310+
default:
282311
break;
312+
}
283313

314+
switch (getKind()) {
284315
case DAK_Semantics:
285-
Printer << "@_semantics(\"" << cast<SemanticsAttr>(this)->Value << "\")";
316+
Printer.printAttrName("@_semantics");
317+
Printer << "(\"" << cast<SemanticsAttr>(this)->Value << "\")";
286318
break;
287319

288320
case DAK_Alignment:
289-
Printer << "@_alignment(" << cast<AlignmentAttr>(this)->Value << ")";
321+
Printer.printAttrName("@_alignment");
322+
Printer << "(" << cast<AlignmentAttr>(this)->Value << ")";
290323
break;
291324

292325
case DAK_SILGenName:
293-
Printer << "@_silgen_name(\"" << cast<SILGenNameAttr>(this)->Name << "\")";
326+
Printer.printAttrName("@_silgen_name");
327+
Printer << "(\"" << cast<SILGenNameAttr>(this)->Name << "\")";
294328
break;
295329

296330
case DAK_Available: {
297-
Printer << "@available(";
331+
Printer.printAttrName("@available");
332+
Printer << "(";
298333
auto Attr = cast<AvailableAttr>(this);
299334
Printer << Attr->platformString();
300335

@@ -326,44 +361,31 @@ void DeclAttribute::print(ASTPrinter &Printer,
326361
break;
327362
}
328363
case DAK_AutoClosure:
329-
Printer << "@autoclosure";
364+
Printer.printAttrName("@autoclosure");
330365
if (cast<AutoClosureAttr>(this)->isEscaping())
331366
Printer << "(escaping)";
332367
break;
333368
case DAK_ObjC: {
334-
if (Options.PrintForSIL && isImplicit())
335-
break;
336-
Printer << "@objc";
369+
Printer.printAttrName("@objc");
337370
llvm::SmallString<32> scratch;
338371
if (auto Name = cast<ObjCAttr>(this)->getName()) {
339372
if (!cast<ObjCAttr>(this)->isNameImplicit())
340373
Printer << "(" << Name->getString(scratch) << ")";
341374
}
342375
break;
343376
}
344-
345-
case DAK_SetterAccessibility:
346-
Printer << getAttrName() << "(set)";
347-
break;
348377

349378
case DAK_SwiftNativeObjCRuntimeBase: {
350379
auto *attr = cast<SwiftNativeObjCRuntimeBaseAttr>(this);
351-
Printer << "@_swift_native_objc_runtime_base("
352-
<< attr->BaseClassName.str() << ")";
380+
Printer.printAttrName("@_swift_native_objc_runtime_base");
381+
Printer << "(" << attr->BaseClassName.str() << ")";
353382
break;
354383
}
355384

356-
case DAK_RawDocComment:
357-
// Not printed.
358-
return;
359-
360-
case DAK_ObjCBridged:
361-
// Not printed.
362-
return;
363-
364385
case DAK_Swift3Migration: {
365386
auto attr = cast<Swift3MigrationAttr>(this);
366-
Printer << "@swift3_migration(";
387+
Printer.printAttrName("@swift3_migration");
388+
Printer << "(";
367389

368390
bool printedAny = false;
369391
auto printSeparator = [&] {
@@ -387,12 +409,8 @@ void DeclAttribute::print(ASTPrinter &Printer,
387409
break;
388410
}
389411

390-
case DAK_SynthesizedProtocol:
391-
// Not printed.
392-
return;
393-
394412
case DAK_WarnUnusedResult: {
395-
Printer << "@warn_unused_result";
413+
Printer.printAttrName("@warn_unused_result");
396414
auto *attr = cast<WarnUnusedResultAttr>(this);
397415
bool printedParens = false;
398416
if (!attr->getMessage().empty()) {
@@ -412,10 +430,22 @@ void DeclAttribute::print(ASTPrinter &Printer,
412430
break;
413431
}
414432

433+
default:
434+
llvm_unreachable("handled before this switch");
435+
415436
case DAK_Count:
416437
llvm_unreachable("exceed declaration attribute kinds");
417438
}
418439

440+
return true;
441+
}
442+
443+
void DeclAttribute::print(ASTPrinter &Printer,
444+
const PrintOptions &Options) const {
445+
446+
if (!printImpl(Printer, Options))
447+
return; // Nothing printed.
448+
419449
if (isLongAttribute() && Options.PrintLongAttrsOnSeparateLines)
420450
Printer.printNewline();
421451
else

test/SourceKit/DocSupport/doc_clang_module.swift.response

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,15 +3656,15 @@ var FooSubUnnamedEnumeratorA1: Int { get }
36563656
key.usr: "c:@F@fooFuncNoreturn1",
36573657
key.offset: 1606,
36583658
key.length: 33,
3659-
key.fully_annotated_decl: "<decl.function.free>@noreturn <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooFuncNoreturn1</decl.name>()</decl.function.free>"
3659+
key.fully_annotated_decl: "<decl.function.free><syntaxtype.attribute.name>@noreturn</syntaxtype.attribute.name> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooFuncNoreturn1</decl.name>()</decl.function.free>"
36603660
},
36613661
{
36623662
key.kind: source.lang.swift.decl.function.free,
36633663
key.name: "fooFuncNoreturn2()",
36643664
key.usr: "c:@F@fooFuncNoreturn2",
36653665
key.offset: 1640,
36663666
key.length: 33,
3667-
key.fully_annotated_decl: "<decl.function.free>@noreturn <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooFuncNoreturn2</decl.name>()</decl.function.free>"
3667+
key.fully_annotated_decl: "<decl.function.free><syntaxtype.attribute.name>@noreturn</syntaxtype.attribute.name> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>fooFuncNoreturn2</decl.name>()</decl.function.free>"
36683668
},
36693669
{
36703670
key.kind: source.lang.swift.decl.function.free,
@@ -4238,15 +4238,15 @@ var FooSubUnnamedEnumeratorA1: Int { get }
42384238
key.usr: "c:objc(cs)FooClassPropertyOwnership(py)assignable",
42394239
key.offset: 3540,
42404240
key.length: 42,
4241-
key.fully_annotated_decl: "<decl.var.instance>unowned(unsafe) <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>assignable</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
4241+
key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>unowned(unsafe)</syntaxtype.keyword> <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>assignable</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
42424242
},
42434243
{
42444244
key.kind: source.lang.swift.decl.var.instance,
42454245
key.name: "unsafeAssignable",
42464246
key.usr: "c:objc(cs)FooClassPropertyOwnership(py)unsafeAssignable",
42474247
key.offset: 3587,
42484248
key.length: 48,
4249-
key.fully_annotated_decl: "<decl.var.instance>unowned(unsafe) <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>unsafeAssignable</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
4249+
key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>unowned(unsafe)</syntaxtype.keyword> <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>unsafeAssignable</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
42504250
},
42514251
{
42524252
key.kind: source.lang.swift.decl.var.instance,
@@ -4270,15 +4270,15 @@ var FooSubUnnamedEnumeratorA1: Int { get }
42704270
key.usr: "c:objc(cs)FooClassPropertyOwnership(py)copyable",
42714271
key.offset: 3701,
42724272
key.length: 35,
4273-
key.fully_annotated_decl: "<decl.var.instance>@NSCopying <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>copyable</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
4273+
key.fully_annotated_decl: "<decl.var.instance><syntaxtype.attribute.name>@NSCopying</syntaxtype.attribute.name> <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>copyable</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
42744274
},
42754275
{
42764276
key.kind: source.lang.swift.decl.var.instance,
42774277
key.name: "weakRef",
42784278
key.usr: "c:objc(cs)FooClassPropertyOwnership(py)weakRef",
42794279
key.offset: 3741,
42804280
key.length: 28,
4281-
key.fully_annotated_decl: "<decl.var.instance>weak <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>weakRef</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
4281+
key.fully_annotated_decl: "<decl.var.instance><syntaxtype.keyword>weak</syntaxtype.keyword> <syntaxtype.keyword>var</syntaxtype.keyword> <decl.name>weakRef</decl.name>: <decl.var.type><ref.protocol usr=\"s:Ps9AnyObject\">AnyObject</ref.protocol>!</decl.var.type> { <syntaxtype.keyword>get</syntaxtype.keyword> <syntaxtype.keyword>set</syntaxtype.keyword> }</decl.var.instance>"
42824282
},
42834283
{
42844284
key.kind: source.lang.swift.decl.var.instance,

test/SourceKit/DocSupport/doc_source_file.swift.response

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,7 +2216,7 @@
22162216
key.usr: "s:FC8__main__5SubC28protMethFPS_4Prot_T_",
22172217
key.offset: 1068,
22182218
key.length: 24,
2219-
key.fully_annotated_decl: "<decl.function.method.instance>override <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>protMeth</decl.name>(<decl.var.parameter><decl.var.parameter.name>a</decl.var.parameter.name>: <decl.var.parameter.type><ref.protocol usr=\"s:P8__main__4Prot\">Prot</ref.protocol></decl.var.parameter.type></decl.var.parameter>)</decl.function.method.instance>",
2219+
key.fully_annotated_decl: "<decl.function.method.instance><syntaxtype.keyword>override</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>protMeth</decl.name>(<decl.var.parameter><decl.var.parameter.name>a</decl.var.parameter.name>: <decl.var.parameter.type><ref.protocol usr=\"s:P8__main__4Prot\">Prot</ref.protocol></decl.var.parameter.type></decl.var.parameter>)</decl.function.method.instance>",
22202220
key.inherits: [
22212221
{
22222222
key.kind: source.lang.swift.ref.function.method.instance,
@@ -2408,7 +2408,7 @@
24082408
key.usr: "s:FC8__main__3SB13fooFT_T_",
24092409
key.offset: 1553,
24102410
key.length: 56,
2411-
key.fully_annotated_decl: "<decl.function.method.instance>override <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>foo</decl.name>()</decl.function.method.instance>",
2411+
key.fully_annotated_decl: "<decl.function.method.instance><syntaxtype.keyword>override</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword> <decl.name>foo</decl.name>()</decl.function.method.instance>",
24122412
key.inherits: [
24132413
{
24142414
key.kind: source.lang.swift.ref.function.method.instance,

test/SourceKit/SourceDocInfo/cursor_info.swift

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ protocol P1 {
116116

117117
func genReq<U, V: P1 where V.T == U>(u: U, v: V) {}
118118

119+
@objc class C5 {
120+
@objc(mmm1)
121+
@noreturn
122+
func m1() {}
123+
124+
private(set)
125+
public
126+
var v1: Int = 1
127+
}
128+
119129
// RUN: rm -rf %t.tmp
120130
// RUN: mkdir %t.tmp
121131
// RUN: %swiftc_driver -emit-module -o %t.tmp/FooSwiftModule.swiftmodule %S/Inputs/FooSwiftModule.swift
@@ -278,13 +288,11 @@ func genReq<U, V: P1 where V.T == U>(u: U, v: V) {}
278288

279289
// RUN: %sourcekitd-test -req=cursor -pos=69:14 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck -check-prefix=CHECK27 %s
280290
// CHECK27: <Declaration>public subscript(i: <Type usr="s:Si">Int</Type>) -&gt; <Type usr="s:Si">Int</Type> { get }</Declaration>
281-
// CHECK27: <decl.function.subscript>public <syntaxtype.keyword>subscript</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.name>i</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr="s:Si">Int</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr="s:Si">Int</ref.struct></decl.function.returntype> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.function.subscript>
282-
// FIXME: keyword 'public'
291+
// CHECK27: <decl.function.subscript><syntaxtype.keyword>public</syntaxtype.keyword> <syntaxtype.keyword>subscript</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.name>i</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr="s:Si">Int</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr="s:Si">Int</ref.struct></decl.function.returntype> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.function.subscript>
283292

284293
// RUN: %sourcekitd-test -req=cursor -pos=69:19 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck -check-prefix=CHECK28 %s
285294
// CHECK28: <Declaration>public subscript(i: <Type usr="s:Si">Int</Type>) -&gt; <Type usr="s:Si">Int</Type> { get }</Declaration>
286-
// CHECK28: <decl.function.subscript>public <syntaxtype.keyword>subscript</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.name>i</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr="s:Si">Int</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr="s:Si">Int</ref.struct></decl.function.returntype> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.function.subscript>
287-
// FIXME: keyword 'public'
295+
// CHECK28: <decl.function.subscript><syntaxtype.keyword>public</syntaxtype.keyword> <syntaxtype.keyword>subscript</syntaxtype.keyword>(<decl.var.parameter><decl.var.parameter.name>i</decl.var.parameter.name>: <decl.var.parameter.type><ref.struct usr="s:Si">Int</ref.struct></decl.var.parameter.type></decl.var.parameter>) -&gt; <decl.function.returntype><ref.struct usr="s:Si">Int</ref.struct></decl.function.returntype> { <syntaxtype.keyword>get</syntaxtype.keyword> }</decl.function.subscript>
288296

289297
// RUN: %sourcekitd-test -req=cursor -pos=74:3 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK29
290298
// CHECK29: source.lang.swift.decl.function.destructor (74:3-74:9)
@@ -435,17 +443,15 @@ func genReq<U, V: P1 where V.T == U>(u: U, v: V) {}
435443

436444
// RUN: %sourcekitd-test -req=cursor -pos=108:19 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK49
437445
// CHECK49: source.lang.swift.decl.var.class (108:19-108:21)
438-
// CHECK49: <decl.var.class>final <syntaxtype.keyword>class</syntaxtype.keyword> <syntaxtype.keyword>var</syntaxtype.keyword>
439-
// FIXME: missing tags on 'final'
446+
// CHECK49: <decl.var.class><syntaxtype.keyword>final</syntaxtype.keyword> <syntaxtype.keyword>class</syntaxtype.keyword> <syntaxtype.keyword>var</syntaxtype.keyword>
440447

441448
// RUN: %sourcekitd-test -req=cursor -pos=109:15 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK50
442449
// CHECK50: source.lang.swift.decl.function.method.static (109:15-109:19)
443450
// CHECK50: <decl.function.method.static><syntaxtype.keyword>static</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword>
444451

445452
// RUN: %sourcekitd-test -req=cursor -pos=110:20 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK51
446453
// CHECK51: source.lang.swift.decl.function.method.class (110:20-110:24)
447-
// CHECK51: <decl.function.method.class>final <syntaxtype.keyword>class</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword>
448-
// FIXME: missing tags on 'final'
454+
// CHECK51: <decl.function.method.class><syntaxtype.keyword>final</syntaxtype.keyword> <syntaxtype.keyword>class</syntaxtype.keyword> <syntaxtype.keyword>func</syntaxtype.keyword>
449455

450456
// RUN: %sourcekitd-test -req=cursor -pos=117:6 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK52
451457
// CHECK52: source.lang.swift.decl.function.free (117:6-117:49)
@@ -455,3 +461,15 @@ func genReq<U, V: P1 where V.T == U>(u: U, v: V) {}
455461
// RUN: %sourcekitd-test -req=cursor -pos=117:16 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK53
456462
// CHECK53: source.lang.swift.decl.generic_type_param (117:16-117:17)
457463
// CHECK53: <decl.generic_type_param><decl.generic_type_param.name>V</decl.generic_type_param.name> : <decl.generic_type_param.constraint><ref.protocol usr="{{.*}}">P1</ref.protocol></decl.generic_type_param.constraint></decl.generic_type_param>
464+
465+
// RUN: %sourcekitd-test -req=cursor -pos=119:13 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK54
466+
// CHECK54: source.lang.swift.decl.class (119:13-119:15)
467+
// CHECK54: <decl.class><syntaxtype.attribute.name>@objc</syntaxtype.attribute.name> <syntaxtype.keyword>class
468+
469+
// RUN: %sourcekitd-test -req=cursor -pos=122:8 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK55
470+
// CHECK55: source.lang.swift.decl.function.method.instance (122:8-122:12)
471+
// CHECK55: <decl.function.method.instance><syntaxtype.attribute.name>@objc</syntaxtype.attribute.name>(mmm1) <syntaxtype.attribute.name>@noreturn</syntaxtype.attribute.name> <syntaxtype.keyword>func
472+
473+
// RUN: %sourcekitd-test -req=cursor -pos=126:7 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck %s -check-prefix=CHECK56
474+
// CHECK56: source.lang.swift.decl.var.instance (126:7-126:9)
475+
// CHECK56: <decl.var.instance><syntaxtype.keyword>private</syntaxtype.keyword>(set) <syntaxtype.keyword>public</syntaxtype.keyword> <syntaxtype.keyword>var

tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ class FullyAnnotatedDeclarationPrinter final : public XMLEscapingPrinter {
289289
return SyntaxKeywordTag;
290290
case PrintNameContext::GenericParameter:
291291
return GenericParamNameTag;
292+
case PrintNameContext::Attribute:
293+
return "syntaxtype.attribute.name";
292294
default:
293295
return "";
294296
}

0 commit comments

Comments
 (0)