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>
This commit is contained in:
Konstantin Shcheglov
2022-02-08 19:50:36 +00:00
committed by Commit Bot
parent 10bcd86677
commit d8e2cdaeec
8 changed files with 140 additions and 0 deletions
+1
View File
@@ -486,6 +486,7 @@ const List<ErrorCode> errorCodeValues = [
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,
+13
View File
@@ -15893,6 +15893,19 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
hasPublishedDocs: true,
);
/**
* 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
@@ -91,6 +91,55 @@ class TypeArgumentsVerifier {
}
}
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,
@@ -560,6 +560,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
@override
void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
_requiredParametersVerifier.visitEnumConstantDeclaration(node);
_typeArgumentsVerifier.checkEnumConstantDeclaration(node);
super.visitEnumConstantDeclaration(node);
}
+7
View File
@@ -13632,6 +13632,13 @@ CompileTimeErrorCode:
}
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.
@@ -776,6 +776,8 @@ import 'wrong_number_of_parameters_for_operator_test.dart'
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 @@ main() {
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();
@@ -431,6 +431,35 @@ class C extends Object with G<B>{}
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> {}
@@ -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),
]);
}
}