blob: c1c72058977c38db69478b671d27a57598f984a1 [file] [log] [blame]
// Copyright (c) 2025, 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:expect/expect.dart';
// Test identity and equality of 'noSuchMethod' tearoffs.
void checkIdentical(Object o1, Object o2) {
Expect.isTrue(identical(o1, o2));
Expect.isTrue(o1 == o2);
Expect.isTrue(o2 == o1);
}
void checkEqual(Object o1, Object o2) {
Expect.isTrue(o1 == o2);
Expect.isTrue(o2 == o1);
// The behavior of `identical` is unspecified, optimizations could
// make a difference and should be allowed: Do not expect anything.
}
void checkUnequal(Object o1, Object o2) {
Expect.isTrue(o1 != o2);
Expect.isTrue(o2 != o1);
// We expect that `identical` is never true when `==` yields false.
Expect.isFalse(identical(o1, o2));
}
class CheckIdentical {
const CheckIdentical(Object o1, Object o2) : assert(identical(o1, o2));
}
class CheckNotIdentical {
const CheckNotIdentical(Object o1, Object o2) : assert(!identical(o1, o2));
}
class A {
// Enable a mixed-in method in `M` that has a superinvocation.
noSuchMethod(Invocation i) => 'A';
}
mixin M on A {
noSuchMethod(Invocation i) => super.noSuchMethod(i) + ' M on A';
}
class AM extends A with M {
Function(Invocation i) get tearoffSuperMethod => super.noSuchMethod;
}
class AMM extends AM with M {
// Tear off the second copy of M.noSuchMethod
// (`tearoffSuperMethod` still tears off the first copy).
Function(Invocation i) get tearoffSuperMethodSecond => super.noSuchMethod;
// In this case, `super.` should not make a difference.
Function(Invocation i) get tearoffSuperMethodSecondNoSuper => noSuchMethod;
}
void main() {
var amm = AMM();
Function(Invocation i) vMixedInSuperMethod1 = amm.tearoffSuperMethod;
Function(Invocation i) vMixedInSuperMethod2 = amm.tearoffSuperMethod;
Function(Invocation i) vMixedInSuperMethodSecond1 =
amm.tearoffSuperMethodSecond;
Function(Invocation i) vMixedInSuperMethodSecond2 =
amm.tearoffSuperMethodSecond;
Function(Invocation i) vMixedInSuperMethodSecondNoSuper1 =
amm.tearoffSuperMethodSecondNoSuper;
Function(Invocation i) vMixedInSuperMethodSecondNoSuper2 =
amm.tearoffSuperMethodSecondNoSuper;
checkEqual(amm.tearoffSuperMethod, amm.tearoffSuperMethod);
checkEqual(vMixedInSuperMethod1, vMixedInSuperMethod2);
checkEqual(amm.tearoffSuperMethodSecond, amm.tearoffSuperMethodSecond);
checkEqual(vMixedInSuperMethodSecond1, vMixedInSuperMethodSecond2);
checkUnequal(amm.tearoffSuperMethod, amm.tearoffSuperMethodSecond);
checkUnequal(vMixedInSuperMethod1, vMixedInSuperMethodSecond2);
checkUnequal(amm.tearoffSuperMethodSecond, amm.tearoffSuperMethod);
checkUnequal(vMixedInSuperMethodSecond1, vMixedInSuperMethod2);
checkEqual(
amm.tearoffSuperMethodSecondNoSuper,
amm.tearoffSuperMethodSecondNoSuper,
);
checkEqual(
vMixedInSuperMethodSecondNoSuper1,
vMixedInSuperMethodSecondNoSuper2,
);
checkUnequal(amm.tearoffSuperMethod, amm.tearoffSuperMethodSecondNoSuper);
checkUnequal(vMixedInSuperMethod1, vMixedInSuperMethodSecondNoSuper2);
checkUnequal(amm.tearoffSuperMethodSecondNoSuper, amm.tearoffSuperMethod);
checkUnequal(vMixedInSuperMethodSecondNoSuper1, vMixedInSuperMethod2);
checkEqual(amm.tearoffSuperMethodSecond, amm.tearoffSuperMethodSecondNoSuper);
}