Skip to content

Commit bb3edd5

Browse files
committed
[CodeCompletion] contextual attribute completion only on the same line
It's common to have decls on consecutive lines. Better to show too many attributes than too few.
1 parent bc03796 commit bb3edd5

File tree

4 files changed

+53
-38
lines changed

4 files changed

+53
-38
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,12 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
13521352
void setAttrTargetDeclKind(Optional<DeclKind> DK) override {
13531353
if (DK == DeclKind::PatternBinding)
13541354
DK = DeclKind::Var;
1355-
AttTargetDK = DK;
1355+
else if (DK == DeclKind::Param)
1356+
// For params, consider the attribute is always for the decl.
1357+
AttTargetIsIndependent = false;
1358+
1359+
if (!AttTargetIsIndependent)
1360+
AttTargetDK = DK;
13561361
}
13571362

13581363
void completeExpr() override;
@@ -5376,16 +5381,13 @@ void CodeCompletionCallbacksImpl::doneParsing() {
53765381
}
53775382

53785383
case CompletionKind::AttributeBegin: {
5379-
auto DK = AttTargetDK;
5380-
if (AttTargetIsIndependent)
5381-
DK = None;
5382-
Lookup.getAttributeDeclCompletions(IsInSil, DK);
5384+
Lookup.getAttributeDeclCompletions(IsInSil, AttTargetDK);
53835385

53845386
// TypeName at attribute position after '@'.
53855387
// - VarDecl: Property Wrappers.
53865388
// - ParamDecl/VarDecl/FuncDecl: Function Buildres.
5387-
if (!DK.hasValue() || *DK == DeclKind::Var || *DK == DeclKind::Param ||
5388-
*DK == DeclKind::Func)
5389+
if (!AttTargetDK || *AttTargetDK == DeclKind::Var ||
5390+
*AttTargetDK == DeclKind::Param || *AttTargetDK == DeclKind::Func)
53895391
Lookup.getTypeCompletionsInDeclContext(
53905392
P.Context.SourceMgr.getCodeCompletionLoc());
53915393
break;

lib/Parse/ParseDecl.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,10 +1754,11 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc At
17541754

17551755
if (Tok.is(tok::code_complete)) {
17561756
if (CodeCompletion) {
1757-
auto ccLine = SourceMgr.getLineNumber(Tok.getLoc());
1758-
auto nextLine = SourceMgr.getLineNumber(peekToken().getLoc());
1759-
CodeCompletion->completeDeclAttrBeginning(isInSILMode(),
1760-
(nextLine - ccLine) > 1);
1757+
// If the next token is not on the same line, this attribute might be
1758+
// starting new declaration instead of adding attribute to existing
1759+
// decl.
1760+
auto isIndependent = peekToken().isAtStartOfLine();
1761+
CodeCompletion->completeDeclAttrBeginning(isInSILMode(), isIndependent);
17611762
}
17621763
consumeToken(tok::code_complete);
17631764
return makeParserCodeCompletionStatus();

test/IDE/complete_decl_attribute.swift

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_INIT | %FileCheck %s -check-prefix=ON_INIT
1010
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_PROPERTY | %FileCheck %s -check-prefix=ON_PROPERTY
1111
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_METHOD | %FileCheck %s -check-prefix=ON_METHOD
12-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_PARAM | %FileCheck %s -check-prefix=ON_PARAM
13-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_MEMBER_INDEPENDENT | %FileCheck %s -check-prefix=ON_MEMBER_LAST
12+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_PARAM_1 | %FileCheck %s -check-prefix=ON_PARAM
13+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_PARAM_2 | %FileCheck %s -check-prefix=ON_PARAM
14+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_MEMBER_INDEPENDENT_1 | %FileCheck %s -check-prefix=ON_MEMBER_LAST
15+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_MEMBER_INDEPENDENT_2 | %FileCheck %s -check-prefix=ON_MEMBER_LAST
1416
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ON_MEMBER_LAST | %FileCheck %s -check-prefix=ON_MEMBER_LAST
15-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_INDEPENDENT | %FileCheck %s -check-prefix=KEYWORD_LAST
17+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_INDEPENDENT_1 | %FileCheck %s -check-prefix=KEYWORD_LAST
18+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_INDEPENDENT_2 | %FileCheck %s -check-prefix=KEYWORD_LAST
1619
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_LAST | %FileCheck %s -check-prefix=KEYWORD_LAST
1720

1821
struct MyStruct {}
@@ -46,8 +49,7 @@ struct MyStruct {}
4649
// AVAILABILITY2-NEXT: Keyword/None: deprecated: [#Specify version number#]; name=deprecated{{$}}
4750
// AVAILABILITY2-NEXT: End completions
4851

49-
@#^KEYWORD2^#
50-
func method(){}
52+
@#^KEYWORD2^# func method(){}
5153

5254
// KEYWORD2: Begin completions
5355
// KEYWORD2-NEXT: Keyword/None: available[#Func Attribute#]; name=available{{$}}
@@ -65,8 +67,7 @@ func method(){}
6567
// KEYWORD2: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
6668
// KEYWORD2: End completions
6769

68-
@#^KEYWORD3^#
69-
class C {}
70+
@#^KEYWORD3^# class C {}
7071

7172
// KEYWORD3: Begin completions
7273
// KEYWORD3-NEXT: Keyword/None: available[#Class Attribute#]; name=available{{$}}
@@ -83,12 +84,10 @@ class C {}
8384
// KEYWORD3-NEXT: Keyword/None: _functionBuilder[#Class Attribute#]; name=_functionBuilder
8485
// KEYWORD3-NEXT: End completions
8586

86-
@#^KEYWORD3_2^#IB
87-
class C2 {}
87+
@#^KEYWORD3_2^#IB class C2 {}
8888
// Same as KEYWORD3.
8989

90-
@#^KEYWORD4^#
91-
enum E {}
90+
@#^KEYWORD4^# enum E {}
9291
// KEYWORD4: Begin completions
9392
// KEYWORD4-NEXT: Keyword/None: available[#Enum Attribute#]; name=available{{$}}
9493
// KEYWORD4-NEXT: Keyword/None: objc[#Enum Attribute#]; name=objc{{$}}
@@ -100,8 +99,7 @@ enum E {}
10099
// KEYWORD4-NEXT: End completions
101100

102101

103-
@#^KEYWORD5^#
104-
struct S{}
102+
@#^KEYWORD5^# struct S{}
105103
// KEYWORD5: Begin completions
106104
// KEYWORD5-NEXT: Keyword/None: available[#Struct Attribute#]; name=available{{$}}
107105
// KEYWORD5-NEXT: Keyword/None: dynamicCallable[#Struct Attribute#]; name=dynamicCallable
@@ -111,8 +109,7 @@ struct S{}
111109
// KEYWORD5-NEXT: Keyword/None: _functionBuilder[#Struct Attribute#]; name=_functionBuilder
112110
// KEYWORD5-NEXT: End completions
113111

114-
@#^ON_GLOBALVAR^#
115-
var globalVar
112+
@#^ON_GLOBALVAR^# var globalVar
116113
// ON_GLOBALVAR: Begin completions
117114
// ON_GLOBALVAR-DAG: Keyword/None: available[#Var Attribute#]; name=available
118115
// ON_GLOBALVAR-DAG: Keyword/None: objc[#Var Attribute#]; name=objc
@@ -130,8 +127,7 @@ var globalVar
130127
// ON_GLOBALVAR: End completions
131128

132129
struct _S {
133-
@#^ON_INIT^#
134-
init()
130+
@#^ON_INIT^# init()
135131
// ON_INIT: Begin completions
136132
// ON_INIT-DAG: Keyword/None: available[#Constructor Attribute#]; name=available
137133
// ON_INIT-DAG: Keyword/None: objc[#Constructor Attribute#]; name=objc
@@ -142,8 +138,7 @@ struct _S {
142138
// ON_INIT-DAG: Keyword/None: discardableResult[#Constructor Attribute#]; name=discardableResult
143139
// ON_INIT: End completions
144140

145-
@#^ON_PROPERTY^#
146-
var foo
141+
@#^ON_PROPERTY^# var foo
147142
// ON_PROPERTY: Begin completions
148143
// ON_PROPERTY-DAG: Keyword/None: available[#Var Attribute#]; name=available
149144
// ON_PROPERTY-DAG: Keyword/None: objc[#Var Attribute#]; name=objc
@@ -161,8 +156,7 @@ struct _S {
161156
// ON_PROPERTY-NOT: Decl[PrecedenceGroup]
162157
// ON_PROPERTY: End completions
163158

164-
@#^ON_METHOD^#
165-
private
159+
@#^ON_METHOD^# private
166160
func foo()
167161
// ON_METHOD: Begin completions
168162
// ON_METHOD-DAG: Keyword/None: available[#Func Attribute#]; name=available
@@ -180,16 +174,29 @@ struct _S {
180174
// ON_METHOD: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
181175
// ON_METHOD: End completions
182176

183-
func bar(@#^ON_PARAM^#)
177+
func bar(@#^ON_PARAM_1^#)
184178
// ON_PARAM: Begin completions
185179
// ON_PARAM-NOT: Keyword
186180
// ON_PARAM: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
187181
// ON_PARAM-NOT: Keyword
188182
// ON_PARAM: End completions
189183

190-
@#^ON_MEMBER_INDEPENDENT^#
184+
func bar(
185+
@#^ON_PARAM_2^#
186+
187+
arg: Int
188+
)
189+
// Same as ON_PARAM.
190+
191+
@#^ON_MEMBER_INDEPENDENT_1^#
192+
193+
func dummy1() {}
194+
// Same as ON_MEMBER_LAST.
195+
196+
@#^ON_MEMBER_INDEPENDENT_2^#
197+
func dummy2() {}
198+
// Same as ON_MEMBER_LAST.
191199

192-
func dummy() {}
193200

194201
@#^ON_MEMBER_LAST^#
195202
// ON_MEMBER_LAST: Begin completions
@@ -223,9 +230,14 @@ struct _S {
223230
// ON_MEMBER_LAST: End completions
224231
}
225232

226-
@#^KEYWORD_INDEPENDENT^#
233+
@#^KEYWORD_INDEPENDENT_1^#
234+
235+
func dummy1() {}
236+
// Same as KEYWORD_LAST.
227237

228-
func dummy() {}
238+
@#^KEYWORD_INDEPENDENT_2^#
239+
func dummy2() {}
240+
// Same as KEYWORD_LAST.
229241

230242
@#^KEYWORD_LAST^#
231243

test/IDE/complete_pound_decl.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// MEMBER: End completions
1616

1717
// ATTR: Begin completions
18-
// ATTR: available[#Func Attribute#]; name=available
18+
// ATTR: available[#Declaration Attribute#]; name=available
1919
// ATTR: End completions
2020

2121
// GLOBAL: Begin completions

0 commit comments

Comments
 (0)