Skip to content

Commit d4ff279

Browse files
committed
[IDE] Range info for accessor decl.
Attributes on explicit accessor decl may have attributes. Only when the range contains those attributes, the range-info should report `SingleDecl`.
1 parent 7df16ca commit d4ff279

File tree

2 files changed

+86
-4
lines changed

2 files changed

+86
-4
lines changed

lib/AST/Decl.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,32 @@ case DeclKind::ID: return cast<ID##Decl>(this)->getSourceRange();
370370
SourceRange Decl::getSourceRangeIncludingAttrs() const {
371371
auto Range = getSourceRange();
372372

373-
// Attributes on AccessorDecl are syntactically belong to PatternBindingDecl.
374-
if (isa<AccessorDecl>(this) || isa<VarDecl>(this))
373+
// Attributes on AccessorDecl may syntactically belong to PatternBindingDecl.
374+
// e.g. 'override'.
375+
if (auto *AD = dyn_cast<AccessorDecl>(this)) {
376+
// If this is implicit getter, accessor range should not include attributes.
377+
if (!AD->getAccessorKeywordLoc().isValid())
378+
return Range;
379+
380+
// Otherwise, include attributes directly attached to the accessor.
381+
SourceLoc VarLoc = AD->getStorage()->getStartLoc();
382+
for (auto Attr : getAttrs()) {
383+
if (!Attr->getRange().isValid())
384+
continue;
385+
386+
SourceLoc AttrStartLoc = Attr->getRangeWithAt().Start;
387+
if (getASTContext().SourceMgr.isBeforeInBuffer(VarLoc, AttrStartLoc))
388+
Range.widen(AttrStartLoc);
389+
}
390+
return Range;
391+
}
392+
393+
// Attributes on VarDecl syntactically belong to PatternBindingDecl.
394+
if (isa<VarDecl>(this))
375395
return Range;
376396

377397
// Attributes on PatternBindingDecls are attached to VarDecls in AST.
378-
if (const PatternBindingDecl *PBD = dyn_cast<PatternBindingDecl>(this)) {
398+
if (auto *PBD = dyn_cast<PatternBindingDecl>(this)) {
379399
for (auto Entry : PBD->getPatternList())
380400
Entry.getPattern()->forEachVariable([&](VarDecl *VD) {
381401
for (auto Attr : VD->getAttrs())

test/IDE/range_info_declattr.swift

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,32 @@ class ObjCBase {
77
}
88
@objc var bar = 12, baz = 13
99
}
10+
class Derived : ObjCBase {
11+
@available(*, unavailable)
12+
override var quux: Int {
13+
@inlinable get { return 0 }
14+
}
15+
16+
subscript(idx: Int) -> Int {
17+
@available(*, unavailable)
18+
get { return 0 }
19+
20+
@available(*, unavailable)
21+
@inlineable
22+
set { }
23+
}
24+
}
1025

1126
// RUN: %target-swift-ide-test -range -pos=4:1 -end-pos=9:2 -source-filename %s | %FileCheck %s -check-prefix=CHECK1
1227
// RUN: %target-swift-ide-test -range -pos=5:3 -end-pos=7:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK2
1328
// RUN: %target-swift-ide-test -range -pos=5:25 -end-pos=7:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK3
1429
// RUN: %target-swift-ide-test -range -pos=8:3 -end-pos=8:31 -source-filename %s | %FileCheck %s -check-prefix=CHECK4
30+
// RUN: %target-swift-ide-test -range -pos=13:5 -end-pos=13:32 -source-filename %s | %FileCheck %s -check-prefix=CHECK5
31+
// RUN: %target-swift-ide-test -range -pos=13:16 -end-pos=13:32 -source-filename %s | %FileCheck %s -check-prefix=CHECK6
32+
// RUN: %target-swift-ide-test -range -pos=12:26 -end-pos=14:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK7
33+
// RUN: %target-swift-ide-test -range -pos=17:5 -end-pos=18:21 -source-filename %s | %FileCheck %s -check-prefix=CHECK8
34+
// RUN: %target-swift-ide-test -range -pos=20:5 -end-pos=22:12 -source-filename %s | %FileCheck %s -check-prefix=CHECK9
35+
// RUN: %target-swift-ide-test -range -pos=21:5 -end-pos=22:12 -source-filename %s | %FileCheck %s -check-prefix=CHECK10
1536

1637
// CHECK1: <Kind>SingleDecl</Kind>
1738
// CHECK1-NEXT: <Content>@objc class ObjCClass : ObjCBase {
@@ -47,11 +68,52 @@ class ObjCBase {
4768
// CHECK3-NEXT: <ASTNodes>1</ASTNodes>
4869
// CHECK3-NEXT: <end>
4970

50-
5171
// CHECK4: <Kind>SingleDecl</Kind>
5272
// CHECK4-NEXT: <Content>@objc var bar = 12, baz = 13</Content>
5373
// CHECK4-NEXT: <Context>swift_ide_test.(file).ObjCClass</Context>
5474
// CHECK4-NEXT: <Declared>bar</Declared><OutscopeReference>false</OutscopeReference>
5575
// CHECK4-NEXT: <Declared>baz</Declared><OutscopeReference>false</OutscopeReference>
5676
// CHECK4-NEXT: <ASTNodes>1</ASTNodes>
5777
// CHECK4-NEXT: <end>
78+
79+
// CHECK5: <Kind>SingleDecl</Kind>
80+
// CHECK5-NEXT: <Content>@inlinable get { return 0 }</Content>
81+
// CHECK5-NEXT: <Context>swift_ide_test.(file).Derived</Context>
82+
// CHECK5-NEXT: <Declared>_</Declared><OutscopeReference>false</OutscopeReference>
83+
// CHECK5-NEXT: <ASTNodes>1</ASTNodes>
84+
// CHECK5-NEXT: <end>
85+
86+
// CHECK6: <Kind>Invalid</Kind>
87+
// CHECK6-NEXT: <Content>get { return 0 }</Content>
88+
// CHECK6-NEXT: <ASTNodes>0</ASTNodes>
89+
// CHECK6-NEXT: <end>
90+
91+
// CHECK7: <Kind>Invalid</Kind>
92+
// CHECK7-NEXT: <Content>{
93+
// CHECK7-NEXT: @inlinable get { return 0 }
94+
// CHECK7-NEXT: }</Content>
95+
// CHECK7-NEXT: <ASTNodes>0</ASTNodes>
96+
// CHECK7-NEXT: <end>
97+
98+
// CHECK8: <Kind>SingleDecl</Kind>
99+
// CHECK8-NEXT: <Content>@available(*, unavailable)
100+
// CHECK8-NEXT: get { return 0 }</Content>
101+
// CHECK8-NEXT: <Context>swift_ide_test.(file).Derived</Context>
102+
// CHECK8-NEXT: <Declared>_</Declared><OutscopeReference>false</OutscopeReference>
103+
// CHECK8-NEXT: <ASTNodes>1</ASTNodes>
104+
// CHECK8-NEXT: <end>
105+
106+
// CHECK9: <Kind>SingleDecl</Kind>
107+
// CHECK9-NEXT: <Content>@available(*, unavailable)
108+
// CHECK9-NEXT: @inlineable
109+
// CHECK9-NEXT: set { }</Content>
110+
// CHECK9-NEXT: <Context>swift_ide_test.(file).Derived</Context>
111+
// CHECK9-NEXT: <Declared>_</Declared><OutscopeReference>false</OutscopeReference>
112+
// CHECK9-NEXT: <ASTNodes>1</ASTNodes>
113+
// CHECK9-NEXT: <end>
114+
115+
// CHECK10: <Kind>Invalid</Kind>
116+
// CHECK10-NEXT: <Content>@inlineable
117+
// CHECK10-NEXT: set { }</Content>
118+
// CHECK10-NEXT: <ASTNodes>0</ASTNodes>
119+
// CHECK10-NEXT: <end>

0 commit comments

Comments
 (0)