[cfe] Check overrides on operators

Change-Id: Ib250117553b2e22c6c71b78bf354be1162bc9981
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151235
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2020-07-08 08:45:34 +00:00 committed by commit-bot@chromium.org
parent fefcac472f
commit 45af99177b
32 changed files with 965 additions and 37 deletions

View file

@ -62,7 +62,7 @@ import '../loader.dart';
import '../modifier.dart';
import '../names.dart' show noSuchMethodName;
import '../names.dart' show equalsName, noSuchMethodName;
import '../problems.dart' show internalProblem, unhandled, unimplemented;
@ -791,27 +791,30 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
"Constructor in override check.", declaredMember.fileOffset, fileUri);
}
if (declaredMember is Procedure && interfaceMember is Procedure) {
if (declaredMember.kind == ProcedureKind.Method &&
interfaceMember.kind == ProcedureKind.Method) {
bool seenCovariant = checkMethodOverride(
types, declaredMember, interfaceMember, isInterfaceCheck);
if (seenCovariant) {
handleSeenCovariant(
types, declaredMember, interfaceMember, isSetter, callback);
}
}
if (declaredMember.kind == ProcedureKind.Getter &&
interfaceMember.kind == ProcedureKind.Getter) {
checkGetterOverride(
types, declaredMember, interfaceMember, isInterfaceCheck);
}
if (declaredMember.kind == ProcedureKind.Setter &&
interfaceMember.kind == ProcedureKind.Setter) {
bool seenCovariant = checkSetterOverride(
types, declaredMember, interfaceMember, isInterfaceCheck);
if (seenCovariant) {
handleSeenCovariant(
types, declaredMember, interfaceMember, isSetter, callback);
if (declaredMember.kind == interfaceMember.kind) {
if (declaredMember.kind == ProcedureKind.Method ||
declaredMember.kind == ProcedureKind.Operator) {
bool seenCovariant = checkMethodOverride(
types, declaredMember, interfaceMember, isInterfaceCheck);
if (seenCovariant) {
handleSeenCovariant(
types, declaredMember, interfaceMember, isSetter, callback);
}
} else if (declaredMember.kind == ProcedureKind.Getter) {
checkGetterOverride(
types, declaredMember, interfaceMember, isInterfaceCheck);
} else if (declaredMember.kind == ProcedureKind.Setter) {
bool seenCovariant = checkSetterOverride(
types, declaredMember, interfaceMember, isInterfaceCheck);
if (seenCovariant) {
handleSeenCovariant(
types, declaredMember, interfaceMember, isSetter, callback);
}
} else {
assert(
false,
"Unexpected procedure kind in override check: "
"${declaredMember.kind}");
}
}
} else {
@ -1093,8 +1096,9 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
@override
bool checkMethodOverride(Types types, Procedure declaredMember,
Procedure interfaceMember, bool isInterfaceCheck) {
assert(declaredMember.kind == ProcedureKind.Method);
assert(interfaceMember.kind == ProcedureKind.Method);
assert(declaredMember.kind == interfaceMember.kind);
assert(declaredMember.kind == ProcedureKind.Method ||
declaredMember.kind == ProcedureKind.Operator);
bool seenCovariant = false;
FunctionNode declaredFunction = declaredMember.function;
FunctionNode interfaceFunction = interfaceMember.function;
@ -1167,6 +1171,17 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
declaredFunction.positionalParameters[i];
VariableDeclaration interfaceParameter =
interfaceFunction.positionalParameters[i];
if (i == 0 &&
declaredMember.name == equalsName &&
declaredParameter.type ==
types.hierarchy.coreTypes.objectNonNullableRawType &&
interfaceParameter.type is DynamicType) {
// TODO(johnniwinther): Add check for opt-in overrides of operator ==.
// `operator ==` methods in opt-out classes have type
// `bool Function(dynamic)`.
continue;
}
_checkTypes(
types,
interfaceSubstitution,
@ -1174,7 +1189,7 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
declaredMember,
interfaceMember,
declaredParameter.type,
interfaceFunction.positionalParameters[i].type,
interfaceParameter.type,
declaredParameter.isCovariant || interfaceParameter.isCovariant,
declaredParameter,
isInterfaceCheck);
@ -1340,6 +1355,10 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl
void reportInvalidOverride(bool isInterfaceCheck, Member declaredMember,
Message message, int fileOffset, int length,
{List<LocatedMessage> context}) {
if (shouldOverrideProblemBeOverlooked(this)) {
return;
}
if (declaredMember.enclosingClass == cls) {
// Ordinary override
library.addProblem(message, fileOffset, length, declaredMember.fileUri,
@ -1769,3 +1788,17 @@ class ConstructorRedirection {
ConstructorRedirection(this.target) : cycleReported = false;
}
/// Returns `true` if override problems should be overlooked.
///
/// This is needed for the current encoding of some JavaScript implementation
/// classes that are not valid Dart. For instance `JSInt` in
/// 'dart:_interceptors' that implements both `int` and `double`, and `JsArray`
/// in `dart:js` that implement both `ListMixin` and `JsObject`.
bool shouldOverrideProblemBeOverlooked(ClassBuilder classBuilder) {
String uri = '${classBuilder.library.importUri}';
return uri == 'dart:js' &&
classBuilder.fileUri.pathSegments.last == 'js.dart' ||
uri == 'dart:_interceptors' &&
classBuilder.fileUri.pathSegments.last == 'js_number.dart';
}

View file

@ -3038,14 +3038,7 @@ class InterfaceConflict extends DelayedMember {
debug?.log("Combined Member Signature: "
"${bestSoFar.fullName} !<: ${candidate.fullName}");
String uri = '${classBuilder.library.importUri}';
if (uri == 'dart:js' &&
classBuilder.fileUri.pathSegments.last == 'js.dart' ||
uri == 'dart:_interceptors' &&
classBuilder.fileUri.pathSegments.last == 'js_number.dart') {
// TODO(johnniwinther): Fix the dart2js libraries and remove the
// above URIs.
} else {
if (!shouldOverrideProblemBeOverlooked(classBuilder)) {
bestSoFar = null;
bestTypeSoFar = null;
mutualSubtypes = null;

View file

@ -751,6 +751,7 @@ os
outputting
overlap
overloader
overlooked
overshadowed
overwrite
overwriting

View file

@ -0,0 +1,24 @@
// Copyright (c) 2020, 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.
class A {
A operator +(B b) => new A();
A operator -() => new A();
A operator [](B b) => new A();
void operator []=(B b1, B b2) {}
}
class B extends A {
A operator +(A a);
B operator -();
A operator [](A a);
void operator []=(A a, B b);
}
class C extends A {
B operator [](B b);
void operator []=(B b, A a);
}
main() {}

View file

@ -0,0 +1,123 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '+' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:6:18: Context: The parameter 'b' of the method 'A.+' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.+'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator +(B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:13:14: Context: This is the overridden method ('+').
// A operator +(A a);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of 'unary-' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:7:14: Context: The return type of the method 'A.unary-' is 'A', which does not match the return type, 'B', of the overridden method, 'B.unary-'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator -() => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:14:14: Context: This is the overridden method ('unary-').
// B operator -();
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '[]' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:8:19: Context: The parameter 'b' of the method 'A.[]' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.[]'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator [](B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:15:14: Context: This is the overridden method ('[]').
// A operator [](A a);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '[]=' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:9:23: Context: The parameter 'b1' of the method 'A.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b1, B b2) {}
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:16:17: Context: This is the overridden method ('[]=').
// void operator []=(A a, B b);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:19:7: Error: The implementation of '[]' in the non-abstract class 'C' does not conform to its interface.
// class C extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:8:14: Context: The return type of the method 'A.[]' is 'A', which does not match the return type, 'B', of the overridden method, 'C.[]'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator [](B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:20:14: Context: This is the overridden method ('[]').
// B operator [](B b);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:19:7: Error: The implementation of '[]=' in the non-abstract class 'C' does not conform to its interface.
// class C extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:9:29: Context: The parameter 'b2' of the method 'A.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'C.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b1, B b2) {}
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:21:17: Context: This is the overridden method ('[]=').
// void operator []=(B b, A a);
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A*
;
operator +(self::B* b) → self::A*
;
operator unary-() → self::A*
;
operator [](self::B* b) → self::A*
;
operator []=(self::B* b1, self::B* b2) → void
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
class B extends self::A {
synthetic constructor •() → self::B*
;
abstract operator +(self::A* a) → self::A*;
abstract operator unary-() → self::B*;
abstract operator [](self::A* a) → self::A*;
abstract operator []=(self::A* a, self::B* b) → void;
}
class C extends self::A {
synthetic constructor •() → self::C*
;
abstract operator [](self::B* b) → self::B*;
abstract operator []=(self::B* b, self::A* a) → void;
}
static method main() → dynamic
;

View file

@ -0,0 +1,124 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '+' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:6:18: Context: The parameter 'b' of the method 'A.+' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.+'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator +(B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:13:14: Context: This is the overridden method ('+').
// A operator +(A a);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of 'unary-' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:7:14: Context: The return type of the method 'A.unary-' is 'A', which does not match the return type, 'B', of the overridden method, 'B.unary-'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator -() => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:14:14: Context: This is the overridden method ('unary-').
// B operator -();
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '[]' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:8:19: Context: The parameter 'b' of the method 'A.[]' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.[]'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator [](B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:15:14: Context: This is the overridden method ('[]').
// A operator [](A a);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '[]=' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:9:23: Context: The parameter 'b1' of the method 'A.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b1, B b2) {}
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:16:17: Context: This is the overridden method ('[]=').
// void operator []=(A a, B b);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:19:7: Error: The implementation of '[]' in the non-abstract class 'C' does not conform to its interface.
// class C extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:8:14: Context: The return type of the method 'A.[]' is 'A', which does not match the return type, 'B', of the overridden method, 'C.[]'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator [](B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:20:14: Context: This is the overridden method ('[]').
// B operator [](B b);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:19:7: Error: The implementation of '[]=' in the non-abstract class 'C' does not conform to its interface.
// class C extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:9:29: Context: The parameter 'b2' of the method 'A.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'C.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b1, B b2) {}
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:21:17: Context: This is the overridden method ('[]=').
// void operator []=(B b, A a);
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A*
: super core::Object::•()
;
operator +(self::B* b) → self::A*
return new self::A::•();
operator unary-() → self::A*
return new self::A::•();
operator [](self::B* b) → self::A*
return new self::A::•();
operator []=(self::B* b1, self::B* b2) → void {}
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
class B extends self::A {
synthetic constructor •() → self::B*
: super self::A::•()
;
abstract operator +(self::A* a) → self::A*;
abstract operator unary-() → self::B*;
abstract operator [](self::A* a) → self::A*;
abstract operator []=(self::A* a, self::B* b) → void;
}
class C extends self::A {
synthetic constructor •() → self::C*
: super self::A::•()
;
abstract operator [](self::B* b) → self::B*;
abstract operator []=(self::B* b, self::A* a) → void;
}
static method main() → dynamic {}

View file

@ -0,0 +1,124 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '+' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:6:18: Context: The parameter 'b' of the method 'A.+' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.+'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator +(B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:13:14: Context: This is the overridden method ('+').
// A operator +(A a);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of 'unary-' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:7:14: Context: The return type of the method 'A.unary-' is 'A', which does not match the return type, 'B', of the overridden method, 'B.unary-'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator -() => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:14:14: Context: This is the overridden method ('unary-').
// B operator -();
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '[]' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:8:19: Context: The parameter 'b' of the method 'A.[]' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.[]'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator [](B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:15:14: Context: This is the overridden method ('[]').
// A operator [](A a);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:12:7: Error: The implementation of '[]=' in the non-abstract class 'B' does not conform to its interface.
// class B extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:9:23: Context: The parameter 'b1' of the method 'A.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'B.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b1, B b2) {}
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:16:17: Context: This is the overridden method ('[]=').
// void operator []=(A a, B b);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:19:7: Error: The implementation of '[]' in the non-abstract class 'C' does not conform to its interface.
// class C extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:8:14: Context: The return type of the method 'A.[]' is 'A', which does not match the return type, 'B', of the overridden method, 'C.[]'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator [](B b) => new A();
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:20:14: Context: This is the overridden method ('[]').
// B operator [](B b);
// ^
//
// pkg/front_end/testcases/general/abstract_operator_override.dart:19:7: Error: The implementation of '[]=' in the non-abstract class 'C' does not conform to its interface.
// class C extends A {
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:9:29: Context: The parameter 'b2' of the method 'A.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'C.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/abstract_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b1, B b2) {}
// ^
// pkg/front_end/testcases/general/abstract_operator_override.dart:21:17: Context: This is the overridden method ('[]=').
// void operator []=(B b, A a);
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A*
: super core::Object::•()
;
operator +(self::B* b) → self::A*
return new self::A::•();
operator unary-() → self::A*
return new self::A::•();
operator [](self::B* b) → self::A*
return new self::A::•();
operator []=(self::B* b1, self::B* b2) → void {}
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
class B extends self::A {
synthetic constructor •() → self::B*
: super self::A::•()
;
abstract operator +(self::A* a) → self::A*;
abstract operator unary-() → self::B*;
abstract operator [](self::A* a) → self::A*;
abstract operator []=(self::A* a, self::B* b) → void;
}
class C extends self::A {
synthetic constructor •() → self::C*
: super self::A::•()
;
abstract operator [](self::B* b) → self::B*;
abstract operator []=(self::B* b, self::A* a) → void;
}
static method main() → dynamic {}

View file

@ -0,0 +1,20 @@
class A {
A operator +(B b) => new A();
A operator -() => new A();
A operator [](B b) => new A();
void operator []=(B b1, B b2) {}
}
class B extends A {
A operator +(A a);
B operator -();
A operator [](A a);
void operator []=(A a, B b);
}
class C extends A {
B operator [](B b);
void operator []=(B b, A a);
}
main() {}

View file

@ -0,0 +1,20 @@
class A {
A operator +(B b) => new A();
A operator -() => new A();
A operator [](B b) => new A();
void operator []=(B b1, B b2) {}
}
class B extends A {
A operator +(A a);
A operator [](A a);
B operator -();
void operator []=(A a, B b);
}
class C extends A {
B operator [](B b);
void operator []=(B b, A a);
}
main() {}

View file

@ -560,6 +560,42 @@ library;
// operator ~<T>() => true;
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:6:12: Error: The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==() => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:27:12: Error: The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
// operator ==(a, b) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:71:12: Error: The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==({a}) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
// operator ==<T>(a) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: The return type of the method 'Operators7.==' is 'dynamic', which does not match the return type, 'bool', of the overridden method, 'Object.=='.
// Change to a subtype of 'bool'.
// operator ==<T>(a) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -560,6 +560,42 @@ library;
// operator ~<T>() => true;
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:6:12: Error: The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==() => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:27:12: Error: The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
// operator ==(a, b) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:71:12: Error: The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==({a}) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
// operator ==<T>(a) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: The return type of the method 'Operators7.==' is 'dynamic', which does not match the return type, 'bool', of the overridden method, 'Object.=='.
// Change to a subtype of 'bool'.
// operator ==<T>(a) => true;
// ^
// sdk/lib/_internal/vm/lib/object_patch.dart:18:17: Context: This is the overridden method ('==').
// bool operator ==(Object other) native "Object_equals";
// ^
//
import self as self;
import "dart:core" as core;

View file

@ -0,0 +1,24 @@
// Copyright (c) 2020, 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.
class A {
A operator +(A a) => a;
B operator -() => new B();
B operator [](A a) => new B();
void operator []=(A a1, A a2) {}
}
class B extends A {
A operator +(B b) => b;
A operator -() => this;
B operator [](B b) => b;
void operator []=(B b, A a) {}
}
class C extends A {
A operator [](B b) => b;
void operator []=(A a, B b) {}
}
main() {}

View file

@ -0,0 +1,121 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:13:18: Error: The parameter 'b' of the method 'B.+' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.+'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator +(B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:6:14: Context: This is the overridden method ('+').
// A operator +(A a) => a;
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:14:14: Error: The return type of the method 'B.unary-' is 'A', which does not match the return type, 'B', of the overridden method, 'A.unary-'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator -() => this;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:7:14: Context: This is the overridden method ('unary-').
// B operator -() => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:15:19: Error: The parameter 'b' of the method 'B.[]' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// B operator [](B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:8:14: Context: This is the overridden method ('[]').
// B operator [](A a) => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:16:23: Error: The parameter 'b' of the method 'B.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b, A a) {}
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:9:17: Context: This is the overridden method ('[]=').
// void operator []=(A a1, A a2) {}
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:20:14: Error: The return type of the method 'C.[]' is 'A', which does not match the return type, 'B', of the overridden method, 'A.[]'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator [](B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:8:14: Context: This is the overridden method ('[]').
// B operator [](A a) => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:20:19: Error: The parameter 'b' of the method 'C.[]' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator [](B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:8:14: Context: This is the overridden method ('[]').
// B operator [](A a) => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:21:28: Error: The parameter 'b' of the method 'C.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(A a, B b) {}
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:9:17: Context: This is the overridden method ('[]=').
// void operator []=(A a1, A a2) {}
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A*
;
operator +(self::A* a) → self::A*
;
operator unary-() → self::B*
;
operator [](self::A* a) → self::B*
;
operator []=(self::A* a1, self::A* a2) → void
;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
class B extends self::A {
synthetic constructor •() → self::B*
;
operator +(self::B* b) → self::A*
;
operator unary-() → self::A*
;
operator [](self::B* b) → self::B*
;
operator []=(self::B* b, self::A* a) → void
;
}
class C extends self::A {
synthetic constructor •() → self::C*
;
operator [](self::B* b) → self::A*
;
operator []=(self::A* a, self::B* b) → void
;
}
static method main() → dynamic
;

View file

@ -0,0 +1,120 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:13:18: Error: The parameter 'b' of the method 'B.+' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.+'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator +(B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:6:14: Context: This is the overridden method ('+').
// A operator +(A a) => a;
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:14:14: Error: The return type of the method 'B.unary-' is 'A', which does not match the return type, 'B', of the overridden method, 'A.unary-'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator -() => this;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:7:14: Context: This is the overridden method ('unary-').
// B operator -() => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:15:19: Error: The parameter 'b' of the method 'B.[]' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// B operator [](B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:8:14: Context: This is the overridden method ('[]').
// B operator [](A a) => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:16:23: Error: The parameter 'b' of the method 'B.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(B b, A a) {}
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:9:17: Context: This is the overridden method ('[]=').
// void operator []=(A a1, A a2) {}
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:20:14: Error: The return type of the method 'C.[]' is 'A', which does not match the return type, 'B', of the overridden method, 'A.[]'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a subtype of 'B'.
// A operator [](B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:8:14: Context: This is the overridden method ('[]').
// B operator [](A a) => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:20:19: Error: The parameter 'b' of the method 'C.[]' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]'.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// A operator [](B b) => b;
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:8:14: Context: This is the overridden method ('[]').
// B operator [](A a) => new B();
// ^
//
// pkg/front_end/testcases/general/invalid_operator_override.dart:21:28: Error: The parameter 'b' of the method 'C.[]=' has type 'B', which does not match the corresponding type, 'A', in the overridden method, 'A.[]='.
// - 'B' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// - 'A' is from 'pkg/front_end/testcases/general/invalid_operator_override.dart'.
// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
// void operator []=(A a, B b) {}
// ^
// pkg/front_end/testcases/general/invalid_operator_override.dart:9:17: Context: This is the overridden method ('[]=').
// void operator []=(A a1, A a2) {}
// ^
//
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A*
: super core::Object::•()
;
operator +(self::A* a) → self::A*
return a;
operator unary-() → self::B*
return new self::B::•();
operator [](self::A* a) → self::B*
return new self::B::•();
operator []=(self::A* a1, self::A* a2) → void {}
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
class B extends self::A {
synthetic constructor •() → self::B*
: super self::A::•()
;
operator +(self::B* b) → self::A*
return b;
operator unary-() → self::A*
return this;
operator [](self::B* b) → self::B*
return b;
operator []=(self::B* b, self::A* a) → void {}
}
class C extends self::A {
synthetic constructor •() → self::C*
: super self::A::•()
;
operator [](self::B* b) → self::A*
return b;
operator []=(self::A* a, self::B* b) → void {}
}
static method main() → dynamic {}

View file

@ -0,0 +1,20 @@
class A {
A operator +(A a) => a;
B operator -() => new B();
B operator [](A a) => new B();
void operator []=(A a1, A a2) {}
}
class B extends A {
A operator +(B b) => b;
A operator -() => this;
B operator [](B b) => b;
void operator []=(B b, A a) {}
}
class C extends A {
A operator [](B b) => b;
void operator []=(A a, B b) {}
}
main() {}

View file

@ -0,0 +1,20 @@
class A {
A operator +(A a) => a;
B operator -() => new B();
B operator [](A a) => new B();
void operator []=(A a1, A a2) {}
}
class B extends A {
A operator +(B b) => b;
A operator -() => this;
B operator [](B b) => b;
void operator []=(B b, A a) {}
}
class C extends A {
A operator [](B b) => b;
void operator []=(A a, B b) {}
}
main() {}

View file

@ -0,0 +1,9 @@
// Copyright (c) 2020, 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.
class A {
operator ==(dynamic other);
}
main() {}

View file

@ -0,0 +1,11 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A
;
abstract operator ==(dynamic other) → core::bool;
}
static method main() → dynamic
;

View file

@ -0,0 +1,11 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
abstract operator ==(dynamic other) → core::bool;
}
static method main() → dynamic {}

View file

@ -0,0 +1,11 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
abstract operator ==(dynamic other) → core::bool;
}
static method main() → dynamic {}

View file

@ -0,0 +1,5 @@
class A {
operator ==(dynamic other);
}
main() {}

View file

@ -0,0 +1,5 @@
class A {
operator ==(dynamic other);
}
main() {}

View file

@ -0,0 +1,11 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
abstract operator ==(dynamic other) → core::bool;
}
static method main() → dynamic {}

View file

@ -0,0 +1,11 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
class A extends core::Object {
synthetic constructor •() → self::A
: super core::Object::•()
;
abstract operator ==(dynamic other) → core::bool;
}
static method main() → dynamic {}

View file

@ -17,6 +17,7 @@ general/bug30695: TypeCheckError
general/covariant_field: TypeCheckError
general/infer_field_from_multiple: TypeCheckError
general/invalid_operator: TypeCheckError
general/invalid_operator_override: TypeCheckError
general/issue41210a: TypeCheckError
general/issue41210b/issue41210: TypeCheckError
general/mixin_application_override: TypeCheckError

View file

@ -65,6 +65,7 @@ general/external_import: RuntimeError # The native extension to import doesn't e
general/incomplete_field_formal_parameter: RuntimeError
general/infer_field_from_multiple: TypeCheckError
general/invalid_operator: TypeCheckError
general/invalid_operator_override: TypeCheckError
general/invocations: RuntimeError
general/issue37776: RuntimeError
general/issue38938: RuntimeError # no main and compile time errors.

View file

@ -65,6 +65,7 @@ general/external_import: RuntimeError
general/incomplete_field_formal_parameter: RuntimeError
general/infer_field_from_multiple: TypeCheckError
general/invalid_operator: TypeCheckError
general/invalid_operator_override: TypeCheckError
general/invocations: RuntimeError
general/issue37776: RuntimeError
general/issue38938: RuntimeError

View file

@ -4325,7 +4325,7 @@ TEST_CASE(InstanceEquality) {
// Test that Instance::OperatorEquals can call a user-defined operator==.
const char* kScript =
"class A {\n"
" bool operator==(A other) { return true; }\n"
" bool operator==(covariant A other) { return true; }\n"
"}\n"
"main() {\n"
" A a = new A();\n"

View file

@ -13,7 +13,7 @@ class Size {
Size(num this.width, num this.height) {}
bool operator ==(Size other) {
bool operator ==(covariant Size other) {
return other != null && width == other.width && height == other.height;
}

View file

@ -36,7 +36,7 @@ class Coordinate {
return Math.sqrt(dx * dx + dy * dy);
}
bool operator ==(Coordinate other) {
bool operator ==(covariant Coordinate other) {
return other != null && x == other.x && y == other.y;
}
@ -73,7 +73,7 @@ class Interval {
return end - start;
}
bool operator ==(Interval other) {
bool operator ==(covariant Interval other) {
return other != null && other.start == start && other.end == end;
}

View file

@ -9,6 +9,7 @@ class Operators1 {
// [cfe] Operator '==' should have exactly one parameter.
// ^^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
// [cfe] The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
operator <() => true;
// ^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
@ -86,6 +87,7 @@ class Operators2 {
// [cfe] Operator '==' should have exactly one parameter.
// ^^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
// [cfe] The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
operator <(a, b) => true;
// ^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
@ -249,6 +251,7 @@ class Operators4 {
operator ==({a}) => true;
// ^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
// [cfe] The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
// ^
// [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
// [cfe] An operator can't have optional parameters.
@ -569,6 +572,9 @@ class Operators7 {
operator ==<T>(a) => true;
// ^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
// [cfe] Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
// ^
// [cfe] The return type of the method 'Operators7.==' is 'dynamic', which does not match the return type, 'bool', of the overridden method, 'Object.=='.
// ^^^
// [analyzer] SYNTACTIC_ERROR.TYPE_PARAMETERS_ON_OPERATOR
// ^

View file

@ -9,6 +9,7 @@ class Operators1 {
// [cfe] Operator '==' should have exactly one parameter.
// ^^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
// [cfe] The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
operator <() => true;
// ^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
@ -86,6 +87,7 @@ class Operators2 {
// [cfe] Operator '==' should have exactly one parameter.
// ^^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
// [cfe] The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
operator <(a, b) => true;
// ^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
@ -248,6 +250,7 @@ class Operators4 {
operator ==({a}) => true;
// ^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
// [cfe] The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
// ^
// [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
// [cfe] An operator can't have optional parameters.
@ -568,6 +571,9 @@ class Operators7 {
operator ==<T>(a) => true;
// ^^
// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
// [cfe] Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
// ^
// [cfe] The return type of the method 'Operators7.==' is 'dynamic', which does not match the return type, 'bool', of the overridden method, 'Object.=='.
// ^^^
// [analyzer] SYNTACTIC_ERROR.TYPE_PARAMETERS_ON_OPERATOR
// ^