mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:58:29 +00:00
Resolve WhenClause in SwitchStatement cases.
Change-Id: I836d0bec357597490ad7302e90ff9e4740547810 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/264880 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
35d6ecbcd6
commit
d923f69436
|
@ -778,14 +778,23 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
|
|||
getSwitchStatementMemberInfo(covariant SwitchStatement node, int index) {
|
||||
var member = node.members[index];
|
||||
AstNode? pattern;
|
||||
WhenClause? whenClause;
|
||||
if (member is SwitchCase) {
|
||||
pattern = member.expression;
|
||||
} else if (member is SwitchPatternCase) {
|
||||
pattern = member.pattern;
|
||||
whenClause = member.whenClause;
|
||||
}
|
||||
return SwitchStatementMemberInfo(
|
||||
[CaseHeadOrDefaultInfo(pattern: pattern)], member.statements,
|
||||
labels: member.labels);
|
||||
[
|
||||
CaseHeadOrDefaultInfo(
|
||||
pattern: pattern,
|
||||
guard: whenClause?.expression,
|
||||
),
|
||||
],
|
||||
member.statements,
|
||||
labels: member.labels,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -144,6 +144,82 @@ IfStatement
|
|||
thenStatement: Block
|
||||
leftBracket: {
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_rewrite_whenClause() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(x, bool Function() a) {
|
||||
if (x case 0 when a()) {}
|
||||
}
|
||||
''');
|
||||
|
||||
final node = findNode.ifStatement('if');
|
||||
assertResolvedNodeText(node, r'''
|
||||
IfStatement
|
||||
ifKeyword: if
|
||||
leftParenthesis: (
|
||||
condition: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: dynamic
|
||||
caseClause: CaseClause
|
||||
caseKeyword: case
|
||||
pattern: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
whenClause: WhenClause
|
||||
whenKeyword: when
|
||||
expression: FunctionExpressionInvocation
|
||||
function: SimpleIdentifier
|
||||
token: a
|
||||
staticElement: self::@function::f::@parameter::a
|
||||
staticType: bool Function()
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticElement: <null>
|
||||
staticInvokeType: bool Function()
|
||||
staticType: bool
|
||||
rightParenthesis: )
|
||||
thenStatement: Block
|
||||
leftBracket: {
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_whenClause() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(x) {
|
||||
if (x case 0 when true) {}
|
||||
}
|
||||
''');
|
||||
|
||||
final node = findNode.ifStatement('if');
|
||||
assertResolvedNodeText(node, r'''
|
||||
IfStatement
|
||||
ifKeyword: if
|
||||
leftParenthesis: (
|
||||
condition: SimpleIdentifier
|
||||
token: x
|
||||
staticElement: self::@function::f::@parameter::x
|
||||
staticType: dynamic
|
||||
caseClause: CaseClause
|
||||
caseKeyword: case
|
||||
pattern: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
whenClause: WhenClause
|
||||
whenKeyword: when
|
||||
expression: BooleanLiteral
|
||||
literal: true
|
||||
staticType: bool
|
||||
rightParenthesis: )
|
||||
thenStatement: Block
|
||||
leftBracket: {
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
266
pkg/analyzer/test/src/dart/resolution/switch_statement_test.dart
Normal file
266
pkg/analyzer/test/src/dart/resolution/switch_statement_test.dart
Normal file
|
@ -0,0 +1,266 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// 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:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import 'context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(SwitchStatementPatternTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class SwitchStatementPatternTest extends PatternsResolutionTest {
|
||||
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
|
||||
SwitchPatternCase
|
||||
keyword: case
|
||||
pattern: PostfixPattern
|
||||
operand: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
operator: ?
|
||||
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
|
||||
SwitchPatternCase
|
||||
keyword: case
|
||||
pattern: PostfixPattern
|
||||
operand: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
operator: ?
|
||||
colon: :
|
||||
SwitchPatternCase
|
||||
keyword: case
|
||||
pattern: PostfixPattern
|
||||
operand: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 1
|
||||
staticType: int
|
||||
operator: ?
|
||||
colon: :
|
||||
statements
|
||||
BreakStatement
|
||||
breakKeyword: break
|
||||
semicolon: ;
|
||||
SwitchPatternCase
|
||||
keyword: case
|
||||
pattern: PostfixPattern
|
||||
operand: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 2
|
||||
staticType: int
|
||||
operator: ?
|
||||
colon: :
|
||||
statements
|
||||
BreakStatement
|
||||
breakKeyword: break
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_rewrite_pattern() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(Object? x, int Function() a) {
|
||||
switch (x) {
|
||||
case const a():
|
||||
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
|
||||
SwitchPatternCase
|
||||
keyword: case
|
||||
pattern: ConstantPattern
|
||||
const: const
|
||||
expression: FunctionExpressionInvocation
|
||||
function: SimpleIdentifier
|
||||
token: a
|
||||
staticElement: self::@function::f::@parameter::a
|
||||
staticType: int Function()
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticElement: <null>
|
||||
staticInvokeType: int Function()
|
||||
staticType: int
|
||||
colon: :
|
||||
statements
|
||||
BreakStatement
|
||||
breakKeyword: break
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_rewrite_whenClause() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(Object? x, bool Function() a) {
|
||||
switch (x) {
|
||||
case 0 when a():
|
||||
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
|
||||
SwitchPatternCase
|
||||
keyword: case
|
||||
pattern: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
whenClause: WhenClause
|
||||
whenKeyword: when
|
||||
expression: FunctionExpressionInvocation
|
||||
function: SimpleIdentifier
|
||||
token: a
|
||||
staticElement: self::@function::f::@parameter::a
|
||||
staticType: bool Function()
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
staticElement: <null>
|
||||
staticInvokeType: bool Function()
|
||||
staticType: bool
|
||||
colon: :
|
||||
statements
|
||||
BreakStatement
|
||||
breakKeyword: break
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_whenClause() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
void f(Object? x) {
|
||||
switch (x) {
|
||||
case 0 when true:
|
||||
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
|
||||
SwitchPatternCase
|
||||
keyword: case
|
||||
pattern: ConstantPattern
|
||||
expression: IntegerLiteral
|
||||
literal: 0
|
||||
staticType: int
|
||||
whenClause: WhenClause
|
||||
whenKeyword: when
|
||||
expression: BooleanLiteral
|
||||
literal: true
|
||||
staticType: bool
|
||||
colon: :
|
||||
statements
|
||||
BreakStatement
|
||||
breakKeyword: break
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
}
|
|
@ -77,6 +77,7 @@ import 'record_type_annotation_test.dart' as record_type_annotation;
|
|||
import 'relational_pattern_test.dart' as relational_pattern;
|
||||
import 'simple_identifier_test.dart' as simple_identifier;
|
||||
import 'super_formal_parameter_test.dart' as super_formal_parameter;
|
||||
import 'switch_statement_test.dart' as super_formal_parameter2;
|
||||
import 'top_level_variable_test.dart' as top_level_variable;
|
||||
import 'top_type_inference_test.dart' as top_type_inference;
|
||||
import 'try_statement_test.dart' as try_statement;
|
||||
|
@ -158,6 +159,7 @@ main() {
|
|||
relational_pattern.main();
|
||||
simple_identifier.main();
|
||||
super_formal_parameter.main();
|
||||
super_formal_parameter2.main();
|
||||
top_level_variable.main();
|
||||
top_type_inference.main();
|
||||
try_statement.main();
|
||||
|
|
Loading…
Reference in a new issue