Skip to content

Commit 47d29ca

Browse files
FMorschelCommit Queue
authored andcommitted
[DAS] Fixes types and keyword suggestions on named parameters
Fixes: #60550 Change-Id: Ie1f116387483c47f48b90cd6353481b06d93321e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422903 Commit-Queue: Brian Wilkerson <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]> Auto-Submit: Felipe Morschel <[email protected]>
1 parent 1577900 commit 47d29ca

File tree

5 files changed

+193
-91
lines changed

5 files changed

+193
-91
lines changed

pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,11 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
13481348
}
13491349
}
13501350

1351-
keywordHelper.addFormalParameterKeywords(node);
1351+
keywordHelper.addFormalParameterKeywords(
1352+
node,
1353+
suggestRequired: true,
1354+
suggestVariableName: true,
1355+
);
13521356
_forTypeAnnotation(node);
13531357
}
13541358

@@ -1507,7 +1511,11 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
15071511
collector.completionLocation = 'FormalParameterList_parameter';
15081512
var returnType = node.returnType;
15091513
if (returnType != null && offset <= returnType.end) {
1510-
keywordHelper.addFormalParameterKeywords(node.parentFormalParameterList);
1514+
keywordHelper.addFormalParameterKeywords(
1515+
node.parentFormalParameterList,
1516+
suggestRequired: node.requiredKeyword == null,
1517+
suggestVariableName: node.name.lexeme.isEmpty,
1518+
);
15111519
_forTypeAnnotation(node);
15121520
} else if (returnType == null && offset < node.name.offset) {
15131521
_forTypeAnnotation(node);
@@ -2551,24 +2559,18 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
25512559
@override
25522560
void visitSimpleFormalParameter(SimpleFormalParameter node) {
25532561
var name = node.name;
2562+
var noRequired = node.requiredKeyword == null;
25542563
if (name != null && node.isSingleIdentifier) {
25552564
collector.completionLocation = 'FormalParameterList_parameter';
2565+
keywordHelper.addFormalParameterKeywords(
2566+
node.parentFormalParameterList,
2567+
suggestRequired: name.keyword != Keyword.REQUIRED,
2568+
suggestCovariant: name.keyword != Keyword.COVARIANT,
2569+
suggestVariableName: true,
2570+
);
2571+
_forTypeAnnotation(node);
25562572
if (name.isKeyword) {
2557-
if (name.keyword == Keyword.REQUIRED && node.covariantKeyword == null) {
2558-
keywordHelper.addKeyword(Keyword.COVARIANT);
2559-
}
2560-
_forTypeAnnotation(node);
25612573
return;
2562-
} else if (name.isSynthetic) {
2563-
keywordHelper.addFormalParameterKeywords(
2564-
node.parentFormalParameterList,
2565-
);
2566-
_forTypeAnnotation(node);
2567-
} else {
2568-
keywordHelper.addFormalParameterKeywords(
2569-
node.parentFormalParameterList,
2570-
);
2571-
_forTypeAnnotation(node);
25722574
}
25732575
}
25742576
var type = node.type;
@@ -2589,6 +2591,9 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
25892591
if (type.beginToken.coversOffset(offset)) {
25902592
keywordHelper.addFormalParameterKeywords(
25912593
node.parentFormalParameterList,
2594+
suggestRequired: noRequired,
2595+
suggestVariableName:
2596+
node.name == null || type.beginToken.offset == offset,
25922597
);
25932598
_forTypeAnnotation(node);
25942599
} else if (type is GenericFunctionType &&
@@ -2598,11 +2603,17 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
25982603
}
25992604
} else {
26002605
var keyword = node.keyword;
2601-
if (keyword != null && offset <= keyword.end) {
2606+
if (keyword == null || offset <= keyword.end) {
26022607
collector.completionLocation = 'FormalParameterList_parameter';
26032608
var parent = node.parent;
2604-
if (parent is FormalParameterList) {
2605-
keywordHelper.addFormalParameterKeywords(parent);
2609+
if (parent
2610+
case FormalParameterList list ||
2611+
DefaultFormalParameter(parent: FormalParameterList list)) {
2612+
keywordHelper.addFormalParameterKeywords(
2613+
list,
2614+
suggestRequired: noRequired,
2615+
suggestVariableName: name.coversOffset(offset),
2616+
);
26062617
}
26072618
_forTypeAnnotation(node);
26082619
}

pkg/analysis_server/lib/src/services/completion/dart/keyword_helper.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ class KeywordHelper {
299299

300300
/// Return `true` if `switch` should be suggested for the given [node].
301301
bool switchIsValid(AstNode? node) {
302+
if (node is SimpleIdentifier && node.parent is DefaultFormalParameter) {
303+
return false;
304+
}
302305
if (node is CollectionElement && node is! Expression) {
303306
node = node.parent;
304307
}
@@ -421,12 +424,22 @@ class KeywordHelper {
421424

422425
/// Add the keywords that are appropriate when the selection is at the start
423426
/// of a formal parameter in the given [parameterList].
424-
void addFormalParameterKeywords(FormalParameterList parameterList) {
425-
addKeyword(Keyword.COVARIANT);
427+
void addFormalParameterKeywords(
428+
FormalParameterList parameterList, {
429+
required bool suggestRequired,
430+
required bool suggestVariableName,
431+
bool suggestCovariant = true,
432+
}) {
433+
if (suggestCovariant) {
434+
addKeyword(Keyword.COVARIANT);
435+
}
426436
addKeyword(Keyword.FINAL);
427-
if (parameterList.inNamedGroup(offset)) {
437+
if (suggestRequired && parameterList.inNamedGroup(offset)) {
428438
addKeyword(Keyword.REQUIRED);
429439
}
440+
if (!suggestVariableName) {
441+
return;
442+
}
430443
var parent = parameterList.parent;
431444
if (parent is ConstructorDeclaration) {
432445
if (featureSet.isEnabled(Feature.super_parameters)) {

pkg/analysis_server/test/services/completion/dart/completion_test.dart

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5179,48 +5179,6 @@ suggestions
51795179
Future<void> test_commentSnippets030_1() async {
51805180
allowedIdentifiers = {'T'};
51815181
await computeSuggestions('''
5182-
class Bar<T extends Foo> {const Bar(^T k);T m(T a, T b){}final T f = null;}
5183-
''');
5184-
assertResponse(r'''
5185-
replacement
5186-
right: 1
5187-
suggestions
5188-
this
5189-
kind: keyword
5190-
void
5191-
kind: keyword
5192-
T
5193-
kind: typeParameter
5194-
covariant
5195-
kind: keyword
5196-
dynamic
5197-
kind: keyword
5198-
final
5199-
kind: keyword
5200-
super
5201-
kind: keyword
5202-
''');
5203-
}
5204-
5205-
Future<void> test_commentSnippets030_2() async {
5206-
allowedIdentifiers = {'T'};
5207-
await computeSuggestions('''
5208-
class Bar<T extends Foo> {const Bar(T^ k);T m(T a, T b){}final T f = null;}
5209-
''');
5210-
assertResponse(r'''
5211-
replacement
5212-
left: 1
5213-
suggestions
5214-
this
5215-
kind: keyword
5216-
T
5217-
kind: typeParameter
5218-
''');
5219-
}
5220-
5221-
Future<void> test_commentSnippets030_3() async {
5222-
allowedIdentifiers = {'T'};
5223-
await computeSuggestions('''
52245182
class Bar<T extends Foo> {const Bar(T k);T^ m(T a, T b){}final T f = null;}
52255183
''');
52265184
assertResponse(r'''
@@ -5232,7 +5190,7 @@ suggestions
52325190
''');
52335191
}
52345192

5235-
Future<void> test_commentSnippets030_4() async {
5193+
Future<void> test_commentSnippets030_2() async {
52365194
allowedIdentifiers = {'T'};
52375195
await computeSuggestions('''
52385196
class Bar<T extends Foo> {const Bar(T k);T m(T^ a, T b){}final T f = null;}
@@ -5246,7 +5204,7 @@ suggestions
52465204
''');
52475205
}
52485206

5249-
Future<void> test_commentSnippets030_5() async {
5207+
Future<void> test_commentSnippets030_3() async {
52505208
allowedIdentifiers = {'T'};
52515209
await computeSuggestions('''
52525210
class Bar<T extends Foo> {const Bar(T k);T m(T a, T^ b){}final T f = null;}
@@ -5260,7 +5218,7 @@ suggestions
52605218
''');
52615219
}
52625220

5263-
Future<void> test_commentSnippets030_6() async {
5221+
Future<void> test_commentSnippets030_4() async {
52645222
allowedIdentifiers = {'T'};
52655223
await computeSuggestions('''
52665224
class Bar<T extends Foo> {const Bar(T k);T m(T a, T b){}final T^ f = null;}

pkg/analysis_server/test/services/completion/dart/location/parameter_list_test.dart

Lines changed: 144 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,116 @@ replacement
9393
suggestions
9494
this
9595
kind: keyword
96+
''');
97+
}
98+
99+
Future<void> test_afterRequired_beforeVariableName() async {
100+
allowedIdentifiers = {'int', 'String'};
101+
await computeSuggestions('''
102+
class A {
103+
A({required ^ s});
104+
}
105+
''');
106+
assertResponse(r'''
107+
suggestions
108+
String
109+
kind: class
110+
int
111+
kind: class
112+
void
113+
kind: keyword
114+
covariant
115+
kind: keyword
116+
dynamic
117+
kind: keyword
118+
final
119+
kind: keyword
120+
''');
121+
}
122+
123+
Future<void> test_afterRequired_withoutVariableName() async {
124+
allowedIdentifiers = {'int', 'String'};
125+
await computeSuggestions('''
126+
class A {
127+
A({required ^});
128+
}
129+
''');
130+
assertResponse(r'''
131+
suggestions
132+
String
133+
kind: class
134+
int
135+
kind: class
136+
this
137+
kind: keyword
138+
void
139+
kind: keyword
140+
covariant
141+
kind: keyword
142+
dynamic
143+
kind: keyword
144+
final
145+
kind: keyword
146+
super
147+
kind: keyword
148+
''');
149+
}
150+
151+
Future<void> test_afterRequiredVariableName() async {
152+
allowedIdentifiers = {'String'};
153+
await computeSuggestions('''
154+
class A {
155+
A({required S^});
156+
}
157+
''');
158+
assertResponse(r'''
159+
replacement
160+
left: 1
161+
suggestions
162+
String
163+
kind: class
164+
super
165+
kind: keyword
166+
''');
167+
}
168+
169+
Future<void> test_afterType() async {
170+
allowedIdentifiers = {'T'};
171+
await computeSuggestions('''
172+
class Bar<T extends Foo> {const Bar(T^ k);T m(T a, T b){}final T f = null;}
173+
''');
174+
assertResponse(r'''
175+
replacement
176+
left: 1
177+
suggestions
178+
T
179+
kind: typeParameter
180+
''');
181+
}
182+
183+
Future<void> test_beforeType() async {
184+
allowedIdentifiers = {'T'};
185+
await computeSuggestions('''
186+
class Bar<T extends Foo> {const Bar(^T k);T m(T a, T b){}final T f = null;}
187+
''');
188+
assertResponse(r'''
189+
replacement
190+
right: 1
191+
suggestions
192+
this
193+
kind: keyword
194+
void
195+
kind: keyword
196+
T
197+
kind: typeParameter
198+
covariant
199+
kind: keyword
200+
dynamic
201+
kind: keyword
202+
final
203+
kind: keyword
204+
super
205+
kind: keyword
96206
''');
97207
}
98208
}
@@ -118,6 +228,40 @@ suggestions
118228
kind: keyword
119229
final
120230
kind: keyword
231+
''');
232+
}
233+
234+
Future<void> test_named_last_afterCovariant() async {
235+
await computeSuggestions('''
236+
void f({covariant ^}) {}
237+
''');
238+
assertResponse('''
239+
suggestions
240+
void
241+
kind: keyword
242+
dynamic
243+
kind: keyword
244+
final
245+
kind: keyword
246+
required
247+
kind: keyword
248+
''');
249+
}
250+
251+
Future<void> test_named_last_afterRequired() async {
252+
await computeSuggestions('''
253+
void f({required ^}) {}
254+
''');
255+
assertResponse('''
256+
suggestions
257+
void
258+
kind: keyword
259+
covariant
260+
kind: keyword
261+
dynamic
262+
kind: keyword
263+
final
264+
kind: keyword
121265
''');
122266
}
123267
}
@@ -141,8 +285,6 @@ suggestions
141285
kind: keyword
142286
null
143287
kind: keyword
144-
switch
145-
kind: keyword
146288
''');
147289
}
148290

@@ -173,8 +315,6 @@ suggestions
173315
kind: keyword
174316
null
175317
kind: keyword
176-
switch
177-
kind: keyword
178318
''');
179319
}
180320

0 commit comments

Comments
 (0)