|  | // 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. | 
|  |  | 
|  | // Tests extension method resolution type inference. | 
|  |  | 
|  | import "package:expect/expect.dart"; | 
|  |  | 
|  | void main() { | 
|  | List<num> numList = <int>[]; | 
|  | // Inference of E1(numList), implicit or explicit, is the same as | 
|  | // for C1(numList), which infers `num`. | 
|  | var numListInstance1 = C1<num>(numList); | 
|  |  | 
|  | Expect.type<List<num>>(numList.argList1); | 
|  | sameType(numListInstance1.argDynList1, numList.argDynList1); | 
|  | sameType(numListInstance1.selfList1, numList.selfList1); | 
|  |  | 
|  | Expect.type<List<num>>(E1(numList).argList1); | 
|  | sameType(numListInstance1.argDynList1, E1(numList).argDynList1); | 
|  | sameType(numListInstance1.selfList1, E1(numList).selfList1); | 
|  |  | 
|  | var numListInstance2 = C2<List<num>>(numList); | 
|  |  | 
|  | Expect.type<List<List<num>>>(numList.argList2); | 
|  | sameType(numListInstance2.argDynList2, numList.argDynList2); | 
|  | sameType(numListInstance2.selfList2, numList.selfList2); | 
|  |  | 
|  | Expect.type<List<List<num>>>(E2(numList).argList2); | 
|  | sameType(numListInstance2.argDynList2, E2(numList).argDynList2); | 
|  | sameType(numListInstance2.selfList2, E2(numList).selfList2); | 
|  |  | 
|  | Pair<int, double> pair = Pair(1, 2.5); | 
|  | var pairInstance3 = C3<int, double>(pair); | 
|  |  | 
|  | Expect.type<List<int>>(pair.argList3); | 
|  | Expect.type<List<double>>(pair.arg2List3); | 
|  | sameType(pairInstance3.argDynList3, pair.argDynList3); | 
|  | sameType(pairInstance3.arg2DynList3, pair.arg2DynList3); | 
|  | sameType(pairInstance3.selfList3, pair.selfList3); | 
|  |  | 
|  | Expect.type<List<int>>(E3(pair).argList3); | 
|  | Expect.type<List<double>>(E3(pair).arg2List3); | 
|  | sameType(pairInstance3.argDynList3, E3(pair).argDynList3); | 
|  | sameType(pairInstance3.arg2DynList3, E3(pair).arg2DynList3); | 
|  | sameType(pairInstance3.selfList3, E3(pair).selfList3); | 
|  |  | 
|  | var pairInstance4 = C4<num>(pair); | 
|  |  | 
|  | Expect.type<List<num>>(pair.argList4); | 
|  | sameType(pairInstance4.argDynList4, pair.argDynList4); | 
|  | sameType(pairInstance4.selfList4, pair.selfList4); | 
|  |  | 
|  | Expect.type<List<num>>(E4(pair).argList4); | 
|  | sameType(pairInstance4.argDynList4, E4(pair).argDynList4); | 
|  | sameType(pairInstance4.selfList4, E4(pair).selfList4); | 
|  |  | 
|  | List<int> intList = <int>[1]; | 
|  | var intListInstance5 = C5<int>(intList); | 
|  |  | 
|  | Expect.type<List<int>>(intList.argList5); | 
|  | sameType(intListInstance5.argDynList5, intList.argDynList5); | 
|  | sameType(intListInstance5.selfList5, intList.selfList5); | 
|  |  | 
|  | Expect.type<List<int>>(E5(intList).argList5); | 
|  | sameType(intListInstance5.argDynList5, E5(intList).argDynList5); | 
|  | sameType(intListInstance5.selfList5, E5(intList).selfList5); | 
|  | } | 
|  |  | 
|  | void sameType(o1, o2) { | 
|  | Expect.equals(o1.runtimeType, o2.runtimeType); | 
|  | } | 
|  |  | 
|  | extension E1<T> on List<T> { | 
|  | List<T> get argList1 => <T>[]; | 
|  | List<Object?> get argDynList1 => <T>[]; | 
|  | List<Object?> get selfList1 { | 
|  | var result = [this]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | class C1<T> { | 
|  | List<T> self; | 
|  | C1(this.self); | 
|  | List<T> get argList1 => <T>[]; | 
|  | List<Object?> get argDynList1 => <T>[]; | 
|  | List<Object?> get selfList1 { | 
|  | var result = [self]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | extension E2<T> on T { | 
|  | List<T> get argList2 => <T>[]; | 
|  | List<Object?> get argDynList2 => <T>[]; | 
|  | List<Object?> get selfList2 { | 
|  | var result = [this]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | class C2<T> { | 
|  | T self; | 
|  | C2(this.self); | 
|  | List<T> get argList2 => <T>[]; | 
|  | List<Object?> get argDynList2 => <T>[]; | 
|  | List<Object?> get selfList2 { | 
|  | var result = [self]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | extension E3<S, T> on Pair<T, S> { | 
|  | List<T> get argList3 => <T>[]; | 
|  | List<Object?> get argDynList3 => <T>[]; | 
|  | List<S> get arg2List3 => <S>[]; | 
|  | List<Object?> get arg2DynList3 => <S>[]; | 
|  | List<Object?> get selfList3 { | 
|  | var result = [this]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | class C3<T, S> { | 
|  | Pair<T, S> self; | 
|  | C3(this.self); | 
|  | List<T> get argList3 => <T>[]; | 
|  | List<Object?> get argDynList3 => <T>[]; | 
|  | List<S> get arg2List3 => <S>[]; | 
|  | List<Object?> get arg2DynList3 => <S>[]; | 
|  | List<Object?> get selfList3 { | 
|  | var result = [self]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | extension E4<T> on Pair<T, T> { | 
|  | List<T> get argList4 => <T>[]; | 
|  | List<Object?> get argDynList4 => <T>[]; | 
|  | List<Object?> get selfList4 { | 
|  | var result = [this]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | class C4<T> { | 
|  | Pair<T, T> self; | 
|  | C4(this.self); | 
|  | List<T> get argList4 => <T>[]; | 
|  | List<Object?> get argDynList4 => <T>[]; | 
|  | List<Object?> get selfList4 { | 
|  | var result = [self]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | extension E5<T extends num> on List<T> { | 
|  | List<T> get argList5 => <T>[]; | 
|  | List<Object?> get argDynList5 => <T>[]; | 
|  | List<Object?> get selfList5 { | 
|  | var result = [this]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | class C5<T extends num> { | 
|  | List<T> self; | 
|  | C5(this.self); | 
|  | List<T> get argList5 => <T>[]; | 
|  | List<Object?> get argDynList5 => <T>[]; | 
|  | List<Object?> get selfList5 { | 
|  | var result = [self]; | 
|  | return result; | 
|  | } | 
|  | } | 
|  |  | 
|  | class Pair<A, B> { | 
|  | final A first; | 
|  | final B second; | 
|  | Pair(this.first, this.second); | 
|  | } |