blob: 549f2d44ea26918f3da73c1012251bb5d6f037bf [file] [log] [blame]
// Copyright (c) 2021, 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 function/method tearoffs.
void checkIdentical(Object o1, Object o2) {
Expect.isTrue(identical(o1, o2));
Expect.isTrue(o1 == o2 && o2 == o1);
}
void checkEqual(Object o1, Object o2) {
Expect.isTrue(o1 == o2 && 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 && 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));
}
void topLevelFunction() {}
X? genericTopLevelFunction<X>() => null;
class A {
static void staticMethod() {}
static X? genericStaticMethod<X>() => null;
void instanceMethod() {}
X? genericInstanceMethod<X>() => null;
// Enable a mixed-in method in `M` that has a superinvocation.
int mixedInSuperMethod() => 0;
}
mixin M on A {
void mixedInMethod() {}
int mixedInSuperMethod() => super.mixedInSuperMethod() + 1;
}
class AM extends A with M {
int Function() get tearoffSuperMethod => super.mixedInSuperMethod;
}
class AMM extends AM with M {
// Tear off the second copy of M.mixedInSuperMethod
// (`tearoffSuperMethod` still tears off the first copy).
int Function() get tearoffSuperMethodSecond => super.mixedInSuperMethod;
// In this case, `super.` should not make a difference.
int Function() get tearoffSuperMethodSecondNoSuper => mixedInSuperMethod;
}
const cTopLevelFunction = topLevelFunction;
const cGenericTopLevelFunction = genericTopLevelFunction;
const cStaticMethod = A.staticMethod;
const cGenericStaticMethod = A.genericStaticMethod;
const int? Function() cIntTopLevelFunction1 = genericTopLevelFunction;
const int? Function() cIntStaticMethod1 = A.genericStaticMethod;
const int? Function() cIntTopLevelFunction2 = genericTopLevelFunction;
const int? Function() cIntStaticMethod2 = A.genericStaticMethod;
const String? Function() cStringTopLevelFunction = genericTopLevelFunction;
const String? Function() cStringStaticMethod = A.genericStaticMethod;
int? Function() vIntTopLevelFunction1 = genericTopLevelFunction;
int? Function() vIntStaticMethod1 = A.genericStaticMethod;
int? Function() vIntTopLevelFunction2 = genericTopLevelFunction;
int? Function() vIntStaticMethod2 = A.genericStaticMethod;
String? Function() vStringTopLevelFunction = genericTopLevelFunction;
String? Function() vStringStaticMethod = A.genericStaticMethod;
void main() {
var vTopLevelFunction = topLevelFunction;
var vGenericTopLevelFunction = genericTopLevelFunction;
var vStaticMethod = A.staticMethod;
var vGenericStaticMethod = A.genericStaticMethod;
var a = A();
var vInstanceMethod = a.instanceMethod;
var vGenericInstanceMethod = a.genericInstanceMethod;
checkIdentical(topLevelFunction, topLevelFunction);
checkIdentical(A.staticMethod, A.staticMethod);
checkEqual(a.instanceMethod, a.instanceMethod);
checkIdentical(genericTopLevelFunction, genericTopLevelFunction);
checkIdentical(A.genericStaticMethod, A.genericStaticMethod);
checkEqual(a.genericInstanceMethod, a.genericInstanceMethod);
checkIdentical(topLevelFunction, cTopLevelFunction);
checkIdentical(A.staticMethod, cStaticMethod);
checkIdentical(genericTopLevelFunction, cGenericTopLevelFunction);
checkIdentical(A.genericStaticMethod, cGenericStaticMethod);
checkIdentical(topLevelFunction, vTopLevelFunction);
checkIdentical(A.staticMethod, vStaticMethod);
checkEqual(a.instanceMethod, vInstanceMethod);
checkIdentical(genericTopLevelFunction, vGenericTopLevelFunction);
checkIdentical(A.genericStaticMethod, vGenericStaticMethod);
checkEqual(a.genericInstanceMethod, vGenericInstanceMethod);
checkIdentical(cTopLevelFunction, vTopLevelFunction);
checkIdentical(cStaticMethod, vStaticMethod);
checkIdentical(cGenericTopLevelFunction, vGenericTopLevelFunction);
checkIdentical(cGenericStaticMethod, vGenericStaticMethod);
int? Function() vIntInstanceMethod1 = a.genericInstanceMethod;
int? Function() vIntInstanceMethod2 = a.genericInstanceMethod;
String? Function() vStringInstanceMethod = a.genericInstanceMethod;
checkIdentical(cIntTopLevelFunction1, cIntTopLevelFunction2);
checkIdentical(cIntStaticMethod1, cIntStaticMethod2);
checkIdentical(cIntTopLevelFunction1, vIntTopLevelFunction2);
checkIdentical(cIntStaticMethod1, vIntStaticMethod2);
checkIdentical(vIntTopLevelFunction1, vIntTopLevelFunction2);
checkIdentical(vIntStaticMethod1, vIntStaticMethod2);
checkEqual(vIntInstanceMethod1, vIntInstanceMethod2);
const CheckIdentical(topLevelFunction, topLevelFunction);
const CheckIdentical(A.staticMethod, A.staticMethod);
const CheckIdentical(genericTopLevelFunction, genericTopLevelFunction);
const CheckIdentical(A.genericStaticMethod, A.genericStaticMethod);
const CheckIdentical(topLevelFunction, cTopLevelFunction);
const CheckIdentical(A.staticMethod, cStaticMethod);
const CheckIdentical(genericTopLevelFunction, cGenericTopLevelFunction);
const CheckIdentical(A.genericStaticMethod, cGenericStaticMethod);
const CheckIdentical(cIntTopLevelFunction1, cIntTopLevelFunction2);
const CheckIdentical(cIntStaticMethod1, cIntStaticMethod2);
checkUnequal(topLevelFunction, genericTopLevelFunction);
checkUnequal(topLevelFunction, A.staticMethod);
checkUnequal(topLevelFunction, A.genericStaticMethod);
checkUnequal(topLevelFunction, a.instanceMethod);
checkUnequal(topLevelFunction, a.genericInstanceMethod);
checkUnequal(genericTopLevelFunction, topLevelFunction);
checkUnequal(genericTopLevelFunction, A.staticMethod);
checkUnequal(genericTopLevelFunction, A.genericStaticMethod);
checkUnequal(genericTopLevelFunction, a.instanceMethod);
checkUnequal(genericTopLevelFunction, a.genericInstanceMethod);
checkUnequal(A.staticMethod, topLevelFunction);
checkUnequal(A.staticMethod, genericTopLevelFunction);
checkUnequal(A.staticMethod, A.genericStaticMethod);
checkUnequal(A.staticMethod, a.instanceMethod);
checkUnequal(A.staticMethod, a.genericInstanceMethod);
checkUnequal(A.genericStaticMethod, topLevelFunction);
checkUnequal(A.genericStaticMethod, genericTopLevelFunction);
checkUnequal(A.genericStaticMethod, A.staticMethod);
checkUnequal(A.genericStaticMethod, a.instanceMethod);
checkUnequal(A.genericStaticMethod, a.genericInstanceMethod);
checkUnequal(a.instanceMethod, topLevelFunction);
checkUnequal(a.instanceMethod, genericTopLevelFunction);
checkUnequal(a.instanceMethod, A.staticMethod);
checkUnequal(a.instanceMethod, A.genericStaticMethod);
checkUnequal(a.instanceMethod, a.genericInstanceMethod);
checkUnequal(a.genericInstanceMethod, topLevelFunction);
checkUnequal(a.genericInstanceMethod, genericTopLevelFunction);
checkUnequal(a.genericInstanceMethod, A.staticMethod);
checkUnequal(a.genericInstanceMethod, A.genericStaticMethod);
checkUnequal(a.genericInstanceMethod, a.instanceMethod);
checkUnequal(topLevelFunction, cGenericTopLevelFunction);
checkUnequal(topLevelFunction, cStaticMethod);
checkUnequal(topLevelFunction, cGenericStaticMethod);
checkUnequal(genericTopLevelFunction, cTopLevelFunction);
checkUnequal(genericTopLevelFunction, cStaticMethod);
checkUnequal(genericTopLevelFunction, cGenericStaticMethod);
checkUnequal(A.staticMethod, cTopLevelFunction);
checkUnequal(A.staticMethod, cGenericTopLevelFunction);
checkUnequal(A.staticMethod, cGenericStaticMethod);
checkUnequal(A.genericStaticMethod, cTopLevelFunction);
checkUnequal(A.genericStaticMethod, cGenericTopLevelFunction);
checkUnequal(A.genericStaticMethod, cStaticMethod);
checkUnequal(a.instanceMethod, cTopLevelFunction);
checkUnequal(a.instanceMethod, cGenericTopLevelFunction);
checkUnequal(a.instanceMethod, cStaticMethod);
checkUnequal(a.instanceMethod, cGenericStaticMethod);
checkUnequal(a.genericInstanceMethod, cTopLevelFunction);
checkUnequal(a.genericInstanceMethod, cGenericTopLevelFunction);
checkUnequal(a.genericInstanceMethod, cStaticMethod);
checkUnequal(a.genericInstanceMethod, cGenericStaticMethod);
checkUnequal(topLevelFunction, vGenericTopLevelFunction);
checkUnequal(topLevelFunction, vStaticMethod);
checkUnequal(topLevelFunction, vGenericStaticMethod);
checkUnequal(topLevelFunction, vInstanceMethod);
checkUnequal(topLevelFunction, vGenericInstanceMethod);
checkUnequal(genericTopLevelFunction, vTopLevelFunction);
checkUnequal(genericTopLevelFunction, vStaticMethod);
checkUnequal(genericTopLevelFunction, vGenericStaticMethod);
checkUnequal(genericTopLevelFunction, vInstanceMethod);
checkUnequal(genericTopLevelFunction, vGenericInstanceMethod);
checkUnequal(A.staticMethod, vTopLevelFunction);
checkUnequal(A.staticMethod, vGenericTopLevelFunction);
checkUnequal(A.staticMethod, vGenericStaticMethod);
checkUnequal(A.staticMethod, vInstanceMethod);
checkUnequal(A.staticMethod, vGenericInstanceMethod);
checkUnequal(A.genericStaticMethod, vTopLevelFunction);
checkUnequal(A.genericStaticMethod, vGenericTopLevelFunction);
checkUnequal(A.genericStaticMethod, vStaticMethod);
checkUnequal(A.genericStaticMethod, vInstanceMethod);
checkUnequal(A.genericStaticMethod, vGenericInstanceMethod);
checkUnequal(a.instanceMethod, vTopLevelFunction);
checkUnequal(a.instanceMethod, vGenericTopLevelFunction);
checkUnequal(a.instanceMethod, vStaticMethod);
checkUnequal(a.instanceMethod, vGenericStaticMethod);
checkUnequal(a.instanceMethod, vGenericInstanceMethod);
checkUnequal(a.genericInstanceMethod, vTopLevelFunction);
checkUnequal(a.genericInstanceMethod, vGenericTopLevelFunction);
checkUnequal(a.genericInstanceMethod, vStaticMethod);
checkUnequal(a.genericInstanceMethod, vGenericStaticMethod);
checkUnequal(a.genericInstanceMethod, vInstanceMethod);
checkUnequal(cTopLevelFunction, vGenericTopLevelFunction);
checkUnequal(cTopLevelFunction, vStaticMethod);
checkUnequal(cTopLevelFunction, vGenericStaticMethod);
checkUnequal(cTopLevelFunction, vInstanceMethod);
checkUnequal(cTopLevelFunction, vGenericInstanceMethod);
checkUnequal(cGenericTopLevelFunction, vTopLevelFunction);
checkUnequal(cGenericTopLevelFunction, vStaticMethod);
checkUnequal(cGenericTopLevelFunction, vGenericStaticMethod);
checkUnequal(cGenericTopLevelFunction, vInstanceMethod);
checkUnequal(cGenericTopLevelFunction, vGenericInstanceMethod);
checkUnequal(cStaticMethod, vTopLevelFunction);
checkUnequal(cStaticMethod, vGenericTopLevelFunction);
checkUnequal(cStaticMethod, vGenericStaticMethod);
checkUnequal(cStaticMethod, vInstanceMethod);
checkUnequal(cStaticMethod, vGenericInstanceMethod);
checkUnequal(cGenericStaticMethod, vTopLevelFunction);
checkUnequal(cGenericStaticMethod, vGenericTopLevelFunction);
checkUnequal(cGenericStaticMethod, vStaticMethod);
checkUnequal(cGenericStaticMethod, vInstanceMethod);
checkUnequal(cGenericStaticMethod, vGenericInstanceMethod);
var a2 = A();
var v2InstanceMethod = a2.instanceMethod;
var v2GenericInstanceMethod = a2.genericInstanceMethod;
checkUnequal(vInstanceMethod, v2InstanceMethod);
checkUnequal(vGenericInstanceMethod, v2GenericInstanceMethod);
const CheckNotIdentical(topLevelFunction, genericTopLevelFunction);
const CheckNotIdentical(topLevelFunction, A.staticMethod);
const CheckNotIdentical(topLevelFunction, A.genericStaticMethod);
const CheckNotIdentical(genericTopLevelFunction, topLevelFunction);
const CheckNotIdentical(genericTopLevelFunction, A.staticMethod);
const CheckNotIdentical(genericTopLevelFunction, A.genericStaticMethod);
const CheckNotIdentical(A.staticMethod, topLevelFunction);
const CheckNotIdentical(A.staticMethod, genericTopLevelFunction);
const CheckNotIdentical(A.staticMethod, A.genericStaticMethod);
const CheckNotIdentical(A.genericStaticMethod, topLevelFunction);
const CheckNotIdentical(A.genericStaticMethod, genericTopLevelFunction);
const CheckNotIdentical(A.genericStaticMethod, A.staticMethod);
const CheckNotIdentical(topLevelFunction, cGenericTopLevelFunction);
const CheckNotIdentical(topLevelFunction, cStaticMethod);
const CheckNotIdentical(topLevelFunction, cGenericStaticMethod);
const CheckNotIdentical(genericTopLevelFunction, cTopLevelFunction);
const CheckNotIdentical(genericTopLevelFunction, cStaticMethod);
const CheckNotIdentical(genericTopLevelFunction, cGenericStaticMethod);
const CheckNotIdentical(A.staticMethod, cTopLevelFunction);
const CheckNotIdentical(A.staticMethod, cGenericTopLevelFunction);
const CheckNotIdentical(A.staticMethod, cGenericStaticMethod);
const CheckNotIdentical(A.genericStaticMethod, cTopLevelFunction);
const CheckNotIdentical(A.genericStaticMethod, cGenericTopLevelFunction);
const CheckNotIdentical(A.genericStaticMethod, cStaticMethod);
checkUnequal(cIntTopLevelFunction1, cIntStaticMethod1);
checkUnequal(cIntTopLevelFunction1, vIntStaticMethod1);
checkUnequal(cIntTopLevelFunction1, vIntInstanceMethod1);
checkUnequal(cIntStaticMethod1, vIntTopLevelFunction1);
checkUnequal(cIntStaticMethod1, vIntInstanceMethod1);
checkUnequal(vIntTopLevelFunction1, vIntStaticMethod1);
checkUnequal(vIntTopLevelFunction1, vIntInstanceMethod1);
checkUnequal(vIntStaticMethod1, vIntInstanceMethod1);
int? Function() v2IntInstanceMethod = a2.genericInstanceMethod;
checkUnequal(vIntInstanceMethod1, v2IntInstanceMethod);
checkUnequal(vIntInstanceMethod1, vStringInstanceMethod);
const CheckNotIdentical(cIntTopLevelFunction1, cIntStaticMethod1);
const CheckNotIdentical(cIntTopLevelFunction1, cStringTopLevelFunction);
const CheckNotIdentical(cIntStaticMethod1, cStringStaticMethod);
{
var am = AM();
void Function() vMixedInMethod1 = am.mixedInMethod;
void Function() vMixedInMethod2 = am.mixedInMethod;
int Function() vMixedInSuperMethod1 = am.mixedInSuperMethod;
int Function() vMixedInSuperMethod2 = am.mixedInSuperMethod;
checkEqual(am.mixedInMethod, am.mixedInMethod);
checkEqual(vMixedInMethod1, vMixedInMethod2);
checkEqual(am.mixedInSuperMethod, am.mixedInSuperMethod);
checkEqual(vMixedInSuperMethod1, vMixedInSuperMethod2);
}
{
var amm = AMM();
void Function() vMixedInMethod1 = amm.mixedInMethod;
void Function() vMixedInMethod2 = amm.mixedInMethod;
int Function() vMixedInSuperMethod1 = amm.tearoffSuperMethod;
int Function() vMixedInSuperMethod2 = amm.tearoffSuperMethod;
int Function() vMixedInSuperMethodSecond1 = amm.tearoffSuperMethodSecond;
int Function() vMixedInSuperMethodSecond2 = amm.tearoffSuperMethodSecond;
int Function() vMixedInSuperMethodSecondNoSuper1 =
amm.tearoffSuperMethodSecondNoSuper;
int Function() vMixedInSuperMethodSecondNoSuper2 =
amm.tearoffSuperMethodSecondNoSuper;
checkEqual(amm.mixedInMethod, amm.mixedInMethod);
checkEqual(vMixedInMethod1, vMixedInMethod2);
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);
}
<X>() {
X? Function() vXTopLevelFunction1 = genericTopLevelFunction;
X? Function() vXStaticMethod1 = A.genericStaticMethod;
X? Function() vXTopLevelFunction2 = genericTopLevelFunction;
X? Function() vXStaticMethod2 = A.genericStaticMethod;
X? Function() vXInstanceMethod1 = a.genericInstanceMethod;
X? Function() vXInstanceMethod2 = a.genericInstanceMethod;
checkEqual(vXTopLevelFunction1, vXTopLevelFunction2);
checkEqual(vXStaticMethod1, vXStaticMethod2);
checkEqual(vXInstanceMethod1, vXInstanceMethod2);
checkEqual(vXTopLevelFunction1, vIntTopLevelFunction1);
checkEqual(vXStaticMethod1, vIntStaticMethod1);
checkEqual(vXInstanceMethod1, vIntInstanceMethod2);
checkUnequal(vXTopLevelFunction1, vXStaticMethod1);
checkUnequal(vXTopLevelFunction1, vXInstanceMethod1);
checkUnequal(vXStaticMethod1, vXInstanceMethod1);
int? Function() v2XInstanceMethod = a2.genericInstanceMethod;
checkUnequal(vXInstanceMethod1, v2XInstanceMethod);
checkUnequal(vXInstanceMethod1, vStringInstanceMethod);
}<int>();
}