1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-05 09:20:04 +00:00

Resolve switch statement with patterns, support variables.

Change-Id: Idafdd5680beed4ea556cfd47941bfb22e5fe6797
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/272521
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov 2022-11-30 01:16:06 +00:00 committed by Commit Queue
parent f28b2d71cd
commit 13531511d5
8 changed files with 956 additions and 37 deletions

View File

@ -1184,6 +1184,12 @@ mixin TypeAnalyzer<
_finishJoinedVariables(variables, reportErrors: false);
handleCase_afterCaseHeads(node, caseIndex, variables.values);
// Stack: (Expression, numExecutionPaths * StatementCase, CaseHeads)
// If there are joined variables, declare them.
if (heads.length > 1 || memberInfo.hasLabels) {
for (Variable variable in variables.values) {
flow?.declare(variable, true);
}
}
for (Statement statement in memberInfo.body) {
dispatchStatement(statement);
}

View File

@ -12513,6 +12513,9 @@ class SwitchStatementCaseGroup {
final List<SwitchMemberImpl> members;
final bool hasLabels;
/// Joined variables declared in [members], available in [statements].
late final Map<String, PromotableElement> variables;
SwitchStatementCaseGroup(this.members, this.hasLabels);
NodeListImpl<StatementImpl> get statements {

View File

@ -670,14 +670,29 @@ class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
}
@override
void visitSwitchStatement(SwitchStatement node) {
var expression = node.expression;
var members = node.members;
expression.accept(this);
void visitSwitchStatement(covariant SwitchStatementImpl node) {
node.expression.accept(this);
assignedVariables.beginNode();
members.accept(this);
for (var group in node.memberGroups) {
for (var member in group.members) {
if (member is SwitchCaseImpl) {
member.expression.accept(this);
} else if (member is SwitchPatternCaseImpl) {
var guardedPattern = member.guardedPattern;
assignedVariables.beginNode();
for (var variable in guardedPattern.variables.values) {
assignedVariables.declare(variable);
}
guardedPattern.whenClause?.accept(this);
assignedVariables.endNode(node);
}
}
for (var variable in group.variables.values) {
assignedVariables.declare(variable);
}
group.statements.accept(this);
}
assignedVariables.endNode(node);
}

View File

@ -1162,8 +1162,8 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
if (group.hasLabels) {
_patternVariables.switchStatementSharedCaseScopeEmpty(node);
}
// TODO(scheglov) use variables
_patternVariables.switchStatementSharedCaseScopeFinish(node);
group.variables =
_patternVariables.switchStatementSharedCaseScopeFinish(node);
_withNameScope(() {
var statements = group.statements;
_buildLocalElements(statements);

View File

@ -942,7 +942,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
var guardedPattern = member.guardedPattern;
return CaseHeadOrDefaultInfo(
pattern: guardedPattern.pattern,
variables: {}, // TODO(scheglov) use actual
variables: guardedPattern.variables,
guard: guardedPattern.whenClause?.expression,
);
} else {
@ -958,7 +958,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
return SwitchStatementMemberInfo(
group.members.map(ofMember).toList(),
group.statements,
{},
group.variables,
hasLabels: group.hasLabels,
);
}
@ -4585,23 +4585,7 @@ class ScopeResolverVisitor extends UnifyingAstVisitor<void> {
}
@override
void visitSwitchCase(SwitchCase node) {
node.expression.accept(this);
_withDeclaredLocals(node, node.statements, () {
node.statements.accept(this);
});
}
@override
void visitSwitchDefault(SwitchDefault node) {
_withDeclaredLocals(node, node.statements, () {
node.statements.accept(this);
});
}
@override
void visitSwitchStatement(SwitchStatement node) {
void visitSwitchStatement(covariant SwitchStatementImpl node) {
var outerScope = labelScope;
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
@ -4614,17 +4598,34 @@ class ScopeResolverVisitor extends UnifyingAstVisitor<void> {
LabelScope(labelScope, labelName.name, member, labelElement);
}
}
visitSwitchStatementInScope(node);
node.expression.accept(this);
for (var group in node.memberGroups) {
for (var member in group.members) {
if (member is SwitchCaseImpl) {
member.expression.accept(this);
} else if (member is SwitchPatternCaseImpl) {
_withNameScope(() {
var variables = member.guardedPattern.variables;
for (var variable in variables.values) {
_define(variable);
}
member.guardedPattern.accept(this);
});
}
}
_withDeclaredLocals(node, group.statements, () {
for (var variable in group.variables.values) {
_define(variable);
}
group.statements.accept(this);
});
}
} finally {
labelScope = outerScope;
_implicitLabelScope = outerImplicitScope;
}
}
void visitSwitchStatementInScope(SwitchStatement node) {
super.visitSwitchStatement(node);
}
@override
void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);

View File

@ -45,7 +45,6 @@ f() {
expect(element.nameOffset, 23);
}
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50502')
test_element_switchCase() async {
await assertNoErrorsInCode(r'''
f(int a) {

View File

@ -2,18 +2,20 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(SwitchStatementPatternTest);
defineReflectiveTests(SwitchStatementResolutionTest);
defineReflectiveTests(SwitchStatementResolutionTest_Language218);
});
}
@reflectiveTest
class SwitchStatementPatternTest extends PatternsResolutionTest {
class SwitchStatementResolutionTest extends PubPackageResolutionTest {
test_default() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
@ -228,6 +230,797 @@ SwitchStatement
''');
}
test_variables_joinedCase_declareBoth_consistent() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case int a when a < 0:
case int a when a > 0:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@48
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@48
staticType: int
operator: <
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::<::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::<
staticInvokeType: bool Function(num)
staticType: bool
colon: :
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@75
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@75
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: a[a@48, a@75]
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_variables_joinedCase_declareBoth_consistent_final() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case final int a when a < 0:
case final int a when a > 0:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
keyword: final
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: isFinal a@54
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@54
staticType: int
operator: <
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::<::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::<
staticInvokeType: bool Function(num)
staticType: bool
colon: :
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
keyword: final
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: isFinal a@87
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@87
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: final a[a@54, a@87]
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_variables_joinedCase_declareBoth_notConsistent_differentFinality() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case final int a when a < 0:
case num a when a > 0:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
keyword: final
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: isFinal a@54
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@54
staticType: int
operator: <
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::<::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::<
staticInvokeType: bool Function(num)
staticType: bool
colon: :
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: num
staticElement: dart:core::@class::num
staticType: null
type: num
name: a
declaredElement: a@81
type: num
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@81
staticType: num
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: notConsistent a[a@54, a@81]
staticType: dynamic
semicolon: ;
rightBracket: }
''');
}
test_variables_joinedCase_declareBoth_notConsistent_differentTypes() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case int a when a < 0:
case num a when a > 0:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@48
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@48
staticType: int
operator: <
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::<::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::<
staticInvokeType: bool Function(num)
staticType: bool
colon: :
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: num
staticElement: dart:core::@class::num
staticType: null
type: num
name: a
declaredElement: a@75
type: num
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@75
staticType: num
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: notConsistent a[a@48, a@75]
staticType: dynamic
semicolon: ;
rightBracket: }
''');
}
test_variables_joinedCase_declareFirst() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case 0:
case int a when a > 0:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
colon: :
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@60
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@60
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: notConsistent a[a@60]
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_variables_joinedCase_declareSecond() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case int a when a > 0:
case 0:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@48
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@48
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: notConsistent a[a@48]
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_variables_joinedCase_hasDefault() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case int a when a > 0:
default:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@48
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@48
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
SwitchDefault
keyword: default
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: notConsistent a[a@48]
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_variables_joinedCase_hasLabel() async {
await assertErrorsInCode(r'''
void f(Object? x) {
switch (x) {
myLabel:
case int a when a > 0:
a;
}
}
''', [
error(HintCode.UNUSED_LABEL, 39, 8),
]);
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
labels
Label
label: SimpleIdentifier
token: myLabel
staticElement: myLabel@39
staticType: null
colon: :
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@61
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@61
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: notConsistent a[a@61]
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_variables_scope() async {
await assertErrorsInCode(r'''
const a = 0;
void f(Object? x) {
switch (x) {
case [int a, == a] when a > 0:
a;
}
}
''', [
error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 68, 1,
contextMessages: [message('/home/test/lib/test.dart', 62, 1)]),
]);
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: ListPattern
leftBracket: [
elements
VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@62
type: int
RelationalPattern
operator: ==
operand: SimpleIdentifier
token: a
staticElement: a@62
staticType: int
element: dart:core::@class::Object::@method::==
rightBracket: ]
requiredType: List<Object?>
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@62
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: a@62
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_variables_singleCase() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case int a when a > 0:
a;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchPatternCase
keyword: case
guardedPattern: GuardedPattern
pattern: VariablePattern
type: NamedType
name: SimpleIdentifier
token: int
staticElement: dart:core::@class::int
staticType: null
type: int
name: a
declaredElement: a@48
type: int
whenClause: WhenClause
whenKeyword: when
expression: BinaryExpression
leftOperand: SimpleIdentifier
token: a
staticElement: a@48
staticType: int
operator: >
rightOperand: IntegerLiteral
literal: 0
parameter: dart:core::@class::num::@method::>::@parameter::other
staticType: int
staticElement: dart:core::@class::num::@method::>
staticInvokeType: bool Function(num)
staticType: bool
colon: :
statements
ExpressionStatement
expression: SimpleIdentifier
token: a
staticElement: a@48
staticType: int
semicolon: ;
rightBracket: }
''');
}
test_whenClause() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
@ -271,3 +1064,107 @@ SwitchStatement
''');
}
}
@reflectiveTest
class SwitchStatementResolutionTest_Language218 extends PubPackageResolutionTest
with WithLanguage218Mixin {
test_default() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case 0:
break;
default:
break;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchCase
keyword: case
expression: IntegerLiteral
literal: 0
staticType: int
colon: :
statements
BreakStatement
breakKeyword: break
semicolon: ;
SwitchDefault
keyword: default
colon: :
statements
BreakStatement
breakKeyword: break
semicolon: ;
rightBracket: }
''');
}
test_mergeCases() async {
await assertNoErrorsInCode(r'''
void f(Object? x) {
switch (x) {
case 0:
case 1:
break;
case 2:
break;
}
}
''');
final node = findNode.switchStatement('switch');
assertResolvedNodeText(node, r'''
SwitchStatement
switchKeyword: switch
leftParenthesis: (
expression: SimpleIdentifier
token: x
staticElement: self::@function::f::@parameter::x
staticType: Object?
rightParenthesis: )
leftBracket: {
members
SwitchCase
keyword: case
expression: IntegerLiteral
literal: 0
staticType: int
colon: :
SwitchCase
keyword: case
expression: IntegerLiteral
literal: 1
staticType: int
colon: :
statements
BreakStatement
breakKeyword: break
semicolon: ;
SwitchCase
keyword: case
expression: IntegerLiteral
literal: 2
staticType: int
colon: :
statements
BreakStatement
breakKeyword: break
semicolon: ;
rightBracket: }
''');
}
}

View File

@ -116,7 +116,6 @@ print(x) {}
]);
}
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50502')
test_hideInSwitchCase_function() async {
await assertErrorsInCode(r'''
var v = 0;
@ -156,7 +155,6 @@ void f(int a) {
assertElement(findNode.simple('v;'), findElement.localFunction('v'));
}
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50502')
test_hideInSwitchCase_local() async {
await assertErrorsInCode(r'''
var v = 0;