Version 2.17.0-93.0.dev
Merge commit 'f481cbf2fa27ca7d72ababdccc561b4465bd1660' into 'dev'
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index c43d2d6..018dbbb 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -162,6 +162,7 @@
CompileTimeErrorCode.DUPLICATE_PART,
CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
CompileTimeErrorCode.ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR,
+ CompileTimeErrorCode.ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED,
CompileTimeErrorCode.ENUM_MIXIN_WITH_INSTANCE_VARIABLE,
CompileTimeErrorCode.ENUM_WITH_ABSTRACT_MEMBER,
CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET,
@@ -478,6 +479,7 @@
CompileTimeErrorCode.URI_WITH_INTERPOLATION,
CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
CompileTimeErrorCode.USE_OF_VOID_RESULT,
+ CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM,
CompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
CompileTimeErrorCode.WRONG_EXPLICIT_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR,
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 8dc00f0..b703443 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -644,7 +644,7 @@
}
@override
- visitEnumConstantDeclaration(node) {
+ void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
var constructorElement = node.constructorElement;
if (constructorElement != null) {
int offset;
@@ -657,8 +657,15 @@
offset = node.name.end;
length = 0;
}
- recordRelationOffset(constructorElement, IndexRelationKind.IS_INVOKED_BY,
- offset, length, true);
+ recordRelationOffset(
+ constructorElement,
+ node.arguments == null
+ ? IndexRelationKind.IS_INVOKED_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS
+ : IndexRelationKind.IS_INVOKED_BY,
+ offset,
+ length,
+ true,
+ );
}
super.visitEnumConstantDeclaration(node);
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 834d75a..d188c60 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -3699,6 +3699,8 @@
var parent = child.parent;
if (parent is ConstantContextForExpressionImpl) {
return true;
+ } else if (parent is EnumConstantArguments) {
+ return true;
} else if (parent is TypedLiteralImpl && parent.constKeyword != null) {
// Inside an explicitly `const` list or map literal.
return true;
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 9af29c4..a6b2bef 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -120,6 +120,16 @@
}
@override
+ visitEnumConstantDeclaration(node) {
+ super.visitEnumConstantDeclaration(node);
+
+ var argumentList = node.arguments?.argumentList;
+ if (argumentList != null) {
+ _validateConstantArguments(argumentList);
+ }
+ }
+
+ @override
void visitFunctionExpression(FunctionExpression node) {
super.visitFunctionExpression(node);
_validateDefaultValues(node.parameters);
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index b38a654..f12c602 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -30,6 +30,7 @@
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:analyzer/src/dart/element/type_schema_elimination.dart';
+import 'package:analyzer/src/dart/element/well_bounded.dart';
/// The [TypeSystem] implementation.
class TypeSystemImpl implements TypeSystem {
@@ -1178,6 +1179,17 @@
return false;
}
+ /// See `15.2 Super-bounded types` in the language specification.
+ TypeBoundedResult isWellBounded(
+ DartType type, {
+ required bool allowSuperBounded,
+ }) {
+ return TypeBoundedHelper(this).isWellBounded(
+ type,
+ allowSuperBounded: allowSuperBounded,
+ );
+ }
+
/// Returns the least closure of [type] with respect to [typeParameters].
///
/// https://github.com/dart-lang/language
diff --git a/pkg/analyzer/lib/src/dart/element/well_bounded.dart b/pkg/analyzer/lib/src/dart/element/well_bounded.dart
new file mode 100644
index 0000000..35185ec
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/well_bounded.dart
@@ -0,0 +1,138 @@
+// 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/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_system.dart';
+
+class NotWellBoundedTypeResult implements TypeBoundedResult {
+ final String elementName;
+ final List<TypeArgumentIssue> issues;
+
+ NotWellBoundedTypeResult._({
+ required this.elementName,
+ required this.issues,
+ });
+}
+
+class RegularBoundedTypeResult implements WellBoundedTypeResult {
+ const RegularBoundedTypeResult._();
+}
+
+class SuperBoundedTypeResult implements WellBoundedTypeResult {
+ const SuperBoundedTypeResult._();
+}
+
+class TypeArgumentIssue {
+ /// The index for type argument within the passed type arguments.
+ final int index;
+
+ /// The type parameter with the bound that was violated.
+ final TypeParameterElement parameter;
+
+ /// The substituted bound of the [parameter].
+ final DartType parameterBound;
+
+ /// The type argument that violated the [parameterBound].
+ final DartType argument;
+
+ TypeArgumentIssue(
+ this.index,
+ this.parameter,
+ this.parameterBound,
+ this.argument,
+ );
+
+ @override
+ String toString() {
+ return 'TypeArgumentIssue(index=$index, parameter=$parameter, '
+ 'parameterBound=$parameterBound, argument=$argument)';
+ }
+}
+
+/// Helper for checking whether a type if well-bounded.
+///
+/// See `15.2 Super-bounded types` in the language specification.
+class TypeBoundedHelper {
+ final TypeSystemImpl typeSystem;
+
+ TypeBoundedHelper(this.typeSystem);
+
+ TypeBoundedResult isWellBounded(
+ DartType type, {
+ required bool allowSuperBounded,
+ }) {
+ var result = _isRegularBounded(type);
+ if (!allowSuperBounded) {
+ return result;
+ }
+
+ return _isSuperBounded(type);
+ }
+
+ TypeBoundedResult _isRegularBounded(DartType type) {
+ List<TypeArgumentIssue>? issues;
+
+ final String elementName;
+ final List<TypeParameterElement> typeParameters;
+ final List<DartType> typeArguments;
+ final alias = type.alias;
+ if (alias != null) {
+ elementName = alias.element.name;
+ typeParameters = alias.element.typeParameters;
+ typeArguments = alias.typeArguments;
+ } else if (type is InterfaceType) {
+ elementName = type.element.name;
+ typeParameters = type.element.typeParameters;
+ typeArguments = type.typeArguments;
+ } else {
+ return const RegularBoundedTypeResult._();
+ }
+
+ final substitution = Substitution.fromPairs(typeParameters, typeArguments);
+ for (var i = 0; i < typeParameters.length; i++) {
+ var typeParameter = typeParameters[i];
+ var typeArgument = typeArguments[i];
+
+ var bound = typeParameter.bound;
+ if (bound == null) {
+ continue;
+ }
+
+ bound = typeSystem.toLegacyType(bound);
+ bound = substitution.substituteType(bound);
+
+ if (!typeSystem.isSubtypeOf(typeArgument, bound)) {
+ issues ??= <TypeArgumentIssue>[];
+ issues.add(
+ TypeArgumentIssue(i, typeParameter, bound, typeArgument),
+ );
+ }
+ }
+
+ if (issues == null) {
+ return const RegularBoundedTypeResult._();
+ } else {
+ return NotWellBoundedTypeResult._(
+ elementName: elementName,
+ issues: issues,
+ );
+ }
+ }
+
+ TypeBoundedResult _isSuperBounded(DartType type) {
+ final invertedType = typeSystem.replaceTopAndBottom(type);
+ var result = _isRegularBounded(invertedType);
+ if (result is RegularBoundedTypeResult) {
+ return const SuperBoundedTypeResult._();
+ } else {
+ return result;
+ }
+ }
+}
+
+abstract class TypeBoundedResult {}
+
+class WellBoundedTypeResult implements TypeBoundedResult {}
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 16f20e9..2683b24 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -3671,6 +3671,13 @@
correctionMessage: "Try invoking a const generative constructor.",
);
+ static const CompileTimeErrorCode
+ ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED = CompileTimeErrorCode(
+ 'ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED',
+ "The result of instantiating the enum to bounds is not well-bounded.",
+ correctionMessage: "Try using different bounds for type parameters.",
+ );
+
static const CompileTimeErrorCode ENUM_MIXIN_WITH_INSTANCE_VARIABLE =
CompileTimeErrorCode(
'ENUM_MIXIN_WITH_INSTANCE_VARIABLE',
@@ -15583,6 +15590,13 @@
hasPublishedDocs: true,
);
+ static const CompileTimeErrorCode VALUES_DECLARATION_IN_ENUM =
+ CompileTimeErrorCode(
+ 'VALUES_DECLARATION_IN_ENUM',
+ "A member named 'values' can't be declared in an enum.",
+ correctionMessage: "Try using a different name.",
+ );
+
/**
* Parameters:
* 0: the type of the object being assigned.
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index ed4297e..38fc6db 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -53,13 +53,9 @@
var staticGetters = <String, Element>{};
var staticSetters = <String, Element>{};
- var valuesField = enumElement.valuesField;
- if (valuesField != null) {
- staticGetters['values'] = valuesField;
- }
-
for (EnumConstantDeclaration constant in node.constants) {
_checkDuplicateIdentifier(staticGetters, constant.name);
+ _checkValuesDeclarationInEnum(constant.name);
}
for (var member in node.members) {
@@ -89,6 +85,7 @@
identifier,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
+ _checkValuesDeclarationInEnum(identifier);
}
} else if (member is MethodDeclaration) {
_checkDuplicateIdentifier(
@@ -96,6 +93,7 @@
member.name,
setterScope: member.isStatic ? staticSetters : instanceSetters,
);
+ _checkValuesDeclarationInEnum(member.name);
}
}
@@ -514,6 +512,15 @@
}
}
+ void _checkValuesDeclarationInEnum(SimpleIdentifier name) {
+ if (name.name == 'values') {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM,
+ name,
+ );
+ }
+ }
+
ExecutableElement? _getInheritedMember(
ClassElement element, String baseName) {
var libraryUri = _currentLibrary.source.uri;
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index d78da68..e7d450e 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -197,9 +197,11 @@
var fieldElement = field.declaredElement as FieldElement;
_checkDeclaredMember(field.name, libraryUri, fieldElement.getter);
_checkDeclaredMember(field.name, libraryUri, fieldElement.setter);
+ if (!member.isStatic && !classElement.isEnum) {
+ _checkIllegalEnumValuesDeclaration(field.name);
+ }
if (!member.isStatic) {
_checkIllegalNonAbstractEnumIndex(field.name);
- _checkIllegalEnumValuesDeclaration(field.name);
}
}
} else if (member is MethodDeclaration) {
@@ -210,7 +212,7 @@
_checkDeclaredMember(member.name, libraryUri, member.declaredElement,
methodParameterNodes: member.parameters?.parameters);
- if (!member.isStatic) {
+ if (!member.isStatic && !classElement.isEnum) {
_checkIllegalEnumValuesDeclaration(member.name);
}
if (!(member.isStatic || member.isAbstract || member.isSetter)) {
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 2cc6b50..4b746e6 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -26,6 +26,7 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/element/well_bounded.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
@@ -582,12 +583,11 @@
_checkClassInheritance(node, null, withClause, implementsClause);
}
- // TODO(scheglov) implement
- // _checkForConflictingClassMembers();
_constructorFieldsVerifier.enterEnum(node);
_checkForFinalNotInitializedInClass(node.members);
_checkForWrongTypeParameterVarianceInSuperinterfaces();
_checkForMainFunction(node.name);
+ _checkForEnumInstantiatedToBoundsIsNotWellBounded(node, element);
super.visitEnumDeclaration(node);
} finally {
@@ -2463,6 +2463,25 @@
return true;
}
+ void _checkForEnumInstantiatedToBoundsIsNotWellBounded(
+ EnumDeclaration node,
+ EnumElementImpl element,
+ ) {
+ var valuesFieldType = element.valuesField?.type;
+ if (valuesFieldType is InterfaceType) {
+ var isWellBounded = typeSystem.isWellBounded(
+ valuesFieldType.typeArguments.single,
+ allowSuperBounded: true,
+ );
+ if (isWellBounded is NotWellBoundedTypeResult) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED,
+ node.name,
+ );
+ }
+ }
+ }
+
/// Check that if the visiting library is not system, then any given library
/// should not be SDK internal library. The [exportElement] is the
/// [ExportElement] retrieved from the node, if the element in the node was
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 44e5dc8..67e3358 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -68,6 +68,12 @@
/// Right: location.
IS_INVOKED_BY,
+ /// Left: an unnamed constructor.
+ /// Is invoked by an enum constant, without arguments, which is special
+ /// because when the name given, an empty argument list must be added.
+ /// Right: location.
+ IS_INVOKED_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS,
+
/// Left: any element.
/// Is referenced (and not invoked, read/written) at.
/// Right: location.
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index a17feaf..adb8e7d 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -496,6 +496,12 @@
/// Right: location.
IS_INVOKED_BY,
+ /// Left: an unnamed constructor.
+ /// Is invoked by an enum constant, without arguments, which is special
+ /// because when the name given, an empty argument list must be added.
+ /// Right: location.
+ IS_INVOKED_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS,
+
/// Left: any element.
/// Is referenced (and not invoked, read/written) at.
/// Right: location.
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 3c90ccd..a06b9d4 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -3354,6 +3354,9 @@
ENUM_CONSTANT_WITH_NON_CONST_CONSTRUCTOR:
problemMessage: The invoked constructor isn't a const constructor.
correctionMessage: Try invoking a const generative constructor.
+ ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED:
+ problemMessage: The result of instantiating the enum to bounds is not well-bounded.
+ correctionMessage: Try using different bounds for type parameters.
ENUM_MIXIN_WITH_INSTANCE_VARIABLE:
problemMessage: Mixins applied to enums can't have instance variables.
correctionMessage: Try replacing the instance variables with getters.
@@ -13377,6 +13380,9 @@
Either rewrite the code so that the expression has a value or rewrite the
code so that it doesn't depend on the value.
+ VALUES_DECLARATION_IN_ENUM:
+ problemMessage: A member named 'values' can't be declared in an enum.
+ correctionMessage: Try using a different name.
VARIABLE_TYPE_MISMATCH:
problemMessage: "A value of type '{0}' can't be assigned to a const variable of type '{1}'."
correctionMessage: "Try using a subtype, or removing the 'const' keyword"
diff --git a/pkg/analyzer/test/generated/parser_test_base.dart b/pkg/analyzer/test/generated/parser_test_base.dart
index 4c2d5a6..384a789 100644
--- a/pkg/analyzer/test/generated/parser_test_base.dart
+++ b/pkg/analyzer/test/generated/parser_test_base.dart
@@ -1170,7 +1170,13 @@
analyzer.Parser parser = analyzer.Parser(
source,
listener,
- featureSet: FeatureSet.latestLanguageVersion(),
+ featureSet: FeatureSet.fromEnableFlags2(
+ sdkLanguageVersion: ExperimentStatus.currentVersion,
+ flags: [
+ Feature.enhanced_enums.enableString,
+ Feature.super_parameters.enableString,
+ ],
+ ),
);
parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
CompilationUnit unit = parser.parseCompilationUnit(result.tokens);
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index d1bcdbf..215d184 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -459,7 +459,7 @@
enum E {
v;
int operator [](int index) => 0;
- operator []=(int index, int vlaue) {}
+ operator []=(int index, int value) {}
}
void f(E e) {
e[0];
@@ -952,18 +952,20 @@
/// [new E] 1
enum E {
v1, // 2
- v2.new(); // 3
+ v2(), // 3
+ v3.new(); // 4
E();
- E.other() : this(); // 4
+ E.other() : this(); // 5
}
''');
var element = findElement.unnamedConstructor('E');
assertThat(element)
- ..hasRelationCount(4)
+ ..hasRelationCount(5)
..isReferencedAt('] 1', true, length: 0)
- ..isInvokedAt(', // 2', true, length: 0)
- ..isInvokedAt('.new(); // 3', true, length: 4)
- ..isInvokedAt('(); // 4', true, length: 0);
+ ..isInvokedByEnumConstantWithoutArgumentsAt(', // 2', length: 0)
+ ..isInvokedAt('(), // 3', true, length: 0)
+ ..isInvokedAt('.new(); // 4', true, length: 4)
+ ..isInvokedAt('(); // 5', true, length: 0);
}
test_isReferencedBy_ConstructorElement_enum_unnamed_declared_new() async {
@@ -971,18 +973,20 @@
/// [new E] 1
enum E {
v1, // 2
- v2.new(); // 3
+ v2(), // 3
+ v3.new(); // 4
E.new() {}
- E.other() : this(); // 4
+ E.other() : this(); // 5
}
''');
var element = findElement.unnamedConstructor('E');
assertThat(element)
- ..hasRelationCount(4)
+ ..hasRelationCount(5)
..isReferencedAt('] 1', true, length: 0)
- ..isInvokedAt(', // 2', true, length: 0)
- ..isInvokedAt('.new(); // 3', true, length: 4)
- ..isInvokedAt('(); // 4', true, length: 0);
+ ..isInvokedByEnumConstantWithoutArgumentsAt(', // 2', length: 0)
+ ..isInvokedAt('(), // 3', true, length: 0)
+ ..isInvokedAt('.new(); // 4', true, length: 4)
+ ..isInvokedAt('(); // 5', true, length: 0);
}
test_isReferencedBy_ConstructorElement_enum_unnamed_synthetic() async {
@@ -990,15 +994,17 @@
/// [new E] 1
enum E {
v1, // 2
- v2.new(); // 3
+ v2(), // 3
+ v3.new(); // 4
}
''');
var element = findElement.unnamedConstructor('E');
assertThat(element)
- ..hasRelationCount(3)
+ ..hasRelationCount(4)
..isReferencedAt('] 1', true, length: 0)
- ..isInvokedAt(', // 2', true, length: 0)
- ..isInvokedAt('.new(); // 3', true, length: 4);
+ ..isInvokedByEnumConstantWithoutArgumentsAt(', // 2', length: 0)
+ ..isInvokedAt('(), // 3', true, length: 0)
+ ..isInvokedAt('.new(); // 4', true, length: 4);
}
test_isReferencedBy_DynamicElement() async {
@@ -1894,6 +1900,16 @@
test._expectedLocation(search, isQualified, length: length));
}
+ void isInvokedByEnumConstantWithoutArgumentsAt(String search,
+ {required int length}) {
+ test._assertHasRelation(
+ element,
+ relations,
+ IndexRelationKind.IS_INVOKED_BY_ENUM_CONSTANT_WITHOUT_ARGUMENTS,
+ test._expectedLocation(search, true, length: length),
+ );
+ }
+
void isMixedInAt(String search, bool isQualified, {int? length}) {
test._assertHasRelation(
element,
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index 84635ce..c388c0b 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -120,6 +120,16 @@
testUnit = parseCompilationUnit(source) as CompilationUnitImpl;
}
+ test_inConstantContext_enumConstant_true() {
+ parse('''
+enum E {
+ v([]);
+ const E(_);
+}
+''');
+ assertInContext('[]', true);
+ }
+
test_inConstantContext_instanceCreation_annotation_true() {
parse('''
@C(C(0))
diff --git a/pkg/analyzer/test/src/diagnostics/const_with_non_constant_argument_test.dart b/pkg/analyzer/test/src/diagnostics/const_with_non_constant_argument_test.dart
index e21d023..91e3a9e 100644
--- a/pkg/analyzer/test/src/diagnostics/const_with_non_constant_argument_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_with_non_constant_argument_test.dart
@@ -47,6 +47,28 @@
]);
}
+ test_enumConstant() async {
+ await assertErrorsInCode(r'''
+var a = 42;
+
+enum E {
+ v(a);
+ const E(_);
+}
+''', [
+ error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 26, 1),
+ ]);
+ }
+
+ test_enumConstant_constantContext() async {
+ await assertNoErrorsInCode(r'''
+enum E {
+ v([]);
+ const E(_);
+}
+''');
+ }
+
test_instanceCreation() async {
await assertErrorsInCode(r'''
class A {
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
index 517491f..57a6e98 100644
--- a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
@@ -339,16 +339,6 @@
]);
}
- test_constant_values() async {
- await assertErrorsInCode(r'''
-enum E {
- values
-}
-''', [
- error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 11, 6),
- ]);
- }
-
test_instance_field_field() async {
await assertErrorsInCode(r'''
enum E {
@@ -589,17 +579,6 @@
]);
}
- test_static_field_values() async {
- await assertErrorsInCode(r'''
-enum E {
- v;
- static int values = 0;
-}
-''', [
- error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 27, 6),
- ]);
- }
-
test_static_fieldFinal_getter() async {
await assertErrorsInCode(r'''
enum E {
diff --git a/pkg/analyzer/test/src/diagnostics/enum_instantiated_to_bounds_is_not_well_bounded_test.dart b/pkg/analyzer/test/src/diagnostics/enum_instantiated_to_bounds_is_not_well_bounded_test.dart
new file mode 100644
index 0000000..2a07dc5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/enum_instantiated_to_bounds_is_not_well_bounded_test.dart
@@ -0,0 +1,33 @@
+// 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 '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(EnumInstantiatedToBoundsIsNotWellBoundedTest);
+ });
+}
+
+@reflectiveTest
+class EnumInstantiatedToBoundsIsNotWellBoundedTest
+ extends PubPackageResolutionTest {
+ test_enum_it() async {
+ await assertErrorsInCode('''
+typedef A<X> = X Function(X);
+
+enum E<T extends A<T>, U> {
+ v<Never, int>()
+}
+''', [
+ error(
+ CompileTimeErrorCode.ENUM_INSTANTIATED_TO_BOUNDS_IS_NOT_WELL_BOUNDED,
+ 36,
+ 1),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/illegal_enum_values_declaration_test.dart b/pkg/analyzer/test/src/diagnostics/illegal_enum_values_declaration_test.dart
index 25014ed..c7e818f 100644
--- a/pkg/analyzer/test/src/diagnostics/illegal_enum_values_declaration_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/illegal_enum_values_declaration_test.dart
@@ -87,50 +87,6 @@
''');
}
- test_enum_field() async {
- await assertErrorsInCode(r'''
-enum E {
- v;
- int values = 0;
-}
-''', [
- error(CompileTimeErrorCode.ILLEGAL_ENUM_VALUES_DECLARATION, 20, 6),
- ]);
- }
-
- test_enum_getter() async {
- await assertErrorsInCode(r'''
-enum E {
- v;
- int get values => 0;
-}
-''', [
- error(CompileTimeErrorCode.ILLEGAL_ENUM_VALUES_DECLARATION, 24, 6),
- ]);
- }
-
- test_enum_method() async {
- await assertErrorsInCode(r'''
-enum E {
- v;
- void values() {}
-}
-''', [
- error(CompileTimeErrorCode.ILLEGAL_ENUM_VALUES_DECLARATION, 21, 6),
- ]);
- }
-
- test_enum_setter() async {
- await assertErrorsInCode(r'''
-enum E {
- v;
- set values(int _) {}
-}
-''', [
- error(CompileTimeErrorCode.ILLEGAL_ENUM_VALUES_DECLARATION, 20, 6),
- ]);
- }
-
test_mixin_field() async {
await assertErrorsInCode(r'''
mixin M on Enum {
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index a98026b..1a8c3b2 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -158,6 +158,8 @@
as enum_constant_same_name_as_enclosing;
import 'enum_constant_with_non_const_constructor_test.dart'
as enum_constant_with_non_const_constructor;
+import 'enum_instantiated_to_bounds_is_not_well_bounded_test.dart'
+ as enum_instantiated_to_bounds_is_not_well_bounded;
import 'enum_mixin_with_instance_variable_test.dart'
as enum_mixin_with_instance_variable;
import 'enum_with_abstract_member_test.dart' as enum_with_abstract_member;
@@ -770,6 +772,7 @@
import 'use_of_native_extension_test.dart' as use_of_native_extension;
import 'use_of_nullable_value_test.dart' as use_of_nullable_value_test;
import 'use_of_void_result_test.dart' as use_of_void_result;
+import 'values_declaration_in_enum_test.dart' as values_declaration_in_enum;
import 'variable_type_mismatch_test.dart' as variable_type_mismatch;
import 'void_with_type_arguments_test.dart' as void_with_type_arguments_test;
import 'wrong_number_of_parameters_for_operator_test.dart'
@@ -896,6 +899,7 @@
duplicate_shown_name.main();
enum_constant_same_name_as_enclosing.main();
enum_constant_with_non_const_constructor.main();
+ enum_instantiated_to_bounds_is_not_well_bounded.main();
enum_mixin_with_instance_variable.main();
enum_with_abstract_member.main();
equal_elements_in_const_set.main();
@@ -1304,6 +1308,7 @@
use_of_native_extension.main();
use_of_nullable_value_test.main();
use_of_void_result.main();
+ values_declaration_in_enum.main();
variable_type_mismatch.main();
void_with_type_arguments_test.main();
wrong_number_of_parameters_for_operator.main();
diff --git a/pkg/analyzer/test/src/diagnostics/values_declaration_in_enum_test.dart b/pkg/analyzer/test/src/diagnostics/values_declaration_in_enum_test.dart
new file mode 100644
index 0000000..e4f48df
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/values_declaration_in_enum_test.dart
@@ -0,0 +1,115 @@
+// 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 '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ValuesDeclarationInEnumTest);
+ });
+}
+
+@reflectiveTest
+class ValuesDeclarationInEnumTest extends PubPackageResolutionTest {
+ test_constant() async {
+ await assertErrorsInCode(r'''
+enum E {
+ values
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 11, 6),
+ ]);
+ }
+
+ test_field() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ int values = 0;
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 20, 6),
+ ]);
+ }
+
+ test_field_static() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ static int values = 0;
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 27, 6),
+ ]);
+ }
+
+ test_getter() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ int get values => 0;
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 24, 6),
+ ]);
+ }
+
+ test_getter_static() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ static int get values => 0;
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 31, 6),
+ ]);
+ }
+
+ test_method() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ void values() {}
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 21, 6),
+ ]);
+ }
+
+ test_method_static() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ static void values() {}
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 28, 6),
+ ]);
+ }
+
+ test_setter() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ set values(int _) {}
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 20, 6),
+ ]);
+ }
+
+ test_setter_static() async {
+ await assertErrorsInCode(r'''
+enum E {
+ v;
+ static set values(int _) {}
+}
+''', [
+ error(CompileTimeErrorCode.VALUES_DECLARATION_IN_ENUM, 27, 6),
+ ]);
+ }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 6eccc8d..00d1d49 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 92
+PRERELEASE 93
PRERELEASE_PATCH 0
\ No newline at end of file