blob: 6c954e94c512a4cf54d4ea5e756edafa3c759531 [file] [log] [blame]
// Copyright (c) 2018, 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/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(EnumDeclarationResolutionTest);
});
}
@reflectiveTest
class EnumDeclarationResolutionTest extends PubPackageResolutionTest {
test_constructor_argumentList_contextType() async {
await assertNoErrorsInCode(r'''
enum E {
v([]);
const E(List<int> a);
}
''');
var node = findNode.listLiteral('[]');
assertResolvedNodeText(node, r'''
ListLiteral
leftBracket: [
rightBracket: ]
correspondingParameter: <testLibraryFragment>::@enum::E::@constructor::new::@parameter::a#element
staticType: List<int>
''');
}
test_constructor_argumentList_namedType() async {
await assertNoErrorsInCode(r'''
enum E {
v(<void Function(double)>[]);
const E(Object a);
}
''');
var node = findNode.genericFunctionType('Function');
assertResolvedNodeText(node, r'''
GenericFunctionType
returnType: NamedType
name: void
element2: <null>
type: void
functionKeyword: Function
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: double
element2: dart:core::@class::double
type: double
declaredElement: null@null
type: double
rightParenthesis: )
declaredElement: GenericFunctionTypeElement
parameters
<empty>
kind: required positional
type: double
returnType: void
type: void Function(double)
type: void Function(double)
''');
}
test_constructor_generic_noTypeArguments_named() async {
await assertNoErrorsInCode(r'''
enum E<T> {
v.named(42);
const E.named(T a);
}
''');
var node = findNode.enumConstantDeclaration('v.');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
arguments: EnumConstantArguments
constructorSelector: ConstructorSelector
period: .
name: SimpleIdentifier
token: named
element: <null>
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 42
correspondingParameter: ParameterMember
baseElement: <testLibraryFragment>::@enum::E::@constructor::named::@parameter::a#element
substitution: {T: int}
staticType: int
rightParenthesis: )
constructorElement2: ConstructorMember
baseElement: <testLibraryFragment>::@enum::E::@constructor::named#element
substitution: {T: int}
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_constructor_generic_noTypeArguments_unnamed() async {
await assertNoErrorsInCode(r'''
enum E<T> {
v(42);
const E(T a);
}
''');
var node = findNode.enumConstantDeclaration('v(');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
arguments: EnumConstantArguments
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 42
correspondingParameter: ParameterMember
baseElement: <testLibraryFragment>::@enum::E::@constructor::new::@parameter::a#element
substitution: {T: int}
staticType: int
rightParenthesis: )
constructorElement2: ConstructorMember
baseElement: <testLibraryFragment>::@enum::E::@constructor::new#element
substitution: {T: int}
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_constructor_generic_typeArguments_named() async {
await assertNoErrorsInCode(r'''
enum E<T> {
v<double>.named(42);
const E.named(T a);
}
''');
var node = findNode.enumConstantDeclaration('v<');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
arguments: EnumConstantArguments
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: double
element2: dart:core::@class::double
type: double
rightBracket: >
constructorSelector: ConstructorSelector
period: .
name: SimpleIdentifier
token: named
element: <null>
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 42
correspondingParameter: ParameterMember
baseElement: <testLibraryFragment>::@enum::E::@constructor::named::@parameter::a#element
substitution: {T: double}
staticType: double
rightParenthesis: )
constructorElement2: ConstructorMember
baseElement: <testLibraryFragment>::@enum::E::@constructor::named#element
substitution: {T: double}
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_constructor_notGeneric_named() async {
await assertNoErrorsInCode(r'''
enum E {
v.named(42);
const E.named(int a);
}
''');
var node = findNode.enumConstantDeclaration('v.');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
arguments: EnumConstantArguments
constructorSelector: ConstructorSelector
period: .
name: SimpleIdentifier
token: named
element: <null>
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 42
correspondingParameter: <testLibraryFragment>::@enum::E::@constructor::named::@parameter::a#element
staticType: int
rightParenthesis: )
constructorElement2: <testLibraryFragment>::@enum::E::@constructor::named#element
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_constructor_notGeneric_unnamed() async {
await assertNoErrorsInCode(r'''
enum E {
v(42);
const E(int a);
}
''');
var node = findNode.enumConstantDeclaration('v(');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
arguments: EnumConstantArguments
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 42
correspondingParameter: <testLibraryFragment>::@enum::E::@constructor::new::@parameter::a#element
staticType: int
rightParenthesis: )
constructorElement2: <testLibraryFragment>::@enum::E::@constructor::new#element
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_constructor_notGeneric_unnamed_implicit() async {
await assertNoErrorsInCode(r'''
enum E {
v
}
''');
var node = findNode.enumConstantDeclaration('v\n');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
constructorElement2: <testLibraryFragment>::@enum::E::@constructor::new#element
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_constructor_unresolved_named() async {
await assertErrorsInCode(
r'''
enum E {
v.named(42);
const E(int a);
}
''',
[error(CompileTimeErrorCode.UNDEFINED_ENUM_CONSTRUCTOR_NAMED, 13, 5)],
);
var node = findNode.enumConstantDeclaration('v.');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
arguments: EnumConstantArguments
constructorSelector: ConstructorSelector
period: .
name: SimpleIdentifier
token: named
element: <null>
staticType: null
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 42
correspondingParameter: <null>
staticType: int
rightParenthesis: )
constructorElement2: <null>
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_constructor_unresolved_unnamed() async {
await assertErrorsInCode(
r'''
enum E {
v(42);
const E.named(int a);
}
''',
[error(CompileTimeErrorCode.UNDEFINED_ENUM_CONSTRUCTOR_UNNAMED, 11, 1)],
);
var node = findNode.enumConstantDeclaration('v(');
assertResolvedNodeText(node, r'''
EnumConstantDeclaration
name: v
arguments: EnumConstantArguments
argumentList: ArgumentList
leftParenthesis: (
arguments
IntegerLiteral
literal: 42
correspondingParameter: <null>
staticType: int
rightParenthesis: )
constructorElement2: <null>
declaredElement: <testLibraryFragment>::@enum::E::@field::v
''');
}
test_field() async {
await assertNoErrorsInCode(r'''
enum E {
v;
final foo = 42;
}
''');
var node = findNode.fieldDeclaration('foo =');
assertResolvedNodeText(node, r'''
FieldDeclaration
fields: VariableDeclarationList
keyword: final
variables
VariableDeclaration
name: foo
equals: =
initializer: IntegerLiteral
literal: 42
staticType: int
declaredElement: <testLibraryFragment>::@enum::E::@field::foo
semicolon: ;
declaredElement: <null>
''');
}
test_getter() async {
await assertNoErrorsInCode(r'''
enum E<T> {
v;
T get foo => throw 0;
}
''');
var node = findNode.methodDeclaration('get foo');
assertResolvedNodeText(node, r'''
MethodDeclaration
returnType: NamedType
name: T
element2: T@7
type: T
propertyKeyword: get
name: foo
body: ExpressionFunctionBody
functionDefinition: =>
expression: ThrowExpression
throwKeyword: throw
expression: IntegerLiteral
literal: 0
staticType: int
staticType: Never
semicolon: ;
declaredElement: <testLibraryFragment>::@enum::E::@getter::foo
type: T Function()
''');
}
test_inference_listLiteral() async {
await assertNoErrorsInCode(r'''
enum E1 {a, b}
enum E2 {a, b}
var v = [E1.a, E2.b];
''');
var v = findElement2.topVar('v');
assertType(v.type, 'List<Enum>');
}
test_interfaces() async {
await assertNoErrorsInCode(r'''
class I {}
enum E implements I {
v;
}
''');
var node = findNode.implementsClause('implements');
assertResolvedNodeText(node, r'''
ImplementsClause
implementsKeyword: implements
interfaces
NamedType
name: I
element2: <testLibrary>::@class::I
type: I
''');
}
test_isEnumConstant() async {
await assertNoErrorsInCode(r'''
enum E {
a, b
}
''');
expect(findElement2.field('a').isEnumConstant, isTrue);
expect(findElement2.field('b').isEnumConstant, isTrue);
expect(findElement2.field('values').isEnumConstant, isFalse);
}
test_method() async {
await assertNoErrorsInCode(r'''
enum E<T> {
v;
int foo<U>(T t, U u) => 0;
}
''');
var node = findNode.singleMethodDeclaration;
assertResolvedNodeText(node, r'''
MethodDeclaration
returnType: NamedType
name: int
element2: dart:core::@class::int
type: int
name: foo
typeParameters: TypeParameterList
leftBracket: <
typeParameters
TypeParameter
name: U
declaredElement: U@27
defaultType: dynamic
rightBracket: >
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: T
element2: T@7
type: T
name: t
declaredElement: <testLibraryFragment>::@enum::E::@method::foo::@formalParameter::t
type: T
parameter: SimpleFormalParameter
type: NamedType
name: U
element2: U@27
type: U
name: u
declaredElement: <testLibraryFragment>::@enum::E::@method::foo::@formalParameter::u
type: U
rightParenthesis: )
body: ExpressionFunctionBody
functionDefinition: =>
expression: IntegerLiteral
literal: 0
staticType: int
semicolon: ;
declaredElement: <testLibraryFragment>::@enum::E::@method::foo
type: int Function<U>(T, U)
''');
}
test_method_toString() async {
await assertNoErrorsInCode(r'''
enum E {
v;
String toString() => 'E';
}
''');
var node = findNode.methodDeclaration('toString()');
assertResolvedNodeText(node, r'''
MethodDeclaration
returnType: NamedType
name: String
element2: dart:core::@class::String
type: String
name: toString
parameters: FormalParameterList
leftParenthesis: (
rightParenthesis: )
body: ExpressionFunctionBody
functionDefinition: =>
expression: SimpleStringLiteral
literal: 'E'
semicolon: ;
declaredElement: <testLibraryFragment>::@enum::E::@method::toString
type: String Function()
''');
}
test_mixins() async {
await assertNoErrorsInCode(r'''
mixin M {}
enum E with M {
v;
}
''');
var node = findNode.withClause('with M');
assertResolvedNodeText(node, r'''
WithClause
withKeyword: with
mixinTypes
NamedType
name: M
element2: <testLibrary>::@mixin::M
type: M
''');
}
test_mixins_inference() async {
await assertNoErrorsInCode(r'''
mixin M1<T> {}
mixin M2<T> on M1<T> {}
enum E with M1<int>, M2 {
v;
}
''');
var node = findNode.withClause('with');
assertResolvedNodeText(node, r'''
WithClause
withKeyword: with
mixinTypes
NamedType
name: M1
typeArguments: TypeArgumentList
leftBracket: <
arguments
NamedType
name: int
element2: dart:core::@class::int
type: int
rightBracket: >
element2: <testLibrary>::@mixin::M1
type: M1<int>
NamedType
name: M2
element2: <testLibrary>::@mixin::M2
type: M2<int>
''');
}
test_setter() async {
await assertNoErrorsInCode(r'''
enum E<T> {
v;
set foo(T a) {}
}
''');
var node = findNode.methodDeclaration('set foo');
assertResolvedNodeText(node, r'''
MethodDeclaration
propertyKeyword: set
name: foo
parameters: FormalParameterList
leftParenthesis: (
parameter: SimpleFormalParameter
type: NamedType
name: T
element2: T@7
type: T
name: a
declaredElement: <testLibraryFragment>::@enum::E::@setter::foo::@formalParameter::a
type: T
rightParenthesis: )
body: BlockFunctionBody
block: Block
leftBracket: {
rightBracket: }
declaredElement: <testLibraryFragment>::@enum::E::@setter::foo
type: void Function(T)
''');
}
test_value_underscore() async {
await assertNoErrorsInCode(r'''
enum E { _ }
void f() {
E._.index;
}
''');
var node = findNode.singlePropertyAccess;
assertResolvedNodeText(node, r'''
PropertyAccess
target: PrefixedIdentifier
prefix: SimpleIdentifier
token: E
element: <testLibrary>::@enum::E
staticType: null
period: .
identifier: SimpleIdentifier
token: _
element: <testLibraryFragment>::@enum::E::@getter::_#element
staticType: E
element: <testLibraryFragment>::@enum::E::@getter::_#element
staticType: E
operator: .
propertyName: SimpleIdentifier
token: index
element: dart:core::<fragment>::@class::Enum::@getter::index#element
staticType: int
staticType: int
''');
}
}