diff --git a/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A04_t01.dart b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A04_t01.dart new file mode 100644 index 0000000000..0d7a99ae28 --- /dev/null +++ b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A04_t01.dart @@ -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: +/// ``` +/// - +/// (T1 p1, ..., Tn pn, {Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk}) => +/// u.m(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 sgrekhov22@gmail.com + +import '../../../../Utils/expect.dart'; +import '../../../../Utils/static_type_helper.dart'; + +class C { + Y m(String r1, Y r2, r3, {X? p1, int p2 = 0, p3}) { + return 42 as Y; + } +} + +main() { + var o = C(); + final f = o.m; + f.expectStaticType< + Exactly< + Y Function( + String r1, + Y r2, + dynamic r3, { + X? p1, + int p2, + dynamic p3, + }) + > + >(); + + Expect.isTrue( + f is Y Function( // ignore: unnecessary_type_check + String r1, + Y r2, + dynamic r3, { + X? p1, + int p2, + dynamic p3, + }) + ); +} diff --git a/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A05_t01.dart b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A05_t01.dart new file mode 100644 index 0000000000..6f4e9bc838 --- /dev/null +++ b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A05_t01.dart @@ -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: +/// ``` +/// - +/// (T1 p1, ..., Tn pn, {Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk}) => +/// u.m(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 sgrekhov22@gmail.com + +import '../../../../Utils/expect.dart'; +import '../../../../Utils/static_type_helper.dart'; + +class C { + List m( + List r1, + List r2, + r3, { + List? p1, + List p2 = const [], + p3 = const [], + }) { + return []; + } +} + +main() { + var o = C(); + final f = o.m; + f.expectStaticType< + Exactly< + List Function( + List r1, + List r2, + dynamic r3, { + List? p1, + List p2, + dynamic p3, + }) + > + >(); + + Expect.isTrue( + f is List Function( // ignore: unnecessary_type_check + List r1, + List r2, + dynamic r3, { + List? p1, + List p2, + dynamic p3, + }) + ); +} diff --git a/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A06_t01.dart b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A06_t01.dart new file mode 100644 index 0000000000..fe8b9da170 --- /dev/null +++ b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_named_params_A06_t01.dart @@ -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: +/// ``` +/// - +/// (T1 p1, ..., Tn pn, {Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk}) => +/// u.m(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 sgrekhov22@gmail.com + +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); +} diff --git a/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A04_t01.dart b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A04_t01.dart new file mode 100644 index 0000000000..25e362aaf6 --- /dev/null +++ b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A04_t01.dart @@ -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: +/// ... +/// ``` +/// - +/// (T1 p1, ..., Tn pn, [Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk]) => +/// u.m(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 sgrekhov22@gmail.com + +import '../../../../Utils/expect.dart'; +import '../../../../Utils/static_type_helper.dart'; + +class C { + Y m(String r1, Y r2, r3, [X? p1, int p2 = 0, p3]) { + return 42 as Y; + } +} + +main() { + var o = C(); + final f = o.m; + f.expectStaticType< + Exactly< + Y Function( + String r1, + Y r2, + dynamic r3, [ + X? p1, + int p2, + dynamic p3, + ]) + > + >(); + + Expect.isTrue( + f is Y Function( // ignore: unnecessary_type_check + String r1, + Y r2, + dynamic r3, [ + X? p1, + int p2, + dynamic p3, + ]) + ); +} diff --git a/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A05_t01.dart b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A05_t01.dart new file mode 100644 index 0000000000..9c878db477 --- /dev/null +++ b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A05_t01.dart @@ -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: +/// ... +/// ``` +/// - +/// (T1 p1, ..., Tn pn, [Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk]) => +/// u.m(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 sgrekhov22@gmail.com + +import '../../../../Utils/expect.dart'; +import '../../../../Utils/static_type_helper.dart'; + +class C { + List m( + List r1, + List r2, + r3, [ + List? p1, + List p2 = const [], + p3 = const [], + ]) { + return []; + } +} + +main() { + var o = C(); + final f = o.m; + f.expectStaticType< + Exactly< + List Function( + List r1, + List r2, + dynamic r3, [ + List? p1, + List p2, + dynamic p3, + ]) + > + >(); + + Expect.isTrue( + f is List Function( // ignore: unnecessary_type_check + List r1, + List r2, + dynamic r3, [ + List? p1, + List p2, + dynamic p3, + ]) + ); +} diff --git a/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A06_t01.dart b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A06_t01.dart new file mode 100644 index 0000000000..988dcd1d26 --- /dev/null +++ b/Language/Expressions/Property_Extraction/Instance_Method_Closurization/method_closurization_positional_params_A06_t01.dart @@ -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 `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: +/// ... +/// ``` +/// - +/// (T1 p1, ..., Tn pn, [Tn+1 pn+1 = d1, ..., Tn+k pn+k = dk]) => +/// u.m(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. +/// ... +/// 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 sgrekhov22@gmail.com + +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); +}