Report WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM and TYPE_ARGUMENT_NOT_MATCHING_BOUNDS for enums.
Change-Id: Icac828fa09d7565974727521c27b5cd4daa7e0f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232089
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index b234142..c43d2d6 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -486,6 +486,7 @@
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION,
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+ CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM,
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION,
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION,
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 9758ede..16f20e9 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -15895,6 +15895,19 @@
/**
* Parameters:
+ * 0: the number of type parameters that were declared
+ * 1: the number of type arguments provided
+ */
+ static const CompileTimeErrorCode WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM =
+ CompileTimeErrorCode(
+ 'WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM',
+ "The enum is declared with {0} type parameters, but {1} type arguments "
+ "were given.",
+ correctionMessage: "Try adjusting the number of type arguments.",
+ );
+
+ /**
+ * Parameters:
* 0: the name of the extension being referenced
* 1: the number of type parameters that were declared
* 2: the number of type arguments provided
diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
index 1488253..db01b0b 100644
--- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
+++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart
@@ -91,6 +91,55 @@
}
}
+ void checkEnumConstantDeclaration(EnumConstantDeclaration node) {
+ var constructorElement = node.constructorElement;
+ if (constructorElement == null) {
+ return;
+ }
+
+ var enumElement = constructorElement.enclosingElement;
+ var typeParameters = enumElement.typeParameters;
+
+ var typeArgumentList = node.arguments?.typeArguments;
+ var typeArgumentNodes = typeArgumentList?.arguments;
+ if (typeArgumentList != null &&
+ typeArgumentNodes != null &&
+ typeArgumentNodes.length != typeParameters.length) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM,
+ typeArgumentList,
+ [typeParameters.length, typeArgumentNodes.length],
+ );
+ }
+
+ if (typeParameters.isEmpty) {
+ return;
+ }
+
+ // Check that type arguments are regular-bounded.
+ var typeArguments = constructorElement.returnType.typeArguments;
+ var substitution = Substitution.fromPairs(typeParameters, typeArguments);
+ for (var i = 0; i < typeArguments.length; i++) {
+ var typeParameter = typeParameters[i];
+ var typeArgument = typeArguments[i];
+
+ var bound = typeParameter.bound;
+ if (bound == null) {
+ continue;
+ }
+
+ bound = substitution.substituteType(bound);
+
+ if (!_typeSystem.isSubtypeOf(typeArgument, bound)) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+ typeArgumentNodes?[i] ?? node.name,
+ [typeArgument, typeParameter.name, bound],
+ );
+ }
+ }
+ }
+
void checkFunctionExpressionInvocation(FunctionExpressionInvocation node) {
_checkInvocationTypeArguments(
node.typeArguments?.arguments,
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 36d3095..1acd7b1 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -560,6 +560,7 @@
@override
void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
_requiredParametersVerifier.visitEnumConstantDeclaration(node);
+ _typeArgumentsVerifier.checkEnumConstantDeclaration(node);
super.visitEnumConstantDeclaration(node);
}
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 8682035..3c90ccd 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -13632,6 +13632,13 @@
}
C f() => C.named();
```
+ WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM:
+ problemMessage: The enum is declared with {0} type parameters, but {1} type arguments were given.
+ correctionMessage: Try adjusting the number of type arguments.
+ comment: |-
+ Parameters:
+ 0: the number of type parameters that were declared
+ 1: the number of type arguments provided
WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION:
problemMessage: "The extension '{0}' is declared with {1} type parameters, but {2} type arguments were given."
correctionMessage: Try adjusting the number of type arguments.
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 3fddbed..a98026b 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -776,6 +776,8 @@
as wrong_number_of_parameters_for_operator;
import 'wrong_number_of_parameters_for_setter_test.dart'
as wrong_number_of_parameters_for_setter;
+import 'wrong_number_of_type_arguments_enum_test.dart'
+ as wrong_number_of_type_arguments_enum;
import 'wrong_number_of_type_arguments_extension_test.dart'
as wrong_number_of_type_arguments_extension;
import 'wrong_number_of_type_arguments_test.dart'
@@ -1306,6 +1308,7 @@
void_with_type_arguments_test.main();
wrong_number_of_parameters_for_operator.main();
wrong_number_of_parameters_for_setter.main();
+ wrong_number_of_type_arguments_enum.main();
wrong_number_of_type_arguments_extension.main();
wrong_number_of_type_arguments.main();
wrong_type_parameter_variance_in_superinterface.main();
diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
index 3149899..2aea194 100644
--- a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
@@ -431,6 +431,35 @@
class TypeArgumentNotMatchingBoundsWithNullSafetyTest
extends PubPackageResolutionTest
with TypeArgumentNotMatchingBoundsTestCases {
+ test_enum_inferred() async {
+ await assertErrorsInCode('''
+enum E<T extends int> {
+ v('');
+ const E(T t);
+}
+''', [
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 26, 1),
+ ]);
+ }
+
+ test_enum_superBounded() async {
+ await assertNoErrorsInCode('''
+enum E<T extends E<T>> {
+ v<Never>()
+}
+''');
+ }
+
+ test_enum_withTypeArguments() async {
+ await assertErrorsInCode('''
+enum E<T extends int> {
+ v<String>()
+}
+''', [
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 28, 6),
+ ]);
+ }
+
test_extends_optIn_fromOptOut_Null() async {
newFile('$testPackageLibPath/a.dart', content: r'''
class A<X extends int> {}
diff --git a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_enum_test.dart b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_enum_test.dart
new file mode 100644
index 0000000..60e12c9
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_enum_test.dart
@@ -0,0 +1,37 @@
+// 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(WrongNumberOfTypeArgumentsEnumTest);
+ });
+}
+
+@reflectiveTest
+class WrongNumberOfTypeArgumentsEnumTest extends PubPackageResolutionTest {
+ test_tooFew() async {
+ await assertErrorsInCode(r'''
+enum E<T, U> {
+ v<int>()
+}
+''', [
+ error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM, 18, 5),
+ ]);
+ }
+
+ test_tooMany() async {
+ await assertErrorsInCode(r'''
+enum E<T> {
+ v<int, int>()
+}
+''', [
+ error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ENUM, 15, 10),
+ ]);
+ }
+}