mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:57:17 +00:00
Augment. Report INVALID_OVERRIDE using merged interfaces.
Change-Id: Id515aaf813b60ccbfc3d5fece1b728f1e909a261 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373762 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
b792a0c914
commit
aa8ea803cf
|
@ -196,10 +196,13 @@ class _ClassVerifier {
|
|||
return true;
|
||||
}
|
||||
|
||||
var classElement = this.classElement;
|
||||
if (classElement is! EnumElement &&
|
||||
classElement is ClassElement &&
|
||||
!classElement.isAbstract &&
|
||||
var fragment = classElement;
|
||||
var augmented = fragment.augmented;
|
||||
var declaration = augmented.declaration;
|
||||
|
||||
if (declaration is! EnumElement &&
|
||||
declaration is ClassElement &&
|
||||
!declaration.isAbstract &&
|
||||
implementsDartCoreEnum) {
|
||||
reporter.atToken(
|
||||
classNameToken,
|
||||
|
@ -208,23 +211,23 @@ class _ClassVerifier {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_checkForRecursiveInterfaceInheritance(classElement)) {
|
||||
if (_checkForRecursiveInterfaceInheritance(declaration)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compute the interface of the class.
|
||||
var interface = inheritance.getInterface(classElement);
|
||||
var interface = inheritance.getInterface(declaration);
|
||||
|
||||
// Report conflicts between direct superinterfaces of the class.
|
||||
for (var conflict in interface.conflicts) {
|
||||
_reportInconsistentInheritance(classNameToken, conflict);
|
||||
}
|
||||
|
||||
if (classElement.supertype != null) {
|
||||
directSuperInterfaces.add(classElement.supertype!);
|
||||
if (declaration.supertype != null) {
|
||||
directSuperInterfaces.add(declaration.supertype!);
|
||||
}
|
||||
if (classElement is MixinElement) {
|
||||
directSuperInterfaces.addAll(classElement.superclassConstraints);
|
||||
if (augmented is AugmentedMixinElement) {
|
||||
directSuperInterfaces.addAll(augmented.superclassConstraints);
|
||||
}
|
||||
|
||||
// Each mixin in `class C extends S with M0, M1, M2 {}` is equivalent to:
|
||||
|
@ -235,14 +238,14 @@ class _ClassVerifier {
|
|||
// So, we need to check members of each mixin against superinterfaces
|
||||
// of `S`, and superinterfaces of all previous mixins.
|
||||
var mixinNodes = withClause?.mixinTypes;
|
||||
var mixinTypes = classElement.mixins;
|
||||
var mixinTypes = declaration.mixins;
|
||||
for (var i = 0; i < mixinTypes.length; i++) {
|
||||
var mixinType = mixinTypes[i];
|
||||
_checkDeclaredMembers(mixinNodes![i], mixinType, mixinIndex: i);
|
||||
directSuperInterfaces.add(mixinType);
|
||||
}
|
||||
|
||||
directSuperInterfaces.addAll(classElement.interfaces);
|
||||
directSuperInterfaces.addAll(augmented.interfaces);
|
||||
|
||||
// Check the members of the class itself, against all the previously
|
||||
// collected superinterfaces of the supertype, mixins, and interfaces.
|
||||
|
@ -253,7 +256,7 @@ class _ClassVerifier {
|
|||
var fieldElement = field.declaredElement as FieldElement;
|
||||
_checkDeclaredMember(field.name, libraryUri, fieldElement.getter);
|
||||
_checkDeclaredMember(field.name, libraryUri, fieldElement.setter);
|
||||
if (!member.isStatic && classElement is! EnumElement) {
|
||||
if (!member.isStatic && declaration is! EnumElement) {
|
||||
_checkIllegalEnumValuesDeclaration(field.name);
|
||||
}
|
||||
if (!member.isStatic) {
|
||||
|
@ -271,7 +274,7 @@ class _ClassVerifier {
|
|||
if (!(member.isStatic || member.isAbstract || member.isSetter)) {
|
||||
_checkIllegalConcreteEnumMemberDeclaration(member.name);
|
||||
}
|
||||
if (!member.isStatic && classElement is! EnumElement) {
|
||||
if (!member.isStatic && declaration is! EnumElement) {
|
||||
_checkIllegalEnumValuesDeclaration(member.name);
|
||||
}
|
||||
}
|
||||
|
@ -283,10 +286,10 @@ class _ClassVerifier {
|
|||
GetterSetterTypesVerifier(
|
||||
typeSystem: typeSystem,
|
||||
errorReporter: reporter,
|
||||
).checkInterface(classElement, interface);
|
||||
).checkInterface(declaration, interface);
|
||||
|
||||
if (classElement is ClassElement && !classElement.isAbstract ||
|
||||
classElement is EnumElement) {
|
||||
if (declaration is ClassElement && !declaration.isAbstract ||
|
||||
declaration is EnumElement) {
|
||||
List<ExecutableElement>? inheritedAbstract;
|
||||
|
||||
for (var name in interface.map.keys) {
|
||||
|
@ -302,11 +305,11 @@ class _ClassVerifier {
|
|||
if (_reportConcreteClassWithAbstractMember(name.name)) {
|
||||
continue;
|
||||
}
|
||||
if (_isNotImplementedInConcreteSuperClass(classElement, name)) {
|
||||
if (_isNotImplementedInConcreteSuperClass(declaration, name)) {
|
||||
continue;
|
||||
}
|
||||
// We already reported ILLEGAL_ENUM_VALUES_INHERITANCE.
|
||||
if (classElement is EnumElement &&
|
||||
if (declaration is EnumElement &&
|
||||
const {'values', 'values='}.contains(name.name)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -602,6 +602,23 @@ class B implements A {
|
|||
]);
|
||||
}
|
||||
|
||||
test_method_returnType_interface_fromAugmentation() async {
|
||||
await assertErrorsInCode('''
|
||||
class A {
|
||||
int foo() => 0;
|
||||
}
|
||||
|
||||
class B {
|
||||
String foo() => '';
|
||||
}
|
||||
|
||||
augment class B implements A {}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 3,
|
||||
contextMessages: [message(testFile, 16, 3)]),
|
||||
]);
|
||||
}
|
||||
|
||||
test_method_returnType_interface_grandparent() async {
|
||||
await assertErrorsInCode('''
|
||||
abstract class A {
|
||||
|
@ -646,6 +663,23 @@ class B extends A {
|
|||
]);
|
||||
}
|
||||
|
||||
test_method_returnType_superclass_fromAugmentation() async {
|
||||
await assertErrorsInCode('''
|
||||
class A {
|
||||
int foo() => 0;
|
||||
}
|
||||
|
||||
class B {
|
||||
String foo() => '';
|
||||
}
|
||||
|
||||
augment class B extends A {}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 3,
|
||||
contextMessages: [message(testFile, 16, 3)]),
|
||||
]);
|
||||
}
|
||||
|
||||
test_method_returnType_superclass_grandparent() async {
|
||||
await assertErrorsInCode('''
|
||||
class A {
|
||||
|
@ -694,7 +728,7 @@ class B extends A {
|
|||
]);
|
||||
}
|
||||
|
||||
test_mixin_field_type() async {
|
||||
test_mixin_field_type_on() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
String foo = '';
|
||||
|
@ -711,7 +745,7 @@ mixin M on A {
|
|||
]);
|
||||
}
|
||||
|
||||
test_mixin_getter_type() async {
|
||||
test_mixin_getter_type_on() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
String get foo => '';
|
||||
|
@ -726,7 +760,7 @@ mixin M on A {
|
|||
]);
|
||||
}
|
||||
|
||||
test_mixin_method_returnType() async {
|
||||
test_mixin_method_returnType_on() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
String foo() => '';
|
||||
|
@ -741,7 +775,24 @@ mixin M on A {
|
|||
]);
|
||||
}
|
||||
|
||||
test_mixin_setter_type() async {
|
||||
test_mixin_method_returnType_on_fromAugmentation() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
int foo() => 0;
|
||||
}
|
||||
|
||||
mixin M {
|
||||
String foo() => '';
|
||||
}
|
||||
|
||||
augment mixin M on A {}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.INVALID_OVERRIDE, 50, 3,
|
||||
contextMessages: [message(testFile, 16, 3)]),
|
||||
]);
|
||||
}
|
||||
|
||||
test_mixin_setter_type_on() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
set foo(String _) {}
|
||||
|
|
Loading…
Reference in a new issue