Skip to content

Commit a27bf84

Browse files
committed
[IDE] Don't widen source range for AccessorDecl
Syntactically, Attributes for AccessorDecl are not part of AccessorDecl, but part of PatternBindingDecl. When the selected range is the brace for implicit getter, it should be considered as selecting getter decl regardless of the attributes. Conversely, we should widen source range for PatternBindingDecl by looking into declared VarDecls because, in AST, attributes on PatternBindingDecl are attached to VarDecls. rdar://problem/41073182
1 parent 50fb3b8 commit a27bf84

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

lib/AST/Decl.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,24 @@ case DeclKind::ID: return cast<ID##Decl>(this)->getSourceRange();
372372

373373
SourceRange Decl::getSourceRangeIncludingAttrs() const {
374374
auto Range = getSourceRange();
375+
376+
// Attributes on AccessorDecl are syntactically belong to PatternBindingDecl.
377+
if (isa<AccessorDecl>(this) || isa<VarDecl>(this))
378+
return Range;
379+
380+
// Attributes on PatternBindingDecls are attached to VarDecls in AST.
381+
if (const PatternBindingDecl *PBD = dyn_cast<PatternBindingDecl>(this)) {
382+
for (auto Entry : PBD->getPatternList())
383+
Entry.getPattern()->forEachVariable([&](VarDecl *VD) {
384+
for (auto Attr : VD->getAttrs())
385+
if (Attr->getRange().isValid())
386+
Range.widen(Attr->getRangeWithAt());
387+
});
388+
}
389+
375390
for (auto Attr : getAttrs()) {
376391
if (Attr->getRange().isValid())
377-
Range.widen(Attr->getRange());
392+
Range.widen(Attr->getRangeWithAt());
378393
}
379394
return Range;
380395
}

test/IDE/range_info_declattr.swift

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
class ObjCBase {
2+
var foo: Int { return 1 }
3+
}
4+
@objc class ObjCClass : ObjCBase {
5+
override var foo: Int {
6+
return 42
7+
}
8+
@objc var bar = 12, baz = 13
9+
}
10+
11+
// RUN: %target-swift-ide-test -range -pos=4:1 -end-pos=9:2 -source-filename %s | %FileCheck %s -check-prefix=CHECK1
12+
// RUN: %target-swift-ide-test -range -pos=5:3 -end-pos=7:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK2
13+
// RUN: %target-swift-ide-test -range -pos=5:25 -end-pos=7:4 -source-filename %s | %FileCheck %s -check-prefix=CHECK3
14+
// RUN: %target-swift-ide-test -range -pos=8:3 -end-pos=8:31 -source-filename %s | %FileCheck %s -check-prefix=CHECK4
15+
16+
// CHECK1: <Kind>SingleDecl</Kind>
17+
// CHECK1-NEXT: <Content>@objc class ObjCClass : ObjCBase {
18+
// CHECK1-NEXT: override var foo: Int {
19+
// CHECK1-NEXT: return 42
20+
// CHECK1-NEXT: }
21+
// CHECK1-NEXT: @objc var bar = 12, baz = 13
22+
// CHECK1-NEXT: }</Content>
23+
// CHECK1-NEXT: <Context>swift_ide_test.(file)</Context>
24+
// CHECK1-NEXT: <Declared>ObjCClass</Declared><OutscopeReference>false</OutscopeReference>
25+
// CHECK1-NEXT: <Declared>foo</Declared><OutscopeReference>false</OutscopeReference>
26+
// CHECK1-NEXT: <Declared>_</Declared><OutscopeReference>false</OutscopeReference>
27+
// CHECK1-NEXT: <Declared>bar</Declared><OutscopeReference>false</OutscopeReference>
28+
// CHECK1-NEXT: <Declared>baz</Declared><OutscopeReference>false</OutscopeReference>
29+
// CHECK1-NEXT: <ASTNodes>1</ASTNodes>
30+
// CHECK1-NEXT: <end>
31+
32+
// CHECK2: <Kind>SingleDecl</Kind>
33+
// CHECK2-NEXT: <Content>override var foo: Int {
34+
// CHECK2-NEXT: return 42
35+
// CHECK2-NEXT: }</Content>
36+
// CHECK2-NEXT: <Context>swift_ide_test.(file).ObjCClass</Context>
37+
// CHECK2-NEXT: <Declared>foo</Declared><OutscopeReference>false</OutscopeReference>
38+
// CHECK2-NEXT: <ASTNodes>1</ASTNodes>
39+
// CHECK2-NEXT: <end>
40+
41+
// CHECK3: <Kind>SingleDecl</Kind>
42+
// CHECK3-NEXT: <Content>{
43+
// CHECK3-NEXT: return 42
44+
// CHECK3-NEXT: }</Content>
45+
// CHECK3-NEXT: <Context>swift_ide_test.(file).ObjCClass</Context>
46+
// CHECK3-NEXT: <Declared>_</Declared><OutscopeReference>false</OutscopeReference>
47+
// CHECK3-NEXT: <ASTNodes>1</ASTNodes>
48+
// CHECK3-NEXT: <end>
49+
50+
51+
// CHECK4: <Kind>SingleDecl</Kind>
52+
// CHECK4-NEXT: <Content>@objc var bar = 12, baz = 13</Content>
53+
// CHECK4-NEXT: <Context>swift_ide_test.(file).ObjCClass</Context>
54+
// CHECK4-NEXT: <Declared>bar</Declared><OutscopeReference>false</OutscopeReference>
55+
// CHECK4-NEXT: <Declared>baz</Declared><OutscopeReference>false</OutscopeReference>
56+
// CHECK4-NEXT: <ASTNodes>1</ASTNodes>
57+
// CHECK4-NEXT: <end>

0 commit comments

Comments
 (0)