Skip to content

Commit

Permalink
dart-lang#3054. Add more method clozurization tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrekhov committed Jan 29, 2025
1 parent bc52d30 commit bb0e190
Show file tree
Hide file tree
Showing 6 changed files with 397 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// 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 `o` be an object, and let `u` be a fresh final variable bound
/// to o. The closurization of method `f` on object `o` is defined to be
/// equivalent to:
/// ```
/// - <X1 extends B′1, ..., Xs extends B′s>
/// (T1 p1, ..., Tn pn, {Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk}) =>
/// u.m<X1, ..., Xs>(p1, ..., pn, pn+1: pn+1, ..., pn+k: pn+k);
/// ```
/// where `f` is an instance method named `m` which has type parameter
/// declarations `X1 extends B1, ..., Xs extends Bs`, required parameters
/// `p1, ..., pn`, and named parameters `pn+1, ..., pn+k` with defaults
/// `d1, ..., dk`, using `null` for parameters whose default value is not
/// specified.
/// ...
/// The parameter types `Tj,j ∈ 1..n + k`, are determined as follows: Let the
/// method declaration `D` be the implementation of `m` which is invoked by the
/// expression in the body. Let `T` be the class that contains D.
/// ...
/// If `T` is a non-generic class then for `j ∈ 1..n+k, Tj` is a type
/// annotation that denotes the same type as that which is denoted by the type
/// annotation on the corresponding parameter declaration in `D`. If that
/// parameter declaration has no type annotation then `Tj` is `dynamic`.
///
/// @description Check that if `T` is a non-generic class then for
/// `j ∈ 1..n+k, Tj` is a type annotation that denotes the same type as that
/// which is denoted by the type annotation on the corresponding parameter
/// declaration in `D` or `dynamic` if the parameter declaration has no type
/// annotation.
/// @author [email protected]
import '../../../../Utils/expect.dart';
import '../../../../Utils/static_type_helper.dart';

class C<Z extends String> {
Y m<X, Y extends num>(Z r1, Y r2, r3, {X? p1, int p2 = 0, p3}) {
return 42 as Y;
}
}

