8bfb683892
This CL enables the primary constructors feature by default in Dart 3.13.
The primary constructors feature is a brevity feature. There are no new semantics, but it allows us to express declarations in a less verbose way.
This feature allows one constructor and a set of instance variables to be specified in the header of a declaration.
Currently a declaration with a constructor and some fields is written as:
```dart
// Current syntax.
class Point {
int x;
int y;
Point(this.x, this.y);
}
```
With a primary constructor, we would write the above as:
```
class Point(var int x, var int y);
```
If a primary constructor needs an initializer list or a body, they can be
specified inside the class using the `this` body syntax:
```dart
class Point(var int x, var int y) {
this : assert(x >= 0) {
print('Point created at $x, $y');
}
}
```
As part of this feature, you can also use the `new` and `factory` keywords to
declare constructors in the class body without repeating the class name:
```dart
class Point {
int x, y;
// Equivalent to Point(this.x, this.y)
new(this.x, this.y);
// Equivalent to Point.origin()
new origin() : x = 0, y = 0;
// Equivalent to factory Point.clone(Point other)
factory clone(Point other) => Point(other.x, other.y);
}
```
To learn more about the feature, check out the feature specification located here: https://github.com/dart-lang/language/blob/main/accepted/future-releases/primary-constructors/feature-specification.md
Tested: Has existing language, CFE, analyzer, analysis server tests.
Bug: https://github.com/dart-lang/sdk/issues/61524
Change-Id: I296f2fcd918b87bf2a1dd00256340759866c2423
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489241
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Michael Thomsen <mit@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
662 lines
20 KiB
Dart
662 lines
20 KiB
Dart
// 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.
|
|
|
|
// Test errors required by new enhanced enum syntax.
|
|
|
|
// Enums must satisfy the same requirements as their induced class.
|
|
// That means no name conflicts, no static/instance member conflicts,
|
|
// and no type errors.
|
|
// Enum classes must implement their interface.
|
|
// They cannot override `Enum.index` or have any instance member named
|
|
// `values` or declare any name which will conflicts with a static
|
|
// constant getter named `values`.
|
|
//
|
|
// An enum declaration's generative constructors can never be referenced
|
|
// other than implicitly in creating the values and as target of redirecting
|
|
// generative constructors. All generative constructors must be const.
|
|
//
|
|
// An enum class cannot override `index` or implement anything named `values`.
|
|
|
|
// Helper mixins and also used as interfaces.
|
|
mixin GetFoo {
|
|
int get foo => 42;
|
|
}
|
|
|
|
mixin SetFoo {
|
|
void set foo(int _) {}
|
|
}
|
|
|
|
mixin MethodFoo {
|
|
int foo() => 42;
|
|
}
|
|
|
|
mixin ValuesGetter {
|
|
int get values => 42;
|
|
}
|
|
|
|
mixin IndexGetter {
|
|
int get index => 42;
|
|
}
|
|
|
|
mixin NeverIndexGetter {
|
|
Never get index => throw "Never!";
|
|
}
|
|
|
|
// "You cannot have two members with the same name in the same class---be
|
|
// they declared or inherited"
|
|
|
|
// Enums inherit members of `Object` and `index`.
|
|
// Enums implicitly declare `values` and their enum values (as static const
|
|
// getters.)
|
|
|
|
enum ConflictInstanceMembers {
|
|
e1;
|
|
int get foo => 42;
|
|
int foo() => 37;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'foo' is already declared in this scope.
|
|
}
|
|
|
|
// "It is an error if you have a static member named $m$ in your class
|
|
// and an instance member of the same basename"
|
|
enum ConflictStaticGetterInstanceMembers {
|
|
e1;
|
|
static int get foo => 42;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
int foo() => 37;
|
|
// ^
|
|
// [cfe] 'foo' is already declared in this scope.
|
|
}
|
|
|
|
enum ConflictStaticSetterInstanceMembers {
|
|
e1;
|
|
static void set foo(int _) {}
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
int foo() => 37;
|
|
// ^
|
|
// [cfe] The declaration conflicts with setter 'foo'.
|
|
}
|
|
|
|
enum ConflictStaticInstanceProperty2 {
|
|
e1;
|
|
int get foo => 42;
|
|
static void set foo(int _) {}
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
// [cfe] Static property 'foo' conflicts with instance property of the same name.
|
|
}
|
|
|
|
// "It is an error if you have a static getter $v$
|
|
// and an instance setter \code{$v$=}"
|
|
enum ConflictStaticInstanceProperty {
|
|
e1;
|
|
static int get foo => 42;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
void set foo(int _) {}
|
|
// ^
|
|
// [cfe] Instance property 'foo' conflicts with static property of the same name.
|
|
}
|
|
|
|
|
|
enum ConflictStaticInheritedFoo with MethodFoo {
|
|
e1;
|
|
static int get foo => 42;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum ConflictInheritedEnumValue with MethodFoo {
|
|
foo;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum ConflictStaticEnumValues {
|
|
e1,
|
|
e1,
|
|
//^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'e1' is already declared in this scope.
|
|
;
|
|
}
|
|
|
|
enum ConflictStaticEnumValuesLooksDifferent {
|
|
e1(),
|
|
e1.value(42),
|
|
//^^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] 'e1' is already declared in this scope.
|
|
;
|
|
const ConflictStaticEnumValuesLooksDifferent();
|
|
const ConflictStaticEnumValuesLooksDifferent.value( dynamic_);
|
|
}
|
|
|
|
enum ConflictInstanceGetterInheritedFooMethod with MethodFoo {
|
|
e1;
|
|
int get foo => 42;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_FIELD_AND_METHOD
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum ConflictStaticInstanceImplicitValues {
|
|
e1;
|
|
int get values => 42;
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.VALUES_DECLARATION_IN_ENUM
|
|
// [cfe] An enum can't declare a member named 'values'.
|
|
}
|
|
|
|
enum ConflictStaticInstanceEnumValue {
|
|
e1;
|
|
//^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
int get e1 => 42;
|
|
// ^
|
|
// [cfe] 'e1' is already declared in this scope.
|
|
}
|
|
|
|
enum ConflictEnumValueInheritedIndex {
|
|
index;
|
|
//^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum ConflictEnumValueInheritedToString {
|
|
toString;
|
|
//^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum ConflictEnumValueImplicitValues {
|
|
values;
|
|
//^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.VALUES_DECLARATION_IN_ENUM
|
|
// [cfe] An enum can't declare a member named 'values'.
|
|
}
|
|
|
|
enum ConflictEnumValueInheritedFoo with MethodFoo {
|
|
foo;
|
|
//^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum ConflictClassGetterSetterTypeInstance {
|
|
e1;
|
|
num get foo => 42;
|
|
|
|
// Type of setter parameter must be subtype of type of getter.
|
|
void set foo(int _) {}
|
|
}
|
|
|
|
enum ConflictClassGetterSetterTypeStatic {
|
|
e1;
|
|
static num get foo => 42;
|
|
|
|
// Type of setter parameter must be subtype of type of getter.
|
|
static void set foo(int _) {}
|
|
}
|
|
|
|
enum NoConflictClassEnumValueStaticSetter {
|
|
e1;
|
|
|
|
static void set e1(NoConflictClassEnumValueStaticSetter _) {}
|
|
}
|
|
|
|
enum ConflictClassEnumValueStaticSetterType {
|
|
e1;
|
|
|
|
// Type of setter parameter must be subtype of type of getter.
|
|
static void set e1(int _) {}
|
|
}
|
|
|
|
enum ConflictTypeParameterMember<foo> {
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_TYPE_VARIABLE_AND_MEMBER
|
|
e1;
|
|
int get foo => 42;
|
|
// ^
|
|
// [cfe] Conflicts with type variable 'foo'.
|
|
}
|
|
|
|
enum ConflictTypeParameterValues<values> {
|
|
// ^
|
|
// [cfe] Conflicts with type variable 'values'.
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_TYPE_VARIABLE_AND_MEMBER
|
|
e1;
|
|
}
|
|
|
|
enum ConflictTypeParameterEnumValue<e1> {
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_TYPE_VARIABLE_AND_MEMBER
|
|
e1;
|
|
//^
|
|
// [cfe] Conflicts with type variable 'e1'.
|
|
}
|
|
|
|
enum ConflictTypeParameters<T, T> {
|
|
// ^
|
|
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
|
|
// [cfe] A type variable can't have the same name as another.
|
|
e1;
|
|
}
|
|
|
|
enum ConflictClassTypeParameter<ConflictClassTypeParameter> {
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_TYPE_VARIABLE_AND_CONTAINER
|
|
// [cfe] A type variable can't have the same name as its enclosing declaration.
|
|
e1;
|
|
// [error column 3]
|
|
// [cfe] Couldn't find constructor 'ConflictClassTypeParameter'.
|
|
}
|
|
|
|
// "If you define an instance member named $m$,
|
|
// and your superclass has an instance member of the same name,
|
|
// they override each other."
|
|
|
|
enum OverrideInheritedMemberOverride with MethodFoo {
|
|
e1;
|
|
int foo(int x) => x; // super.foo is nullary.
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
|
|
// [cfe] The method 'OverrideInheritedMemberOverride.foo' has more required arguments than those of overridden method '_Enum with MethodFoo.foo'.
|
|
}
|
|
|
|
enum OverrideInheritedMemberDifferentType with GetFoo {
|
|
e1;
|
|
int foo(int x) => x;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_METHOD_AND_FIELD
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum ImplementInheritedMemberDifferentType implements GetFoo {
|
|
e1;
|
|
int foo(int x) => x;
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_METHOD_AND_FIELD
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum OverrideInheritedParameterTypeOverride with SetFoo {
|
|
e1;
|
|
void set foo(Never n) {} // Invalid parameter override.
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
|
|
// ^
|
|
// [cfe] The parameter 'n' of the method 'OverrideInheritedParameterTypeOverride.foo' has type 'Never', which does not match the corresponding type, 'int', in the overridden method, '_Enum with SetFoo.foo'.
|
|
}
|
|
|
|
// "Setters, getters and operators never have
|
|
// optional parameters of any kind"
|
|
|
|
enum DeclareOperatorOptional {
|
|
e1;
|
|
int operator+([int? x]) => x ?? 0;
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
|
|
// ^
|
|
// [cfe] An operator can't have optional parameters.
|
|
}
|
|
|
|
enum DeclareSetterOptional {
|
|
e1;
|
|
void set foo([int? x]) {}
|
|
// ^^^
|
|
// [analyzer] SYNTACTIC_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
|
|
// ^
|
|
// [cfe] A setter should have exactly one formal parameter.
|
|
}
|
|
|
|
// "The identifier of a named constructor cannot be the same as
|
|
// the basename of a static member declared in the same class"
|
|
|
|
enum ConflictConstructorNameStatic {
|
|
e1.foo();
|
|
const ConflictConstructorNameStatic.foo();
|
|
// ^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_CONSTRUCTOR_AND_STATIC_MEMBER
|
|
static int get foo => 42;
|
|
// ^
|
|
// [cfe] The member conflicts with constructor 'ConflictConstructorNameStatic.foo'.
|
|
}
|
|
|
|
enum ConflictConstructorNameStaticEnumValue {
|
|
e1.e1();
|
|
const ConflictConstructorNameStaticEnumValue.e1();
|
|
// ^
|
|
// [cfe] The constructor conflicts with member 'e1'.
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_CONSTRUCTOR_AND_STATIC_MEMBER
|
|
}
|
|
|
|
// "It is an error if a member has the same name as its enclosing class"
|
|
|
|
enum ConflictClassStatic {
|
|
e1;
|
|
//^
|
|
// [cfe] A const constructor can't have a body.
|
|
static int ConflictClassStatic() => 37;
|
|
//^^^^^^
|
|
// [analyzer] SYNTACTIC_ERROR.STATIC_CONSTRUCTOR
|
|
// [cfe] Constructors can't be static.
|
|
// ^^^
|
|
// [analyzer] SYNTACTIC_ERROR.CONSTRUCTOR_WITH_RETURN_TYPE
|
|
// [cfe] Constructors can't have a return type.
|
|
// ^^
|
|
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
|
|
// [cfe] A generative enum constructor can't have a body.
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.RETURN_OF_INVALID_TYPE
|
|
// [cfe] Constructors can't have a return type.
|
|
}
|
|
|
|
enum ConflictClassInstance {
|
|
e1;
|
|
//^
|
|
// [cfe] A const constructor can't have a body.
|
|
int ConflictClassInstance() => 37;
|
|
//^^^
|
|
// [analyzer] SYNTACTIC_ERROR.CONSTRUCTOR_WITH_RETURN_TYPE
|
|
// [cfe] Constructors can't have a return type.
|
|
// ^^
|
|
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
|
|
// [cfe] A generative enum constructor can't have a body.
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.RETURN_OF_INVALID_TYPE
|
|
// [cfe] Constructors can't have a return type.
|
|
}
|
|
|
|
enum ConflictClassEnumValue {
|
|
ConflictClassEnumValue;
|
|
//^^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING
|
|
// [cfe] A class member can't have the same name as the enclosing class.
|
|
// [cfe] Couldn't find constructor 'ConflictClassEnumValue'.
|
|
}
|
|
|
|
// Has conflict with implicitly inserted `values` member.
|
|
enum values {
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ENUM_WITH_NAME_VALUES
|
|
// [cfe] The name 'values' is not a valid name for an enum. Try using a different name.
|
|
e1;
|
|
// [error column 3]
|
|
// [cfe] Couldn't find constructor 'values'.
|
|
}
|
|
|
|
// "It is an error if a concrete class does not implement some member
|
|
// of its interface, and there is no non-trivial \code{noSuchMethod}"
|
|
|
|
enum UnimplementedInterface {
|
|
e1;
|
|
int foo();
|
|
//^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ENUM_WITH_ABSTRACT_MEMBER
|
|
// ^
|
|
// [cfe] Enums can't declare abstract members.
|
|
}
|
|
|
|
enum UnimplementedInterfaceInherited implements MethodFoo {
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER
|
|
// [cfe] The non-abstract class 'UnimplementedInterfaceInherited' is missing implementations for these members:
|
|
e1;
|
|
}
|
|
|
|
enum ImplementedInterface with MethodFoo {
|
|
e1;
|
|
int foo(); // Abstract members are allowed.
|
|
}
|
|
|
|
enum ImplementedInterfaceNSM {
|
|
e1;
|
|
int foo(); // Abstract members are allowed.
|
|
dynamic noSuchMethod(i) => 42;
|
|
}
|
|
|
|
// Primitive Equality/HashCode.
|
|
// Enums must not override `==` or `hashCode`.
|
|
|
|
enum OverridesEquals {
|
|
e1;
|
|
|
|
bool operator==(Object other) => identical(e1, other);
|
|
// ^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ILLEGAL_CONCRETE_ENUM_MEMBER
|
|
// [cfe] An enum can't declare a non-abstract member named '=='.
|
|
}
|
|
|
|
enum OverridesHashCode {
|
|
e1;
|
|
|
|
int get hashCode => 42;
|
|
// ^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ILLEGAL_CONCRETE_ENUM_MEMBER
|
|
// [cfe] An enum can't declare a non-abstract member named 'hashCode'.
|
|
}
|
|
|
|
// Invalid syntax that the compiled *should* recover from.
|
|
abstract enum CannotBeAbstract {
|
|
// [error column 1, length 8]
|
|
// [analyzer] SYNTACTIC_ERROR.EXTRANEOUS_MODIFIER
|
|
// [cfe] Can't have modifier 'abstract' here.
|
|
e1;
|
|
}
|
|
|
|
// Cannot reference generative constructors of enum classes.
|
|
// Never allowed to reference by ClassName[.name],
|
|
// only implicitly in value declarations and `this`[.name] in
|
|
// redirecting generative constructors.
|
|
// All ClassName[.name] references are errors.
|
|
enum NoConstructorCalls {
|
|
e1(42),
|
|
e2.ignore(NoConstructorCalls(1)),
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// [cfe] Enums can't be instantiated.
|
|
;
|
|
|
|
final int x;
|
|
|
|
const NoConstructorCalls(this.x);
|
|
const NoConstructorCalls.ignore(dynamic _) : x = 0;
|
|
|
|
// Only valid use, as target of redirecting generative constructor.
|
|
const NoConstructorCalls.redirect() : this(1);
|
|
const NoConstructorCalls.redirectNamed() : this.ignore(0);
|
|
|
|
const NoConstructorCalls.invalidRedirect()
|
|
: this.ignore(NoConstructorCalls(1));
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// ^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
|
// [cfe] Enums can't be instantiated.
|
|
|
|
// Generative constructors are implicitly const.
|
|
NoConstructorCalls.notConst(this.x);
|
|
|
|
// As usual, redirecting generative constructors must redirect to
|
|
// generative constructors.
|
|
const NoConstructorCalls.badRedirect() : this.factory();
|
|
// ^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR
|
|
// ^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_NON_CONST_CONSTRUCTOR
|
|
// [cfe] Generative constructors can't redirect to a factory constructor.
|
|
|
|
factory NoConstructorCalls.factory() => e1; // Valid.
|
|
|
|
// Cannot reference generative constructors from factory constructors.
|
|
factory NoConstructorCalls.badFactory() => NoConstructorCalls(2);
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// [cfe] Enums can't be instantiated.
|
|
|
|
factory NoConstructorCalls.badFactoryRedirect(int x) = NoConstructorCalls;
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// [cfe] Enum factory constructors can't redirect to generative constructors.
|
|
|
|
static const NoConstructorCalls e3 = NoConstructorCalls(3);
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// [cfe] Enums can't be instantiated.
|
|
|
|
static void uses() {
|
|
Function f = NoConstructorCalls.new; // No tearoffs.
|
|
// ^^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// ^
|
|
// [cfe] Enum constructors can't be torn off.
|
|
|
|
Function g = NoConstructorCalls.ignore; // No tearoffs.
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// ^
|
|
// [cfe] Enum constructors can't be torn off.
|
|
|
|
const c1 = NoConstructorCalls(0);
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// [cfe] Enums can't be instantiated.
|
|
|
|
var v1 = new NoConstructorCalls(0);
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_REFERENCE_TO_GENERATIVE_ENUM_CONSTRUCTOR
|
|
// [cfe] Enums can't be instantiated.
|
|
}
|
|
}
|
|
|
|
enum DeclaresInstanceValues {
|
|
e1;
|
|
int get values => 42;
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.VALUES_DECLARATION_IN_ENUM
|
|
// [cfe] An enum can't declare a member named 'values'.
|
|
}
|
|
|
|
enum DeclaresStaticValues {
|
|
e1;
|
|
static int get values => 42;
|
|
// ^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.VALUES_DECLARATION_IN_ENUM
|
|
// [cfe] An enum can't declare a member named 'values'.
|
|
}
|
|
|
|
enum InheritsValues with ValuesGetter {
|
|
// ^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ILLEGAL_ENUM_VALUES
|
|
// [cfe] An enum can't inherit a member named 'values'.
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
e1;
|
|
}
|
|
|
|
enum ImplementsValues implements ValuesGetter {
|
|
// ^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ILLEGAL_ENUM_VALUES
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
e1;
|
|
|
|
noSuchMethod(i) => 42;
|
|
}
|
|
|
|
enum DeclaresInstanceIndex {
|
|
e1;
|
|
int get index => 42;
|
|
// ^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ILLEGAL_CONCRETE_ENUM_MEMBER
|
|
// [cfe] An enum can't declare a non-abstract member named 'index'.
|
|
}
|
|
|
|
enum DeclaresStaticIndex {
|
|
e1;
|
|
static int get index => 42; // Conflicts with inherited instance member.
|
|
// ^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
|
|
// [cfe] An enum can't declare a non-abstract member named 'index'.
|
|
// [cfe] Can't declare a member that conflicts with an inherited one.
|
|
}
|
|
|
|
enum InheritsIndex with IndexGetter {
|
|
// ^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ILLEGAL_CONCRETE_ENUM_MEMBER
|
|
// [cfe] An enum can't inherit a member named 'index'.
|
|
e1;
|
|
}
|
|
|
|
// No problem, implementation is not overridden.
|
|
enum ImplementsIndex implements IndexGetter {
|
|
e1;
|
|
}
|
|
|
|
enum DeclaresNeverIndex {
|
|
// ^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_IMPLEMENTATION_OVERRIDE
|
|
// [cfe] The implementation of 'index' in the non-abstract class 'DeclaresNeverIndex' does not conform to its interface.
|
|
e1;
|
|
|
|
Never get index;
|
|
}
|
|
|
|
enum ImplementsNeverIndex {
|
|
e1;
|
|
|
|
Never get index => throw "Never!";
|
|
// ^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.ILLEGAL_CONCRETE_ENUM_MEMBER
|
|
// [cfe] An enum can't declare a non-abstract member named 'index'.
|
|
}
|
|
|
|
enum NSMImplementsNeverIndex implements NeverIndexGetter {
|
|
// ^^^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.INVALID_IMPLEMENTATION_OVERRIDE
|
|
// [cfe] The implementation of 'index' in the non-abstract class 'NSMImplementsNeverIndex' does not conform to its interface.
|
|
e1;
|
|
|
|
noSuchMethod(i) => throw "Never!";
|
|
}
|
|
|
|
// Cannot have cyclic references between constants.
|
|
enum CyclicReference {
|
|
e1(e2),
|
|
//^^
|
|
// [analyzer] COMPILE_TIME_ERROR.RECURSIVE_COMPILE_TIME_CONSTANT
|
|
// [cfe] Can't infer the type of 'e1': circularity found during type inference.
|
|
// [cfe] Constant evaluation error:
|
|
e2(e1);
|
|
//^^
|
|
// [analyzer] COMPILE_TIME_ERROR.RECURSIVE_COMPILE_TIME_CONSTANT
|
|
final CyclicReference other;
|
|
const CyclicReference(this.other);
|
|
}
|
|
|
|
// Since `values` contains `e1`,
|
|
// we can't have a reference in the other direction.
|
|
enum CyclicReferenceValues {
|
|
e1(values);
|
|
//^^
|
|
// [analyzer] COMPILE_TIME_ERROR.RECURSIVE_COMPILE_TIME_CONSTANT
|
|
// [cfe] Constant evaluation error:
|
|
final List<CyclicReferenceValues> list;
|
|
const CyclicReferenceValues(this.list);
|
|
}
|
|
|
|
void main() {}
|