Use separate 'type index' for mixin, some nodes might be unresolved.

R=brianwilkerson@google.com

Change-Id: Idf4bde1e4927bd0f1b69d6e0acef2cb97ade0bf9
Reviewed-on: https://dart-review.googlesource.com/c/77940
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2018-10-03 20:26:13 +00:00 committed by commit-bot@chromium.org
parent 854720a099
commit 1085dd13d1
2 changed files with 100 additions and 71 deletions

View file

@ -1900,10 +1900,14 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
return false;
}
bool problemReported = false;
for (int i = 0; i < withClause.mixinTypes.length; i++) {
TypeName mixinName = withClause.mixinTypes[i];
int mixinTypeIndex = -1;
for (int mixinNameIndex = 0;
mixinNameIndex < withClause.mixinTypes.length;
mixinNameIndex++) {
TypeName mixinName = withClause.mixinTypes[mixinNameIndex];
DartType mixinType = mixinName.type;
if (mixinType is InterfaceType) {
mixinTypeIndex++;
if (_checkForExtendsOrImplementsDisallowedClass(
mixinName, CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) {
problemReported = true;
@ -1914,11 +1918,12 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
problemReported = true;
}
if (mixinElement.isMixin) {
if (_checkForMixinSuperclassConstraints(mixinName, i)) {
if (_checkForMixinSuperclassConstraints(
mixinNameIndex, mixinName)) {
problemReported = true;
}
if (_checkForMixinSuperInvokedMembers(
i, mixinName, mixinElement, mixinType)) {
mixinTypeIndex, mixinName, mixinElement, mixinType)) {
problemReported = true;
}
} else {
@ -4151,15 +4156,15 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> {
}
/// Check that superclass constrains for the mixin type of [mixinName] at
/// the [index] position in the mixins list are satisfied by the
/// the [mixinIndex] position in the mixins list are satisfied by the
/// [_enclosingClass], or a previous mixin.
bool _checkForMixinSuperclassConstraints(TypeName mixinName, int index) {
bool _checkForMixinSuperclassConstraints(int mixinIndex, TypeName mixinName) {
InterfaceType mixinType = mixinName.type;
for (var constraint in mixinType.superclassConstraints) {
bool isSatisfied =
_typeSystem.isSubtypeOf(_enclosingClass.supertype, constraint);
if (!isSatisfied) {
for (int i = 0; i < index && !isSatisfied; i++) {
for (int i = 0; i < mixinIndex && !isSatisfied; i++) {
isSatisfied =
_typeSystem.isSubtypeOf(_enclosingClass.mixins[i], constraint);
}

View file

@ -1423,70 +1423,6 @@ mixin M implements A, B {} // M
assertTypeName(bRef, findElement.class_('B'), 'B');
}
test_inconsistentInheritanceGetterAndMethod_implements_getter_method() async {
addTestFile(r'''
abstract class A {
int get x;
}
abstract class B {
int x();
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritanceGetterAndMethod_implements_method_getter() async {
addTestFile(r'''
abstract class A {
int x();
}
abstract class B {
int get x;
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritanceGetterAndMethod_on_getter_method() async {
addTestFile(r'''
abstract class A {
int get x;
}
abstract class B {
int x();
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritanceGetterAndMethod_on_method_getter() async {
addTestFile(r'''
abstract class A {
int x();
}
abstract class B {
int get x;
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritance_implements_parameterType() async {
addTestFile(r'''
abstract class A {
@ -1583,6 +1519,94 @@ mixin M on A, B {}
]);
}
test_inconsistentInheritanceGetterAndMethod_implements_getter_method() async {
addTestFile(r'''
abstract class A {
int get x;
}
abstract class B {
int x();
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritanceGetterAndMethod_implements_method_getter() async {
addTestFile(r'''
abstract class A {
int x();
}
abstract class B {
int get x;
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritanceGetterAndMethod_on_getter_method() async {
addTestFile(r'''
abstract class A {
int get x;
}
abstract class B {
int x();
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritanceGetterAndMethod_on_method_getter() async {
addTestFile(r'''
abstract class A {
int x();
}
abstract class B {
int get x;
}
mixin M implements A, B {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_invalid_unresolved_before_mixin() async {
addTestFile(r'''
abstract class A {
int foo();
}
mixin M on A {
void bar() {
super.foo();
}
}
abstract class X extends A with U1, U2, M {}
''');
await resolveTestFile();
assertTestErrors([
CompileTimeErrorCode.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
StaticWarningCode.UNDEFINED_CLASS,
StaticWarningCode.UNDEFINED_CLASS,
]);
}
test_isMoreSpecificThan() async {
addTestFile(r'''
mixin M {}