main() {
var o = C<String>();
final f = o.m;
f.expectStaticType<
Exactly<
Y Function<X, Y extends num>(
String r1,
Y r2,
dynamic r3, {
X? p1,
int p2,
dynamic p3,
})
>
>();

Expect.isTrue(
f is Y Function<X, Y extends num>( // ignore: unnecessary_type_check
String r1,
Y r2,
dynamic r3, {
X? p1,
int p2,
dynamic p3,
})
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// 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 `o` be an object, and let `u` be a fresh final variable bound
/// to o. The closurization of method `f` on object `o` is defined to be
/// equivalent to:
/// ```
/// - <X1 extends B′1, ..., Xs extends B′s>
/// (T1 p1, ..., Tn pn, {Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk}) =>
/// u.m<X1, ..., Xs>(p1, ..., pn, pn+1: pn+1, ..., pn+k: pn+k);
/// ```
/// where `f` is an instance method named `m` which has type parameter
/// declarations `X1 extends B1, ..., Xs extends Bs`, required parameters
/// `p1, ..., pn`, and named parameters `pn+1, ..., pn+k` with defaults
/// `d1, ..., dk`, using `null` for parameters whose default value is not
/// specified.
/// ...
/// The parameter types `Tj,j ∈ 1..n + k`, are determined as follows: Let the
/// method declaration `D` be the implementation of `m` which is invoked by the
/// expression in the body. Let `T` be the class that contains D.
/// ...
/// Otherwise `T` is a generic instantiation of a generic class `G`. Let
/// `X′′1,...,X′′s′′` be the formal type parameters of `G`, and
/// `t′′1,...,t′′s′′` be the actual type arguments of `o` at `T`. Then `Tj` is
/// a type annotation that denotes `[t′′ 1/X′′ 1,...,t′′ s′′ /X′′ s′′]Sj`,
/// where `Sj` is the type annotation of the corresponding parameter in `D`. If
/// that parameter declaration has no type annotation then `Tj` is `dynamic`.
///
/// @description Check that if `T` is a generic instantiation of a generic class
/// `G` then `Tj` is a type annotation that denotes
/// `[t′′ 1/X′′ 1,...,t′′ s′′ /X′′ s′′]Sj`, where `Sj` is the type annotation of
/// the corresponding parameter in `D`. If that parameter declaration has no
/// type annotation then `Tj` is `dynamic`.
/// @author [email protected]
import '../../../../Utils/expect.dart';
import '../../../../Utils/static_type_helper.dart';

class C<Z extends String> {
List<Y> m<X, Y extends num>(
List<Z> r1,
List<Y> r2,
List r3, {
List<X>? p1,
List<int> p2 = const [],
List p3 = const [],
}) {
return <Y>[];
}
}

main() {
var o = C<String>();
final f = o.m;
f.expectStaticType<
Exactly<
List<Y> Function<X, Y extends num>(
List<String> r1,
List<Y> r2,
List<dynamic> r3, {
List<X>? p1,
List<int> p2,
List<dynamic> p3,
})
>
>();

Expect.isTrue(
f is List<Y> Function<X, Y extends num>( // ignore: unnecessary_type_check
List<String> r1,
List<Y> r2,
List<dynamic> r3, {
List<X>? p1,
List<int> p2,
List<dynamic> p3,
})
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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 `o` be an object, and let `u` be a fresh final variable bound
/// to o. The closurization of method `f` on object `o` is defined to be
/// equivalent to:
/// ```
/// - <X1 extends B′1, ..., Xs extends B′s>
/// (T1 p1, ..., Tn pn, {Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk}) =>
/// u.m<X1, ..., Xs>(p1, ..., pn, pn+1: pn+1, ..., pn+k: pn+k);
/// ```
/// where `f` is an instance method named `m` which has type parameter
/// declarations `X1 extends B1, ..., Xs extends Bs`, required parameters
/// `p1, ..., pn`, and named parameters `pn+1, ..., pn+k` with defaults
/// `d1, ..., dk`, using `null` for parameters whose default value is not
/// specified.
/// ...
/// There is one way in which the function object yielded by the instance
/// method closurization differs from the function object obtained by function
/// closurization on the above mentioned function literal: Assume that `o1` and
/// `o2` are objects, `m` is an identifier, and `c1` and `c2` are function
/// objects obtained by closurization of `m` on `o1` respectively `o2`. Then
/// `c1 == c2` evaluates to `true` if and only if `o1` and `o2` is the same
/// object.
///
/// @description Check that if `o1` and `o2` are objects, `m` is an identifier,
/// and `c1` and `c2` are function objects obtained by closurization of `m` on
/// `o1` respectively `o2`, then `c1 == c2` evaluates to `true` if and only if
/// `o1` and `o2` is the same object.
/// @author [email protected]
import '../../../../Utils/expect.dart';

class C {
num m(int r1, {String p1 = ""}) => r1;
}

main() {
C o1 = C();
C o2 = C();
final f1 = o1.m;
final f2 = o1.m;
final f3 = o2.m;

Expect.equals(f1, f2);
Expect.notEquals(f1, f3);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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 `o` be an object, and let `u` be a fresh final variable bound
/// to o. The closurization of method `f` on object `o` is defined to be
/// equivalent to:
/// ...
/// ```
/// - <X1 extends B′1, ..., Xs extends B′s>
/// (T1 p1, ..., Tn pn, [Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk]) =>
/// u.m<X1, ..., Xs>(p1, ..., pn+k);
/// ```
/// where `f` is an instance method named `m` which has type parameter
/// declarations `X1 extends B1, ..., Xs extends Bs`, required parameters
/// `p1, ..., pn`, and optional positional parameters `pn+1, ..., pn+k` with
/// defaults `d1, ..., dk`, using `null` for parameters whose default value is
/// not specified.
/// ...
/// The parameter types `Tj,j ∈ 1..n + k`, are determined as follows: Let the
/// method declaration `D` be the implementation of `m` which is invoked by the
/// expression in the body. Let `T` be the class that contains D.
/// ...
/// If `T` is a non-generic class then for `j ∈ 1..n+k, Tj` is a type
/// annotation that denotes the same type as that which is denoted by the type
/// annotation on the corresponding parameter declaration in `D`. If that
/// parameter declaration has no type annotation then `Tj` is `dynamic`.
///
/// @description Check that if `T` is a non-generic class then for
/// `j ∈ 1..n+k, Tj` is a type annotation that denotes the same type as that
/// which is denoted by the type annotation on the corresponding parameter
/// declaration in `D` or `dynamic` if the parameter declaration has no type
/// annotation.
/// @author [email protected]
import '../../../../Utils/expect.dart';
import '../../../../Utils/static_type_helper.dart';

class C<Z extends String> {
Y m<X, Y extends num>(Z r1, Y r2, r3, [X? p1, int p2 = 0, p3]) {
return 42 as Y;
}
}

main() {
var o = C<String>();
final f = o.m;
f.expectStaticType<
Exactly<
Y Function<X, Y extends num>(
String r1,
Y r2,
dynamic r3, [
X? p1,
int p2,
dynamic p3,
])
>
>();

Expect.isTrue(
f is Y Function<X, Y extends num>( // ignore: unnecessary_type_check
String r1,
Y r2,
dynamic r3, [
X? p1,
int p2,
dynamic p3,
])
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// 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 `o` be an object, and let `u` be a fresh final variable bound
/// to o. The closurization of method `f` on object `o` is defined to be
/// equivalent to:
/// ...
/// ```
/// - <X1 extends B′1, ..., Xs extends B′s>
/// (T1 p1, ..., Tn pn, [Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk]) =>
/// u.m<X1, ..., Xs>(p1, ..., pn+k);
/// ```
/// where `f` is an instance method named `m` which has type parameter
/// declarations `X1 extends B1, ..., Xs extends Bs`, required parameters
/// `p1, ..., pn`, and optional positional parameters `pn+1, ..., pn+k` with
/// defaults `d1, ..., dk`, using `null` for parameters whose default value is
/// not specified.
/// ...
/// The parameter types `Tj,j ∈ 1..n + k`, are determined as follows: Let the
/// method declaration `D` be the implementation of `m` which is invoked by the
/// expression in the body. Let `T` be the class that contains D.
/// ...
/// Otherwise `T` is a generic instantiation of a generic class `G`. Let
/// `X′′1,...,X′′s′′` be the formal type parameters of `G`, and
/// `t′′1,...,t′′s′′` be the actual type arguments of `o` at `T`. Then `Tj` is
/// a type annotation that denotes `[t′′ 1/X′′ 1,...,t′′ s′′ /X′′ s′′]Sj`,
/// where `Sj` is the type annotation of the corresponding parameter in `D`. If
/// that parameter declaration has no type annotation then `Tj` is `dynamic`.
///
/// @description Check that if `T` is a generic instantiation of a generic class
/// `G` then `Tj` is a type annotation that denotes
/// `[t′′ 1/X′′ 1,...,t′′ s′′ /X′′ s′′]Sj`, where `Sj` is the type annotation of
/// the corresponding parameter in `D`. If that parameter declaration has no
/// type annotation then `Tj` is `dynamic`.
/// @author [email protected]
import '../../../../Utils/expect.dart';
import '../../../../Utils/static_type_helper.dart';

class C<Z extends String> {
List<Y> m<X, Y extends num>(
List<Z> r1,
List<Y> r2,
List r3, [
List<X>? p1,
List<int> p2 = const [],
List p3 = const [],
]) {
return <Y>[];
}
}

main() {
var o = C<String>();
final f = o.m;
f.expectStaticType<
Exactly<
List<Y> Function<X, Y extends num>(
List<String> r1,
List<Y> r2,
List<dynamic> r3, [
List<X>? p1,
List<int> p2,
List<dynamic> p3,
])
>
>();

Expect.isTrue(
f is List<Y> Function<X, Y extends num>( // ignore: unnecessary_type_check
List<String> r1,
List<Y> r2,
List<dynamic> r3, [
List<X>? p1,
List<int> p2,
List<dynamic> p3,
])
);
}
Loading

0 comments on commit bb0e190

Please sign in to comment.