blob: 6afacf30b001a6f1b2ddc6c85ee9eda0a7fd492d [file] [log] [blame]
// Copyright (c) 2019, 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";
// Tests the resolution of multiple applicable extensions.
String? lastSetterValue;
class SuperTarget {}
class Target<T> extends SuperTarget {
String targetMethod() => "targetMethod";
String get targetGetter => "targetGetter";
void set targetSetter(String argument) {
lastSetterValue = "targetSetter: $argument";
}
}
class SubTarget<T> extends Target<T> {
String subTargetMethod() => "subTargetMethod";
String get subTargetGetter => "subTargetGetter";
void set subTargetSetter(String argument) {
lastSetterValue = "subTargetSetter: $argument";
}
}
extension E1<T> on SubTarget<T> {
static String name = "SubTarget<T>";
String e1() => "$name.e1";
String targetMethod() => "$name.targetMethod";
String get targetGetter => "$name.targetGetter";
void set targetSetter(String value) {
lastSetterValue = "$name.targetSetter: $value";
}
String subTargetMethod() => "$name.subTargetMethod";
String get subTargetGetter => "$name.subTargetGetter";
void set subTargetSetter(String value) {
lastSetterValue = "$name.subTargetSetter: $value";
}
List<T> get typedList => <T>[];
}
extension E2 on SubTarget<Object> {
static String name = "SubTarget<Object>";
String e1() => "$name.e1";
String e2() => "$name.e2";
String targetMethod() => "$name.targetMethod";
String get targetGetter => "$name.targetGetter";
void set targetSetter(String value) {
lastSetterValue = "$name.targetSetter: $value";
}
String subTargetMethod() => "$name.subTargetMethod";
String get subTargetGetter => "$name.subTargetGetter";
void set subTargetSetter(String value) {
lastSetterValue = "$name.subTargetSetter: $value";
}
}
extension E3<T> on Target<T> {
static String name = "Target<T>";
String e1() => "$name.e1";
String e2() => "$name.e2";
String e3() => "$name.e3";
String targetMethod() => "$name.targetMethod";
String get targetGetter => "$name.targetGetter";
void set targetSetter(String value) {
lastSetterValue = "$name.targetSetter: $value";
}
String subTargetMethod() => "$name.subTargetMethod";
String get subTargetGetter => "$name.subTargetGetter";
void set subTargetSetter(String value) {
lastSetterValue = "$name.subTargetSetter: $value";
}
List<T> get typedList => <T>[];
}
extension E4 on Target<Object> {
static String name = "Target<Object>";
String e1() => "$name.e1";
String e2() => "$name.e2";
String e3() => "$name.e3";
String e4() => "$name.e4";
String targetMethod() => "$name.targetMethod";
String get targetGetter => "$name.targetGetter";
void set targetSetter(String value) {
lastSetterValue = "$name.targetSetter: $value";
}
String subTargetMethod() => "$name.subTargetMethod";
String get subTargetGetter => "$name.subTargetGetter";
void set subTargetSetter(String value) {
lastSetterValue = "$name.subTargetSetter: $value";
}
}
extension E5<T> on T {
static String name = "T";
String e1() => "$name.e1";
String e2() => "$name.e2";
String e3() => "$name.e3";
String e4() => "$name.e4";
String e5() => "$name.e5";
String targetMethod() => "$name.targetMethod";
String get targetGetter => "$name.targetGetter";
void set targetSetter(String value) {
lastSetterValue = "$name.targetSetter: $value";
}
String subTargetMethod() => "$name.subTargetMethod";
String get subTargetGetter => "$name.subTargetGetter";
void set subTargetSetter(String value) {
lastSetterValue = "$name.subTargetSetter: $value";
}
List<T> get typedList => <T>[];
}
extension E6 on Object {
static String name = "Object";
String e1() => "$name.e1";
String e2() => "$name.e2";
String e3() => "$name.e3";
String e4() => "$name.e4";
String e5() => "$name.e5";
String e6() => "$name.e6";
String targetMethod() => "$name.targetMethod";
String get targetGetter => "$name.targetGetter";
void set targetSetter(String value) {
lastSetterValue = "$name.targetSetter: $value";
}
String subTargetMethod() => "$name.subTargetMethod";
String get subTargetGetter => "$name.subTargetGetter";
void set subTargetSetter(String value) {
lastSetterValue = "$name.subTargetSetter: $value";
}
}
main() {
SubTarget<num> s1 = SubTarget<int>();
Target<num> t1 = SubTarget<int>();
SuperTarget o1 = SubTarget<int>();
Target<int> ti1 = SubTarget<int>();
;
SubTarget<int> si1 = SubTarget<int>();
;
// Interface methods take precedence.
Expect.equals("targetGetter", s1.targetGetter);
Expect.equals("targetMethod", s1.targetMethod());
s1.targetSetter = "1";
Expect.equals("targetSetter: 1", lastSetterValue);
Expect.equals("subTargetGetter", s1.subTargetGetter);
Expect.equals("subTargetMethod", s1.subTargetMethod());
s1.subTargetSetter = "2";
Expect.equals("subTargetSetter: 2", lastSetterValue);
Expect.equals("targetGetter", t1.targetGetter);
Expect.equals("targetMethod", t1.targetMethod());
t1.targetSetter = "3";
Expect.equals("targetSetter: 3", lastSetterValue);
// Methods not on the instance resolve to extension methods.
Expect.equals("Target<T>.subTargetGetter", t1.subTargetGetter);
Expect.equals("Target<T>.subTargetMethod", t1.subTargetMethod());
t1.subTargetSetter = "4";
Expect.equals("Target<T>.subTargetSetter: 4", lastSetterValue);
Expect.type<List<int>>(ti1.typedList);
Expect.type<List<int>>(si1.typedList);
Expect.type<List<SuperTarget>>(o1.typedList);
// Extension methods can be called directly using override syntax.
Expect.equals("SubTarget<T>.targetGetter", E1<num>(si1).targetGetter);
Expect.equals("SubTarget<T>.targetMethod", E1<num>(si1).targetMethod());
E1<num>(si1).targetSetter = "5";
Expect.equals("SubTarget<T>.targetSetter: 5", lastSetterValue);
Expect.equals("SubTarget<T>.subTargetGetter", E1<num>(si1).subTargetGetter);
Expect.equals("SubTarget<T>.subTargetMethod", E1<num>(si1).subTargetMethod());
E1<num>(si1).subTargetSetter = "6";
Expect.equals("SubTarget<T>.subTargetSetter: 6", lastSetterValue);
Expect.type<List<num>>(E1<num>(si1).typedList);
// Applicable methods.
Expect.equals("SubTarget<T>.e1", s1.e1());
Expect.equals("T.e2", s1.e2());
Expect.equals("T.e3", s1.e3());
Expect.equals("T.e4", s1.e4());
Expect.equals("T.e5", s1.e5());
Expect.equals("Object.e6", s1.e6());
Expect.equals("Target<T>.e1", t1.e1());
Expect.equals("Target<T>.e2", t1.e2());
Expect.equals("Target<T>.e3", t1.e3());
Expect.equals("T.e4", t1.e4());
Expect.equals("T.e5", t1.e5());
Expect.equals("Object.e6", t1.e6());
Expect.equals("T.e1", o1.e1());
Expect.equals("T.e2", o1.e2());
Expect.equals("T.e3", o1.e3());
Expect.equals("T.e4", o1.e4());
Expect.equals("T.e5", o1.e5());
Expect.equals("Object.e6", o1.e6());
}