blob: e52b1d6e745ef84727cf884ad6549632d0f2eb8e [file] [log] [blame]
// 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:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(MapPatternResolutionTest);
});
}
@reflectiveTest
class MapPatternResolutionTest extends PubPackageResolutionTest {
test_matchDynamic_noTypeArguments_variable_typed() async {
await assertErrorsInCode(
r'''
void f(x) {
switch (x) {
case {0: String a}:
break;
}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 47, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: DeclaredVariablePattern
type: NamedType
name: String
element2: dart:core::@class::String
type: String
name: a
declaredElement: a@47
type: String
matchedValueType: dynamic
rightBracket: }
matchedValueType: dynamic
requiredType: Map<dynamic, dynamic>
''');
}
test_matchDynamic_noTypeArguments_variable_untyped() async {
await assertErrorsInCode(
r'''
void f(x) {
switch (x) {
case {0: var a}:
break;
}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 44, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: DeclaredVariablePattern
keyword: var
name: a
declaredElement: hasImplicitType a@44
type: dynamic
matchedValueType: dynamic
rightBracket: }
matchedValueType: dynamic
requiredType: Map<dynamic, dynamic>
''');
}
test_matchDynamic_withTypeArguments_variable_untyped() async {
await assertErrorsInCode(
r'''
void f(x) {
switch (x) {
case <int, String>{0: var a}:
break;
}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 57, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element2: dart:core::@class::int
type: int
NamedType
name: String
element2: dart:core::@class::String
type: String
rightBracket: >
leftBracket: {
elements
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: DeclaredVariablePattern
keyword: var
name: a
declaredElement: hasImplicitType a@57
type: String
matchedValueType: String
rightBracket: }
matchedValueType: dynamic
requiredType: Map<int, String>
''');
}
test_matchMap_noTypeArguments_empty() async {
await assertErrorsInCode(
r'''
void f(Map<int, String> x) {
if (x case {}) {}
}
''',
[error(CompileTimeErrorCode.EMPTY_MAP_PATTERN, 42, 2)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
rightBracket: }
matchedValueType: Map<int, String>
requiredType: Map<int, String>
''');
}
test_matchMap_noTypeArguments_restElement_first() async {
await assertErrorsInCode(
r'''
void f(Map<int, String> x) {
if (x case {..., 0: ''}) {}
}
''',
[error(CompileTimeErrorCode.REST_ELEMENT_IN_MAP_PATTERN, 43, 3)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
RestPatternElement
operator: ...
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: ConstantPattern
expression: SimpleStringLiteral
literal: ''
matchedValueType: String
rightBracket: }
matchedValueType: Map<int, String>
requiredType: Map<int, String>
''');
}
test_matchMap_noTypeArguments_restElement_last() async {
await assertErrorsInCode(
r'''
void f(Map<int, String> x) {
if (x case {0: '', ...}) {}
}
''',
[error(CompileTimeErrorCode.REST_ELEMENT_IN_MAP_PATTERN, 50, 3)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: ConstantPattern
expression: SimpleStringLiteral
literal: ''
matchedValueType: String
RestPatternElement
operator: ...
rightBracket: }
matchedValueType: Map<int, String>
requiredType: Map<int, String>
''');
}
test_matchMap_noTypeArguments_restElement_multiple() async {
await assertErrorsInCode(
r'''
void f(Map<int, String> x) {
if (x case {..., 0: '', ...}) {}
}
''',
[
error(CompileTimeErrorCode.REST_ELEMENT_IN_MAP_PATTERN, 43, 3),
error(CompileTimeErrorCode.REST_ELEMENT_IN_MAP_PATTERN, 55, 3),
],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
RestPatternElement
operator: ...
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: ConstantPattern
expression: SimpleStringLiteral
literal: ''
matchedValueType: String
RestPatternElement
operator: ...
rightBracket: }
matchedValueType: Map<int, String>
requiredType: Map<int, String>
''');
}
test_matchMap_noTypeArguments_restElement_withPattern() async {
await assertErrorsInCode(
r'''
void f(Map<int, String> x) {
if (x case {0: '', ...var rest}) {}
}
''',
[
error(CompileTimeErrorCode.REST_ELEMENT_IN_MAP_PATTERN, 50, 11),
error(WarningCode.UNUSED_LOCAL_VARIABLE, 57, 4),
],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: ConstantPattern
expression: SimpleStringLiteral
literal: ''
matchedValueType: String
RestPatternElement
operator: ...
pattern: DeclaredVariablePattern
keyword: var
name: rest
declaredElement: hasImplicitType rest@57
type: dynamic
matchedValueType: dynamic
rightBracket: }
matchedValueType: Map<int, String>
requiredType: Map<int, String>
''');
}
test_matchMap_noTypeArguments_variable_untyped() async {
await assertErrorsInCode(
r'''
void f(Map<int, String> x) {
if (x case {0: var a}) {}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 50, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: IntegerLiteral
literal: 0
staticType: int
separator: :
value: DeclaredVariablePattern
keyword: var
name: a
declaredElement: hasImplicitType a@50
type: String
matchedValueType: String
rightBracket: }
matchedValueType: Map<int, String>
requiredType: Map<int, String>
''');
}
test_matchMap_withTypeArguments_variable_untyped() async {
await assertErrorsInCode(
r'''
void f(Map<bool, num> x) {
if (x case <bool, int>{true: var a}) {}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 62, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: bool
element2: dart:core::@class::bool
type: bool
NamedType
name: int
element2: dart:core::@class::int
type: int
rightBracket: >
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: DeclaredVariablePattern
keyword: var
name: a
declaredElement: hasImplicitType a@62
type: int
matchedValueType: int
rightBracket: }
matchedValueType: Map<bool, num>
requiredType: Map<bool, int>
''');
}
test_matchObject_noTypeArguments_constant() async {
await assertNoErrorsInCode(r'''
void f(Object x) {
if (x case {true: 0}) {}
}
''');
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
matchedValueType: Object?
rightBracket: }
matchedValueType: Object
requiredType: Map<Object?, Object?>
''');
}
test_matchObject_noTypeArguments_empty() async {
await assertErrorsInCode(
r'''
void f(Object x) {
if (x case {}) {}
}
''',
[error(CompileTimeErrorCode.EMPTY_MAP_PATTERN, 32, 2)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
rightBracket: }
matchedValueType: Object
requiredType: Map<Object?, Object?>
''');
}
test_matchObject_noTypeArguments_variable_typed() async {
await assertErrorsInCode(
r'''
void f(Object x) {
if (x case {true: int a}) {}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 43, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: DeclaredVariablePattern
type: NamedType
name: int
element2: dart:core::@class::int
type: int
name: a
declaredElement: a@43
type: int
matchedValueType: Object?
rightBracket: }
matchedValueType: Object
requiredType: Map<Object?, Object?>
''');
}
test_matchObject_noTypeArguments_variable_untyped() async {
await assertErrorsInCode(
r'''
void f(Object x) {
if (x case {true: var a}) {}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 43, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: DeclaredVariablePattern
keyword: var
name: a
declaredElement: hasImplicitType a@43
type: Object?
matchedValueType: Object?
rightBracket: }
matchedValueType: Object
requiredType: Map<Object?, Object?>
''');
}
test_matchObject_withTypeArguments_constant() async {
await assertNoErrorsInCode(r'''
void f(Object x) {
if (x case <bool, int>{true: 0}) {}
}
''');
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: bool
element2: dart:core::@class::bool
type: bool
NamedType
name: int
element2: dart:core::@class::int
type: int
rightBracket: >
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
matchedValueType: int
rightBracket: }
matchedValueType: Object
requiredType: Map<bool, int>
''');
}
test_matchObject_withTypeArguments_variable_untyped() async {
await assertErrorsInCode(
r'''
void f(Object x) {
if (x case <bool, int>{true: var a}) {}
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 54, 1)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: bool
element2: dart:core::@class::bool
type: bool
NamedType
name: int
element2: dart:core::@class::int
type: int
rightBracket: >
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: DeclaredVariablePattern
keyword: var
name: a
declaredElement: hasImplicitType a@54
type: int
matchedValueType: int
rightBracket: }
matchedValueType: Object
requiredType: Map<bool, int>
''');
}
test_rewrite_key() async {
await assertErrorsInCode(
r'''
void f(x, bool Function() a) {
if (x case {a(): 0}) {}
}
''',
[error(CompileTimeErrorCode.NON_CONSTANT_MAP_PATTERN_KEY, 45, 3)],
);
var node = findNode.singleGuardedPattern.pattern;
assertResolvedNodeText(node, r'''
MapPattern
leftBracket: {
elements
MapPatternEntry
key: FunctionExpressionInvocation
function: SimpleIdentifier
token: a
element: <testLibrary>::@function::f::@formalParameter::a
staticType: bool Function()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
element: <null>
staticInvokeType: bool Function()
staticType: bool
separator: :
value: ConstantPattern
expression: IntegerLiteral
literal: 0
staticType: int
matchedValueType: dynamic
rightBracket: }
matchedValueType: dynamic
requiredType: Map<dynamic, dynamic>
''');
}
test_variableDeclaration_inferredType() async {
await assertErrorsInCode(
r'''
void f(Map<bool, int> x) {
var {true: a} = x;
}
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 40, 1)],
);
var node = findNode.singlePatternVariableDeclaration;
assertResolvedNodeText(node, r'''
PatternVariableDeclaration
keyword: var
pattern: MapPattern
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: DeclaredVariablePattern
name: a
declaredElement: hasImplicitType a@40
type: int
matchedValueType: int
rightBracket: }
matchedValueType: Map<bool, int>
requiredType: Map<bool, int>
equals: =
expression: SimpleIdentifier
token: x
element: <testLibrary>::@function::f::@formalParameter::x
staticType: Map<bool, int>
patternTypeSchema: Map<_, _>
''');
}
test_variableDeclaration_typeSchema_withTypeArguments() async {
await assertErrorsInCode(
r'''
void f() {
var <bool, int>{true: a} = g();
}
T g<T>() => throw 0;
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 35, 1)],
);
var node = findNode.singlePatternVariableDeclaration;
assertResolvedNodeText(node, r'''
PatternVariableDeclaration
keyword: var
pattern: MapPattern
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: bool
element2: dart:core::@class::bool
type: bool
NamedType
name: int
element2: dart:core::@class::int
type: int
rightBracket: >
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: DeclaredVariablePattern
name: a
declaredElement: hasImplicitType a@35
type: int
matchedValueType: int
rightBracket: }
matchedValueType: Map<bool, int>
requiredType: Map<bool, int>
equals: =
expression: MethodInvocation
methodName: SimpleIdentifier
token: g
element: <testLibrary>::@function::g
staticType: T Function<T>()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticInvokeType: Map<bool, int> Function()
staticType: Map<bool, int>
typeArgumentTypes
Map<bool, int>
patternTypeSchema: Map<bool, int>
''');
}
test_variableDeclaration_typeSchema_withVariableType() async {
await assertErrorsInCode(
r'''
void f() {
var {true: int a} = g();
}
T g<T>() => throw 0;
''',
[error(WarningCode.UNUSED_LOCAL_VARIABLE, 28, 1)],
);
var node = findNode.singlePatternVariableDeclaration;
assertResolvedNodeText(node, r'''
PatternVariableDeclaration
keyword: var
pattern: MapPattern
leftBracket: {
elements
MapPatternEntry
key: BooleanLiteral
literal: true
staticType: bool
separator: :
value: DeclaredVariablePattern
type: NamedType
name: int
element2: dart:core::@class::int
type: int
name: a
declaredElement: a@28
type: int
matchedValueType: int
rightBracket: }
matchedValueType: Map<Object?, int>
requiredType: Map<Object?, int>
equals: =
expression: MethodInvocation
methodName: SimpleIdentifier
token: g
element: <testLibrary>::@function::g
staticType: T Function<T>()
argumentList: ArgumentList
leftParenthesis: (
rightParenthesis: )
staticInvokeType: Map<Object?, int> Function()
staticType: Map<Object?, int>
typeArgumentTypes
Map<Object?, int>
patternTypeSchema: Map<_, int>
''');
}
}