mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:18:01 +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:
parent
f28b2d71cd
commit
13531511d5
|
@ -1184,6 +1184,12 @@ mixin TypeAnalyzer<
|
||||||
_finishJoinedVariables(variables, reportErrors: false);
|
_finishJoinedVariables(variables, reportErrors: false);
|
||||||
handleCase_afterCaseHeads(node, caseIndex, variables.values);
|
handleCase_afterCaseHeads(node, caseIndex, variables.values);
|
||||||
// Stack: (Expression, numExecutionPaths * StatementCase, CaseHeads)
|
// 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) {
|
for (Statement statement in memberInfo.body) {
|
||||||
dispatchStatement(statement);
|
dispatchStatement(statement);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12513,6 +12513,9 @@ class SwitchStatementCaseGroup {
|
||||||
final List<SwitchMemberImpl> members;
|
final List<SwitchMemberImpl> members;
|
||||||
final bool hasLabels;
|
final bool hasLabels;
|
||||||
|
|
||||||
|
/// Joined variables declared in [members], available in [statements].
|
||||||
|
late final Map<String, PromotableElement> variables;
|
||||||
|
|
||||||
SwitchStatementCaseGroup(this.members, this.hasLabels);
|
SwitchStatementCaseGroup(this.members, this.hasLabels);
|
||||||
|
|
||||||
NodeListImpl<StatementImpl> get statements {
|
NodeListImpl<StatementImpl> get statements {
|
||||||
|
|
|
@ -670,14 +670,29 @@ class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitSwitchStatement(SwitchStatement node) {
|
void visitSwitchStatement(covariant SwitchStatementImpl node) {
|
||||||
var expression = node.expression;
|
node.expression.accept(this);
|
||||||
var members = node.members;
|
|
||||||
|
|
||||||
expression.accept(this);
|
|
||||||
|
|
||||||
assignedVariables.beginNode();
|
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);
|
assignedVariables.endNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1162,7 +1162,7 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
|
||||||
if (group.hasLabels) {
|
if (group.hasLabels) {
|
||||||
_patternVariables.switchStatementSharedCaseScopeEmpty(node);
|
_patternVariables.switchStatementSharedCaseScopeEmpty(node);
|
||||||
}
|
}
|
||||||
// TODO(scheglov) use variables
|
group.variables =
|
||||||
_patternVariables.switchStatementSharedCaseScopeFinish(node);
|
_patternVariables.switchStatementSharedCaseScopeFinish(node);
|
||||||
_withNameScope(() {
|
_withNameScope(() {
|
||||||
var statements = group.statements;
|
var statements = group.statements;
|
||||||
|
|
|
@ -942,7 +942,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
|
||||||
var guardedPattern = member.guardedPattern;
|
var guardedPattern = member.guardedPattern;
|
||||||
return CaseHeadOrDefaultInfo(
|
return CaseHeadOrDefaultInfo(
|
||||||
pattern: guardedPattern.pattern,
|
pattern: guardedPattern.pattern,
|
||||||
variables: {}, // TODO(scheglov) use actual
|
variables: guardedPattern.variables,
|
||||||
guard: guardedPattern.whenClause?.expression,
|
guard: guardedPattern.whenClause?.expression,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -958,7 +958,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
|
||||||
return SwitchStatementMemberInfo(
|
return SwitchStatementMemberInfo(
|
||||||
group.members.map(ofMember).toList(),
|
group.members.map(ofMember).toList(),
|
||||||
group.statements,
|
group.statements,
|
||||||
{},
|
group.variables,
|
||||||
hasLabels: group.hasLabels,
|
hasLabels: group.hasLabels,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4585,23 +4585,7 @@ class ScopeResolverVisitor extends UnifyingAstVisitor<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitSwitchCase(SwitchCase node) {
|
void visitSwitchStatement(covariant SwitchStatementImpl 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) {
|
|
||||||
var outerScope = labelScope;
|
var outerScope = labelScope;
|
||||||
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
|
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
|
||||||
try {
|
try {
|
||||||
|
@ -4614,17 +4598,34 @@ class ScopeResolverVisitor extends UnifyingAstVisitor<void> {
|
||||||
LabelScope(labelScope, labelName.name, member, labelElement);
|
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 {
|
} finally {
|
||||||
labelScope = outerScope;
|
labelScope = outerScope;
|
||||||
_implicitLabelScope = outerImplicitScope;
|
_implicitLabelScope = outerImplicitScope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitSwitchStatementInScope(SwitchStatement node) {
|
|
||||||
super.visitSwitchStatement(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitVariableDeclaration(VariableDeclaration node) {
|
void visitVariableDeclaration(VariableDeclaration node) {
|
||||||
super.visitVariableDeclaration(node);
|
super.visitVariableDeclaration(node);
|
||||||
|
|
|
@ -45,7 +45,6 @@ f() {
|
||||||
expect(element.nameOffset, 23);
|
expect(element.nameOffset, 23);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50502')
|
|
||||||
test_element_switchCase() async {
|
test_element_switchCase() async {
|
||||||
await assertNoErrorsInCode(r'''
|
await assertNoErrorsInCode(r'''
|
||||||
f(int a) {
|
f(int a) {
|
||||||
|
|
|
@ -2,18 +2,20 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// 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 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||||
|
|
||||||
import 'context_collection_resolution.dart';
|
import 'context_collection_resolution.dart';
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
defineReflectiveSuite(() {
|
defineReflectiveSuite(() {
|
||||||
defineReflectiveTests(SwitchStatementPatternTest);
|
defineReflectiveTests(SwitchStatementResolutionTest);
|
||||||
|
defineReflectiveTests(SwitchStatementResolutionTest_Language218);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@reflectiveTest
|
@reflectiveTest
|
||||||
class SwitchStatementPatternTest extends PatternsResolutionTest {
|
class SwitchStatementResolutionTest extends PubPackageResolutionTest {
|
||||||
test_default() async {
|
test_default() async {
|
||||||
await assertNoErrorsInCode(r'''
|
await assertNoErrorsInCode(r'''
|
||||||
void f(Object? x) {
|
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 {
|
test_whenClause() async {
|
||||||
await assertNoErrorsInCode(r'''
|
await assertNoErrorsInCode(r'''
|
||||||
void f(Object? x) {
|
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: }
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -116,7 +116,6 @@ print(x) {}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50502')
|
|
||||||
test_hideInSwitchCase_function() async {
|
test_hideInSwitchCase_function() async {
|
||||||
await assertErrorsInCode(r'''
|
await assertErrorsInCode(r'''
|
||||||
var v = 0;
|
var v = 0;
|
||||||
|
@ -156,7 +155,6 @@ void f(int a) {
|
||||||
assertElement(findNode.simple('v;'), findElement.localFunction('v'));
|
assertElement(findNode.simple('v;'), findElement.localFunction('v'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/50502')
|
|
||||||
test_hideInSwitchCase_local() async {
|
test_hideInSwitchCase_local() async {
|
||||||
await assertErrorsInCode(r'''
|
await assertErrorsInCode(r'''
|
||||||
var v = 0;
|
var v = 0;
|
||||||
|
|
Loading…
Reference in a new issue