Add specialized messages for conflicting type parameters in mixins

Change-Id: I8d858226b2c93c15c3bf7610980672b064b40167
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/202640
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Brian Wilkerson 2021-06-06 21:51:11 +00:00 committed by commit-bot@chromium.org
parent 7d2ffd78de
commit 01fb0a6e22
6 changed files with 153 additions and 63 deletions

View file

@ -105,6 +105,8 @@ const List<ErrorCode> errorCodeValues = [
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION,
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS,
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN,
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MIXIN,
CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION,

View file

@ -1770,6 +1770,19 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS',
);
/**
* Parameters:
* 0: the name of the type variable
*/
static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN =
CompileTimeErrorCode(
'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
"'{0}' can't be used to name both a type variable and a member in "
"this mixin.",
correction: "Try renaming either the type variable or the member.",
uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN',
);
/**
* It is a compile time error if a generic extension declares a member with
* the same basename as the name of any of the extension's type parameters.
@ -1783,6 +1796,19 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION',
);
/**
* Parameters:
* 0: the name of the type variable
*/
static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MIXIN =
CompileTimeErrorCode(
'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER',
"'{0}' can't be used to name both a type variable and the mixin in "
"which the type variable is defined.",
correction: "Try renaming either the type variable or the mixin.",
uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MIXIN',
);
/**
* 16.12.2 Const: It is a compile-time error if evaluation of a constant
* object results in an uncaught exception being thrown.

View file

@ -1768,28 +1768,25 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
/// Verify all conflicts between type variable and enclosing class.
/// TODO(scheglov)
///
/// See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and
/// [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER].
void _checkForConflictingClassTypeVariableErrorCodes() {
for (TypeParameterElement typeParameter
in _enclosingClass!.typeParameters) {
String name = typeParameter.name;
// name is same as the name of the enclosing class
if (_enclosingClass!.name == name) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
typeParameter,
[name]);
var code = _enclosingClass!.isMixin
? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MIXIN
: CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS;
errorReporter.reportErrorForElement(code, typeParameter, [name]);
}
// check members
if (_enclosingClass!.getMethod(name) != null ||
_enclosingClass!.getGetter(name) != null ||
_enclosingClass!.getSetter(name) != null) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS,
typeParameter,
[name]);
var code = _enclosingClass!.isMixin
? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN
: CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS;
errorReporter.reportErrorForElement(code, typeParameter, [name]);
}
}
}

View file

@ -235,7 +235,7 @@ class D = Object with M2;
await assertErrorsInCode(r'''
mixin M<M> {}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, 8, 1),
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MIXIN, 8, 1),
]);
}
@ -245,7 +245,7 @@ mixin M<T> {
var T;
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS, 8,
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
@ -256,7 +256,7 @@ mixin M<T> {
get T => null;
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS, 8,
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
@ -267,7 +267,7 @@ mixin M<T> {
T() {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS, 8,
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
@ -278,7 +278,7 @@ mixin M<T> {
static T() {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS, 8,
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
@ -289,7 +289,7 @@ mixin M<T> {
void set T(_) {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS, 8,
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}

View file

@ -11,6 +11,7 @@ main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConflictingTypeVariableAndClassTest);
defineReflectiveTests(ConflictingTypeVariableAndExtensionTest);
defineReflectiveTests(ConflictingTypeVariableAndMixinTest);
});
}
@ -19,14 +20,6 @@ class ConflictingTypeVariableAndClassTest extends PubPackageResolutionTest {
test_conflict_on_class() async {
await assertErrorsInCode(r'''
class T<T> {}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, 8, 1),
]);
}
test_conflict_on_mixin() async {
await assertErrorsInCode(r'''
mixin T<T> {}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, 8, 1),
]);
@ -44,3 +37,14 @@ extension T<T> on String {}
]);
}
}
@reflectiveTest
class ConflictingTypeVariableAndMixinTest extends PubPackageResolutionTest {
test_conflict_on_mixin() async {
await assertErrorsInCode(r'''
mixin T<T> {}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MIXIN, 8, 1),
]);
}
}

View file

@ -9,50 +9,15 @@ import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ConflictingTypeVariableAndMemberClassTest);
defineReflectiveTests(ConflictingTypeVariableAndMemberExtensionTest);
defineReflectiveTests(ConflictingTypeVariableAndMemberTest);
defineReflectiveTests(ConflictingTypeVariableAndMemberMixinTest);
});
}
@reflectiveTest
class ConflictingTypeVariableAndMemberExtensionTest
class ConflictingTypeVariableAndMemberClassTest
extends PubPackageResolutionTest {
test_getter() async {
await assertErrorsInCode(r'''
extension A<T> on String {
get T => null;
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
12, 1),
]);
}
test_method() async {
await assertErrorsInCode(r'''
extension A<T> on String {
T() {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
12, 1),
]);
}
test_setter() async {
await assertErrorsInCode(r'''
extension A<T> on String {
set T(x) {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
12, 1),
]);
}
}
@reflectiveTest
class ConflictingTypeVariableAndMemberTest extends PubPackageResolutionTest {
test_field() async {
await assertErrorsInCode(r'''
class A<T> {
@ -108,3 +73,99 @@ class A<T> {
]);
}
}
@reflectiveTest
class ConflictingTypeVariableAndMemberExtensionTest
extends PubPackageResolutionTest {
test_getter() async {
await assertErrorsInCode(r'''
extension A<T> on String {
get T => null;
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
12, 1),
]);
}
test_method() async {
await assertErrorsInCode(r'''
extension A<T> on String {
T() {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
12, 1),
]);
}
test_setter() async {
await assertErrorsInCode(r'''
extension A<T> on String {
set T(x) {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
12, 1),
]);
}
}
@reflectiveTest
class ConflictingTypeVariableAndMemberMixinTest
extends PubPackageResolutionTest {
test_field() async {
await assertErrorsInCode(r'''
mixin M<T> {
var T;
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
test_getter() async {
await assertErrorsInCode(r'''
mixin M<T> {
get T => null;
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
test_method() async {
await assertErrorsInCode(r'''
mixin M<T> {
T() {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
test_method_static() async {
await assertErrorsInCode(r'''
mixin M<T> {
static T() {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
test_setter() async {
await assertErrorsInCode(r'''
mixin M<T> {
set T(x) {}
}
''', [
error(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN, 8,
1),
]);
}
}