-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Add generic method instantiation tests
- Loading branch information
Showing
9 changed files
with
371 additions
and
0 deletions.
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A01_t01.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Let `i` be a property extraction expression of the form `e?.id`, | ||
/// `e.id`, or `super.id`, which is statically resolved to denote an instance | ||
/// method named `id`, and let `G` be the static type of `i`. Consider the | ||
/// situation where `G` is a function type of the form | ||
/// `T0 Function<X1 ◁B1, ..., Xs ◁Bs>(parameters)` with `s > 0` (that is, `G` is | ||
/// a generic function type), and the context type is a non-generic function | ||
/// type `F`. In this situation a compile-time error occurs, except when generic | ||
/// function type instantiation succeeds, that is: | ||
/// | ||
/// Type inference is applied to `G` with context type `F`, and it succeeds, | ||
/// yielding the actual type argument list `T1, ..., Ts`. | ||
/// | ||
/// @description Check that it is a compile-time error if a generic method | ||
/// tear-off cannot be assigned to a non-generic function. | ||
/// @author [email protected] | ||
class C1 { | ||
X foo<X extends num>(X x) => x; | ||
} | ||
|
||
class C2<T extends num> { | ||
X foo<X extends T>(X x) => x; | ||
} | ||
|
||
void main() { | ||
C1 c1 = C1(); | ||
String Function(int) f1 = c1.foo; | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
int Function(num) f2 = c1.foo; | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
|
||
var c2 = C2<int>(); | ||
String Function(int) f3 = c2.foo; | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
int Function(num) f4 = c2.foo; | ||
// ^^^^^^ | ||
// [analyzer] unspecified | ||
// [cfe] unspecified | ||
} |
32 changes: 32 additions & 0 deletions
32
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A01_t02.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Let `i` be a property extraction expression of the form `e?.id`, | ||
/// `e.id`, or `super.id`, which is statically resolved to denote an instance | ||
/// method named `id`, and let `G` be the static type of `i`. Consider the | ||
/// situation where `G` is a function type of the form | ||
/// `T0 Function<X1 ◁B1, ..., Xs ◁Bs>(parameters)` with `s > 0` (that is, `G` is | ||
/// a generic function type), and the context type is a non-generic function | ||
/// type `F`. In this situation a compile-time error occurs, except when generic | ||
/// function type instantiation succeeds, that is: | ||
/// | ||
/// Type inference is applied to `G` with context type `F`, and it succeeds, | ||
/// yielding the actual type argument list `T1, ..., Ts`. | ||
/// | ||
/// @description Check that it is a run-time error if a generic method | ||
/// tear-off cannot be assigned to a non-generic function. | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class C<T extends num> { | ||
X foo<X extends T>(X x) => x; | ||
} | ||
|
||
void main() { | ||
C<num> c = C<int>(); | ||
Expect.throws(() { | ||
num Function(num) f = c.foo; | ||
}); | ||
} |
36 changes: 36 additions & 0 deletions
36
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A01_t03.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Let `i` be a property extraction expression of the form `e?.id`, | ||
/// `e.id`, or `super.id`, which is statically resolved to denote an instance | ||
/// method named `id`, and let `G` be the static type of `i`. Consider the | ||
/// situation where `G` is a function type of the form | ||
/// `T0 Function<X1 ◁B1, ..., Xs ◁Bs>(parameters)` with `s > 0` (that is, `G` is | ||
/// a generic function type), and the context type is a non-generic function | ||
/// type `F`. In this situation a compile-time error occurs, except when generic | ||
/// function type instantiation succeeds, that is: | ||
/// | ||
/// Type inference is applied to `G` with context type `F`, and it succeeds, | ||
/// yielding the actual type argument list `T1, ..., Ts`. | ||
/// | ||
/// @description Check that it is not an error if a type inference is applied to | ||
/// `G` with context type `F`, and it succeeds | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class A { | ||
X fi<X extends num>(X x) => x; | ||
} | ||
|
||
class B extends A { | ||
X fi<X extends num>(X x, [List<X>? xs]) => x; | ||
} | ||
|
||
void main() { | ||
A a = B(); | ||
int Function(int) f = a.fi; | ||
Expect.equals(42, f(42)); | ||
Expect.equals(42, (f as dynamic)(42, [0])); | ||
} |
41 changes: 41 additions & 0 deletions
41
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A02_t01.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Let `i` be a property extraction expression of the form `e?.id`, | ||
/// `e.id`, or `super.id`, which is statically resolved to denote an instance | ||
/// method named `id`, and let `G` be the static type of `i`. Consider the | ||
/// situation where `G` is a function type of the form | ||
/// `T0 Function<X1 ◁B1, ..., Xs ◁Bs>(parameters)` with `s > 0` (that is, `G` is | ||
/// a generic function type), and the context type is a non-generic function | ||
/// type `F`. | ||
/// ... | ||
/// Consider the situation where generic function type instantiation succeeded. | ||
/// Let `gmiNameid` be a fresh name which is associated with `id`, which is | ||
/// private `if` and only if id is private. | ||
/// ... | ||
/// The program is then modified as follows: | ||
/// • When `i` is `e?.id`: Replace `i` by `e?.gmiNameid<T1, ..., Ts>()`. | ||
/// • When `i` is `e.id`: Replace `i` by `e.gmiNameid<T1, ..., Ts>()`. | ||
/// • When `i` is `super.id`: Replace `i` by `super.gmiNameid<T1, ..., Ts>()`. | ||
/// | ||
/// @description Check that generic method instantiation may have a form `e?.id` | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class C { | ||
int v; | ||
C(this.v); | ||
X foo<X extends num>(X x) => x + v as X; | ||
} | ||
|
||
void main() { | ||
C? c1 = 2 > 1 ? C(1) : null; | ||
int Function(int)? f1 = c1?.foo; | ||
Expect.equals(c1?.foo(42), f1?.call(42)); | ||
|
||
C? c2 = 1 > 2 ? C(1) : null; | ||
double Function(double)? f2 = c2?.foo; | ||
Expect.isNull(f2); | ||
} |
37 changes: 37 additions & 0 deletions
37
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A02_t02.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Let `i` be a property extraction expression of the form `e?.id`, | ||
/// `e.id`, or `super.id`, which is statically resolved to denote an instance | ||
/// method named `id`, and let `G` be the static type of `i`. Consider the | ||
/// situation where `G` is a function type of the form | ||
/// `T0 Function<X1 ◁B1, ..., Xs ◁Bs>(parameters)` with `s > 0` (that is, `G` is | ||
/// a generic function type), and the context type is a non-generic function | ||
/// type `F`. | ||
/// ... | ||
/// Consider the situation where generic function type instantiation succeeded. | ||
/// Let `gmiNameid` be a fresh name which is associated with `id`, which is | ||
/// private `if` and only if id is private. | ||
/// ... | ||
/// The program is then modified as follows: | ||
/// • When `i` is `e?.id`: Replace `i` by `e?.gmiNameid<T1, ..., Ts>()`. | ||
/// • When `i` is `e.id`: Replace `i` by `e.gmiNameid<T1, ..., Ts>()`. | ||
/// • When `i` is `super.id`: Replace `i` by `super.gmiNameid<T1, ..., Ts>()`. | ||
/// | ||
/// @description Check that generic method instantiation may have a form `e.id`. | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class C<T extends num> { | ||
int v; | ||
C(this.v); | ||
X foo<X extends T>(X x) => x + v as X; | ||
} | ||
|
||
void main() { | ||
C c1 = C(1); | ||
int Function(int) f1 = c1.foo; | ||
Expect.equals(c1.foo(42), f1(42)); | ||
} |
45 changes: 45 additions & 0 deletions
45
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A02_t03.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Let `i` be a property extraction expression of the form `e?.id`, | ||
/// `e.id`, or `super.id`, which is statically resolved to denote an instance | ||
/// method named `id`, and let `G` be the static type of `i`. Consider the | ||
/// situation where `G` is a function type of the form | ||
/// `T0 Function<X1 ◁B1, ..., Xs ◁Bs>(parameters)` with `s > 0` (that is, `G` is | ||
/// a generic function type), and the context type is a non-generic function | ||
/// type `F`. | ||
/// ... | ||
/// Consider the situation where generic function type instantiation succeeded. | ||
/// Let `gmiNameid` be a fresh name which is associated with `id`, which is | ||
/// private `if` and only if id is private. | ||
/// ... | ||
/// The program is then modified as follows: | ||
/// • When `i` is `e?.id`: Replace `i` by `e?.gmiNameid<T1, ..., Ts>()`. | ||
/// • When `i` is `e.id`: Replace `i` by `e.gmiNameid<T1, ..., Ts>()`. | ||
/// • When `i` is `super.id`: Replace `i` by `super.gmiNameid<T1, ..., Ts>()`. | ||
/// | ||
/// @description Check that generic method instantiation may have a form | ||
/// `super.id`. | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class A { | ||
String foo<X>(X x) => "A:$X"; | ||
} | ||
|
||
class C extends A { | ||
int v; | ||
C(this.v); | ||
String foo<X>(X x) => "C:$X"; | ||
|
||
test() { | ||
String Function(int) f1 = super.foo; | ||
Expect.equals("A:int", f1(42)); | ||
} | ||
} | ||
|
||
void main() { | ||
C(1).test(); | ||
} |
45 changes: 45 additions & 0 deletions
45
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A03_t01.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Consider the situation where generic function type instantiation | ||
/// succeeded. Let `gmiNameid` be a fresh name which is associated with `id`, | ||
/// which is private `if` and only if id is private. | ||
/// ... | ||
/// Let `o` be an instance of a class which contains an implicitly induced | ||
/// declaration of `gmiNameid` as described above. Consider the situation where | ||
/// the program evaluates two invocations of this method with the same receiver | ||
/// `o`, and with actual type arguments whose actual values are the same types | ||
/// `t1, ..., ts` for both invocations, and assume that the invocations returned | ||
/// the instances `o1` respectively `o2`. It is then guaranteed that `o1` and | ||
/// `o2` are equal according to operator ‘==’. | ||
/// | ||
/// @description Check that two generic method instantiation of the same method | ||
/// of a form `e?.id` are equal according to the `==` operator. | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class C1 { | ||
int v; | ||
C1(this.v); | ||
X foo<X extends num>(X x) => x + v as X; | ||
} | ||
|
||
class C2<T extends num> { | ||
T v; | ||
C2(this.v); | ||
X foo<X extends T>(X x) => x + v as X; | ||
} | ||
|
||
void main() { | ||
C1? c1 = 2 > 1 ? C1(1) : null; | ||
int Function(int)? f1 = c1?.foo; | ||
int Function(int)? f2 = c1?.foo; | ||
Expect.isTrue(f1 == f2); | ||
|
||
C2<num>? c2 = 2 > 1 ? C2(2) : null; | ||
int Function(int)? f3 = c2?.foo; | ||
int Function(int)? f4 = c2?.foo; | ||
Expect.isTrue(f3 == f4); | ||
} |
45 changes: 45 additions & 0 deletions
45
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A03_t02.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Consider the situation where generic function type instantiation | ||
/// succeeded. Let `gmiNameid` be a fresh name which is associated with `id`, | ||
/// which is private `if` and only if id is private. | ||
/// ... | ||
/// Let `o` be an instance of a class which contains an implicitly induced | ||
/// declaration of `gmiNameid` as described above. Consider the situation where | ||
/// the program evaluates two invocations of this method with the same receiver | ||
/// `o`, and with actual type arguments whose actual values are the same types | ||
/// `t1, ..., ts` for both invocations, and assume that the invocations returned | ||
/// the instances `o1` respectively `o2`. It is then guaranteed that `o1` and | ||
/// `o2` are equal according to operator ‘==’. | ||
/// | ||
/// @description Check that two generic method instantiation of the same method | ||
/// of a form `e.id` are equal according to the `==` operator. | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class C1 { | ||
int v; | ||
C1(this.v); | ||
X foo<X extends num>(X x) => x + v as X; | ||
} | ||
|
||
class C2<T extends num> { | ||
T v; | ||
C2(this.v); | ||
X foo<X extends T>(X x) => x + v as X; | ||
} | ||
|
||
void main() { | ||
var c1 = C1(1); | ||
int Function(int) f1 = c1.foo; | ||
int Function(int) f2 = c1.foo; | ||
Expect.isTrue(f1 == f2); | ||
|
||
var c2 = C2<num>(2); | ||
int Function(int) f3 = c2.foo; | ||
int Function(int) f4 = c2.foo; | ||
Expect.isTrue(f3 == f4); | ||
} |
41 changes: 41 additions & 0 deletions
41
.../Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A03_t03.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) 2025, 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. | ||
|
||
/// @assertion Consider the situation where generic function type instantiation | ||
/// succeeded. Let `gmiNameid` be a fresh name which is associated with `id`, | ||
/// which is private `if` and only if id is private. | ||
/// ... | ||
/// Let `o` be an instance of a class which contains an implicitly induced | ||
/// declaration of `gmiNameid` as described above. Consider the situation where | ||
/// the program evaluates two invocations of this method with the same receiver | ||
/// `o`, and with actual type arguments whose actual values are the same types | ||
/// `t1, ..., ts` for both invocations, and assume that the invocations returned | ||
/// the instances `o1` respectively `o2`. It is then guaranteed that `o1` and | ||
/// `o2` are equal according to operator ‘==’. | ||
/// | ||
/// @description Check that two generic method instantiation of the same method | ||
/// of a form `super.id` are equal according to the `==` operator. | ||
/// @author [email protected] | ||
import '../../../../Utils/expect.dart'; | ||
|
||
class A { | ||
X foo<X extends num>(X x) => x; | ||
} | ||
|
||
class C extends A { | ||
int v; | ||
C(this.v); | ||
X foo<X extends num>(X x) => x + v as X; | ||
|
||
void test() { | ||
int Function(int) f1 = super.foo; | ||
int Function(int) f2 = super.foo; | ||
Expect.isTrue(f1 == f2); | ||
} | ||
} | ||
|
||
void main() { | ||
C(1).test(); | ||
} |