blob: c02c7645cffd66168b55fa9b85001a8193423864 [file] [log] [blame]
// Copyright (c) 2018, 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";
typedef MapFunc<S1, S2> = void Function(Map<S1, S2>? arg);
class A<P> {
final List barTypeArguments = [];
void foo<Q, Q1 extends P, Q2 extends Q, Q3 extends P, Q4 extends Q>() {
void bar<T1 extends P, T2 extends Q>(Map<T1, T2>? arg) {
barTypeArguments
..add(T1)
..add(T2);
}
// Call with explicit type arguments.
bar<Q1, Q2>(null);
// No explicit type arguments - should be instantiated to bounds.
bar(null);
// Partial tear-off instantiation.
MapFunc<Q3, Q4> instantiated = bar;
instantiated(null);
}
}
class B<Z, P> {
final List barTypeArguments = [];
void foo<Q, Q1 extends P, Q2 extends Q1, Q3 extends Z>() {
void bar<T1 extends Map<Q1, T2>, T2 extends List<Q1>, T3 extends Z,
T4 extends Q>(Map<T1, T2>? arg) {
barTypeArguments
..add(T1)
..add(T2)
..add(T3)
..add(T4);
}
// Call with explicit type arguments.
bar<Map<Q1, List<Q2>>, List<Q1>, Q3, Q>(null);
// Partial tear-off instantiation.
MapFunc<Map<Q2, List<Q1>>, List<Q1>> instantiated = bar;
instantiated(null);
}
}
class C<P> {
final List barTypeArguments = [];
void foo<Q1>() {
void bar<T1>(List<T1>? arg) {
void bar2<T2 extends Map<Q1, T1>>(List<T2>? arg) {
barTypeArguments..add(T2);
}
dynamic f = bar2;
f(null);
}
// Call with explicit type arguments.
bar<int>(null);
}
}
abstract class MyIterable implements Iterable {}
main() {
final a = new A<num>();
a.foo<Iterable, int, List, double, MyIterable>();
Expect.listEquals(
[int, List, num, Iterable, double, MyIterable], a.barTypeArguments);
// Test instantiation to bounds in the enclosing method.
dynamic b = new A<int>();
b.foo();
Expect.listEquals(
[int, dynamic, int, dynamic, int, dynamic], b.barTypeArguments);
final c = new B<String, num>();
c.foo<Iterable, num, int, String>();
Expect.listEquals([
Map<num, List<int>>,
List<num>,
String,
Iterable,
Map<int, List<num>>,
List<num>,
String,
Iterable,
], c.barTypeArguments);
// Test instantiation to bounds in the enclosing method.
dynamic d = new B<int, String>();
d.foo();
Expect.listEquals([
Map<String, List<String>>,
List<String>,
int,
dynamic,
Map<String, List<String>>,
List<String>,
int,
dynamic,
], d.barTypeArguments);
final e = new C<int>();
e.foo<num>();
Expect.listEquals([Map<num, int>], e.barTypeArguments);
}