[DAS] Fixes completion for switch expression pattern after when

Fixes: https://github.com/dart-lang/sdk/issues/62210
Change-Id: I42a3d6f3f93a8ecc8f4b866d89119a6cc49bd3e8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/467160
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Auto-Submit: Felipe Morschel <git@fmorschel.dev>
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
This commit is contained in:
FMorschel
2025-12-16 09:07:37 -08:00
committed by Commit Queue
parent 5458ba73e5
commit 275581bca1
3 changed files with 100 additions and 6 deletions
@@ -1301,6 +1301,8 @@ class DeclarationHelper {
case FunctionExpression():
_visitParameterList(currentNode.parameters);
_visitTypeParameterList(currentNode.typeParameters);
case GuardedPattern():
_visitPattern(currentNode.pattern);
case IfElement():
_visitIfElement(currentNode);
case IfStatement():
@@ -3010,7 +3010,7 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
@override
void visitSwitchExpressionCase(SwitchExpressionCase node) {
if (node.arrow.isSynthetic) {
if (node.arrow.isSynthetic || node.arrow.offset >= offset) {
// The user is completing in the pattern.
collector.completionLocation = 'SwitchExpression_body';
_forPattern(node);
@@ -3021,7 +3021,18 @@ class InScopeCompletionPass extends SimpleAstVisitor<void> {
if (endToken == expression.beginToken || endToken.isSynthetic) {
// The user is completing in the expression.
collector.completionLocation = 'SwitchExpressionCase_expression';
_forExpression(node.expression);
var type =
_computeContextType(node.expression) ?? DynamicTypeImpl.instance;
_forExpression(
node.expression,
canBeBool: _canBeBool(type),
canBeNull: _canBeNull(type),
// TODO(FMorschel): Determine if the parameter type has a constant
// constructor.
// Function tear-offs and closures cannot have the `const` keyword
// before it
canSuggestConst: !type.isDartCoreFunction && type is! FunctionType,
);
}
}
@@ -17,6 +17,45 @@ class SwitchExpressionTest extends AbstractCompletionDriverTest
with SwitchExpressionTestCases {}
mixin SwitchExpressionTestCases on AbstractCompletionDriverTest {
Future<void> test_beforeArrow() async {
await computeSuggestions('''
int f(Object p01) {
return switch (p01) {
^ => 0,
};
}
class A1 {
A1.named();
}
const c01 = 0;
final v01 = 0;
int f01() => 0;
''');
assertResponse(r'''
suggestions
A1
kind: class
c01
kind: topLevelVariable
const
kind: keyword
false
kind: keyword
final
kind: keyword
null
kind: keyword
true
kind: keyword
var
kind: keyword
''');
}
Future<void> test_body_afterArrow() async {
await computeSuggestions('''
int f(Object p01) {
@@ -29,12 +68,27 @@ int f(Object p01) {
suggestions
p01
kind: parameter
false
const
kind: keyword
null
kind: keyword
true
switch
kind: keyword
''');
}
Future<void> test_body_afterArrow_newVar() async {
await computeSuggestions('''
int f(Object p01) {
return switch (p01) {
var v01 => ^
};
}
''');
assertResponse(r'''
suggestions
v01
kind: localVariable
p01
kind: parameter
const
kind: keyword
switch
@@ -72,6 +126,33 @@ suggestions
''');
}
Future<void> test_body_afterWhen_newVar() async {
await computeSuggestions('''
int f(Object p01) {
return switch (p01) {
var v01 when ^
};
}
''');
assertResponse(r'''
suggestions
v01
kind: localVariable
false
kind: keyword
true
kind: keyword
p01
kind: parameter
null
kind: keyword
const
kind: keyword
switch
kind: keyword
''');
}
Future<void> test_body_empty() async {
await computeSuggestions('''
int f(Object p01) {