diff --git a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart index b4d75a21d58..ee410236644 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart @@ -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(): diff --git a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart index 07e264556f0..bbbe9d26321 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart @@ -3010,7 +3010,7 @@ class InScopeCompletionPass extends SimpleAstVisitor { @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 { 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, + ); } } diff --git a/pkg/analysis_server/test/services/completion/dart/location/switch_expression_test.dart b/pkg/analysis_server/test/services/completion/dart/location/switch_expression_test.dart index d41c806a415..097908a9d44 100644 --- a/pkg/analysis_server/test/services/completion/dart/location/switch_expression_test.dart +++ b/pkg/analysis_server/test/services/completion/dart/location/switch_expression_test.dart @@ -17,6 +17,45 @@ class SwitchExpressionTest extends AbstractCompletionDriverTest with SwitchExpressionTestCases {} mixin SwitchExpressionTestCases on AbstractCompletionDriverTest { + Future 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 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 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 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 test_body_empty() async { await computeSuggestions(''' int f(Object p01) {