blob: 3cc922457018b379cf683f791cacbe869b944886 [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.
class Class<T extends num> {
T field1;
T field2;
Class(this.field1, this.field2);
}
extension Extension1<T extends num> on Class<T> {
static String? latestType;
T get field {
latestType = '$T';
return field1;
}
void set field(T value) {
latestType = '$T';
field1 = value;
}
T method() {
latestType = '$T';
return field1;
}
T genericMethod<S extends num>(S t) {
latestType = '$T:$S';
return (field1 + t) as T;
}
}
extension Extension2<T extends num> on Class<T> {
T get field => field2;
void set field(T value) {
field2 = value;
}
T method() => field2;
T genericMethod<S extends num>(S t) => (field2 + t) as T;
}
main() {
Class<int> c = new Class<int>(42, 87);
expect(42, Extension1<num>(c).field);
expect('num', Extension1.latestType);
expect(42, Extension1<int>(c).field);
expect('int', Extension1.latestType);
expect(87, Extension2<num>(c).field);
expect(42, Extension1<num>(c).method());
expect('num', Extension1.latestType);
expect(42, Extension1<int>(c).method());
expect('int', Extension1.latestType);
expect(87, Extension2<num>(c).method());
var tearOffNumber1 = Extension1<num>(c).method;
var tearOffInteger1 = Extension1<int>(c).method;
var tearOff2 = Extension2<num>(c).method;
expect(42, tearOffNumber1());
expect('num', Extension1.latestType);
expect(42, tearOffInteger1());
expect('int', Extension1.latestType);
expect(87, tearOff2());
expect(52, Extension1<num>(c).genericMethod(10));
expect('num:int', Extension1.latestType);
expect(52, Extension1<int>(c).genericMethod(10));
expect('int:int', Extension1.latestType);
expect(97, Extension2<num>(c).genericMethod(10));
expect(52, Extension1<num>(c).genericMethod<num>(10));
expect('num:num', Extension1.latestType);
expect(52, Extension1<int>(c).genericMethod<num>(10));
expect('int:num', Extension1.latestType);
expect(97, Extension2<num>(c).genericMethod<num>(10));
expect(52, Extension1(c).genericMethod(10));
expect('int:int', Extension1.latestType);
expect(52, Extension1(c).genericMethod<num>(10));
expect('int:num', Extension1.latestType);
expect(52, Extension1(c).genericMethod<int>(10));
expect('int:int', Extension1.latestType);
var genericTearOffNumber1 = Extension1<num>(c).genericMethod;
var genericTearOffInteger1 = Extension1<int>(c).genericMethod;
var genericTearOff2 = Extension2<num>(c).genericMethod;
expect(52, genericTearOffNumber1(10));
expect('num:int', Extension1.latestType);
expect(52, genericTearOffInteger1(10));
expect('int:int', Extension1.latestType);
expect(97, genericTearOff2(10));
expect(52, genericTearOffNumber1<num>(10));
expect('num:num', Extension1.latestType);
expect(52, genericTearOffInteger1<num>(10));
expect('int:num', Extension1.latestType);
expect(97, genericTearOff2<num>(10));
expect(23, Extension1<num>(c).field = 23);
expect('num', Extension1.latestType);
expect(23, Extension1<int>(c).field = 23);
expect('int', Extension1.latestType);
expect(67, Extension2<num>(c).field = 67);
expect(23, Extension1<num>(c).field);
expect(67, Extension2<num>(c).field);
}
expect(expected, actual) {
if (expected != actual) {
throw 'Mismatch: expected=$expected, actual=$actual';
}
}