Issue #1087: New tests ащк Tearing off constructors from type aliases added
diff --git a/LanguageFeatures/Constructor-tear-offs/goal_t01_A01.dart b/LanguageFeatures/Constructor-tear-offs/goal_t01_A01.dart
index 6bd70e0..13fea4d 100644
--- a/LanguageFeatures/Constructor-tear-offs/goal_t01_A01.dart
+++ b/LanguageFeatures/Constructor-tear-offs/goal_t01_A01.dart
@@ -25,41 +25,26 @@
import "../../Utils/expect.dart";
class C {
- C.constr1(int i) {}
- C.constr2(int i) {}
- C.constr3(int i, String s, x) {}
- C.constr4() {}
+ int? i;
+
+ C() { i = 0; }
+
+ C.constr1(int i) { this.i = 1; }
+ C.constr2(int num, String str) { this.i = 2; }
+ C.constr3() { i = 3; }
}
main() {
- var v1 = C.constr1;
- var v2 = (C.constr1);
- Expect.equals(v1, v2);
+ Expect.equals(0, C.new());
+ Expect.equals(0, (C.new)());
- var v3 = C.constr2;
- var v4 = (C.constr2);
- Expect.equals(v3, v4);
+ Expect.equals(1, C.constr1(1));
+ Expect.equals(1, (C.constr1)(1));
- var v5 = C.constr1;
- var v6 = (C.constr1);
- Expect.equals(v5, v6);
+ Expect.equals(2, C.constr2(1, "123"));
+ Expect.equals(2, (C.constr2)(1, "123"));
- var v7 = C.constr4;
-
- Expect.notEquals(v1, v3);
- Expect.notEquals(v1, v4);
- Expect.notEquals(v1, v5);
- Expect.notEquals(v1, v6);
- Expect.notEquals(v1, v7);
-
- Expect.notEquals(v2, v3);
- Expect.notEquals(v2, v4);
- Expect.notEquals(v2, v5);
- Expect.notEquals(v2, v6);
- Expect.notEquals(v2, v7);
-
- Expect.notEquals(v3, v7);
- Expect.notEquals(v4, v7);
- Expect.notEquals(v5, v7);
- Expect.notEquals(v6, v7);
+ Expect.equals(1, C.constr3());
+ Expect.equals(1, (C.constr3)());
}
+
diff --git a/LanguageFeatures/Constructor-tear-offs/goal_t01_A02.dart b/LanguageFeatures/Constructor-tear-offs/goal_t01_A02.dart
index 7b8adfa..7e19f33 100644
--- a/LanguageFeatures/Constructor-tear-offs/goal_t01_A02.dart
+++ b/LanguageFeatures/Constructor-tear-offs/goal_t01_A02.dart
@@ -25,23 +25,49 @@
import "../../Utils/expect.dart";
class C<T> {
- C.constr1(int i) {}
+ int? i;
+
+ C() { i = 0; }
+
+ C.constr1(int i) { this.i = 1; }
+ C.constr2(int num, String str) { this.i = 2; }
+ C.constr3() { i = 3; }
}
main() {
- var v1 = C.constr1;
- var v2 = (C.constr1);
- var v3 = (C.constr1<dynamic>);
- var v4 = (C.constr1)<dynamic>;
- Expect.equals(v1, v2);
- Expect.equals(v1, v3);
- Expect.equals(v1, v4);
+ Expect.equals(0, C.new());
+ Expect.equals(0, (C.new)());
+ Expect.equals(0, C<dynamic>.new());
+ Expect.equals(0, (C<dynamic>.new)());
+ Expect.equals(0, (C.new)<dynamic>());
+ Expect.equals(0, C<int>.new());
+ Expect.equals(0, (C<int>.new)());
+ Expect.equals(0, (C.new)<int>());
- var v5 = C.constr1<String>;
- var v6 = (C.constr1<String>);
- var v7 = (C.constr1)<String>;
- Expect.equals(v5, v6);
- Expect.equals(v5, v7);
+ Expect.equals(1, C.constr1(1));
+ Expect.equals(1, (C.constr1)(1));
+ Expect.equals(1, C<dynamic>.constr1(1));
+ Expect.equals(1, (C<dynamic>.constr1)(1));
+ Expect.equals(1, (C.constr1)<dynamic>(1));
+ Expect.equals(1, C<int>.constr1(1));
+ Expect.equals(1, (C<int>.constr1)(1));
+ Expect.equals(1, (C.constr1)<int>(1));
- Expect.notEquals(v1, v5);
+ Expect.equals(2, C.constr2(1, ""));
+ Expect.equals(2, (C.constr2)(1, ""));
+ Expect.equals(2, C<dynamic>.constr1(1, ""));
+ Expect.equals(2, (C<dynamic>.constr2)(1, ""));
+ Expect.equals(2, (C.constr2)<dynamic>(1, ""));
+ Expect.equals(2, C<int>.constr1(1, ""));
+ Expect.equals(2, (C<int>.constr2)(1, ""));
+ Expect.equals(2, (C.constr2)<int>(1, ""));
+
+ Expect.equals(3, C.constr3());
+ Expect.equals(3, (C.constr3)());
+ Expect.equals(3, C<dynamic>.constr3());
+ Expect.equals(3, (C<dynamic>.constr3)());
+ Expect.equals(3, (C.constr3)<dynamic>());
+ Expect.equals(3, C<int>.constr3());
+ Expect.equals(3, (C<int>.constr3)());
+ Expect.equals(3, (C.constr3)<int>());
}
diff --git a/LanguageFeatures/Constructor-tear-offs/goal_t01_A03.dart b/LanguageFeatures/Constructor-tear-offs/goal_t01_A03.dart
index 90b1a87..ffec8b0 100644
--- a/LanguageFeatures/Constructor-tear-offs/goal_t01_A03.dart
+++ b/LanguageFeatures/Constructor-tear-offs/goal_t01_A03.dart
@@ -24,16 +24,50 @@
import "../../Utils/expect.dart";
-class C<T extends int> {
- C.constr1(int i) {}
+class C<T extends num> {
+ int? i;
+
+ C() { i = 0; }
+
+ C.constr1(int i) { this.i = 1; }
+ C.constr2(int num, String str) { this.i = 2; }
+ C.constr3() { i = 3; }
}
main() {
- var v1 = C.constr1;
- var v2 = (C.constr1);
- var v3 = (C.constr1<int>);
- var v4 = (C.constr1)<int>;
- Expect.equals(v1, v2);
- Expect.equals(v1, v3);
- Expect.equals(v1, v4);
+ Expect.equals(0, C.new());
+ Expect.equals(0, (C.new)());
+ Expect.equals(0, C<num>.new());
+ Expect.equals(0, (C<num>.new)());
+ Expect.equals(0, (C.new)<num>());
+ Expect.equals(0, C<int>.new());
+ Expect.equals(0, (C<int>.new)());
+ Expect.equals(0, (C.new)<int>());
+
+ Expect.equals(1, C.constr1(1));
+ Expect.equals(1, (C.constr1)(1));
+ Expect.equals(1, C<num>.constr1(1));
+ Expect.equals(1, (C<num>.constr1)(1));
+ Expect.equals(1, (C.constr1)<num>(1));
+ Expect.equals(1, C<int>.constr1(1));
+ Expect.equals(1, (C<int>.constr1)(1));
+ Expect.equals(1, (C.constr1)<int>(1));
+
+ Expect.equals(2, C.constr2(1, ""));
+ Expect.equals(2, (C.constr2)(1, ""));
+ Expect.equals(2, C<dynamic>.constr1(1, ""));
+ Expect.equals(2, (C<dynamic>.constr2)(1, ""));
+ Expect.equals(2, (C.constr2)<dynamic>(1, ""));
+ Expect.equals(2, C<int>.constr1(1, ""));
+ Expect.equals(2, (C<int>.constr2)(1, ""));
+ Expect.equals(2, (C.constr2)<int>(1, ""));
+
+ Expect.equals(3, C.constr3());
+ Expect.equals(3, (C.constr3)());
+ Expect.equals(3, C<dynamic>.constr3());
+ Expect.equals(3, (C<dynamic>.constr3)());
+ Expect.equals(3, (C.constr3)<dynamic>());
+ Expect.equals(3, C<int>.constr3());
+ Expect.equals(3, (C<int>.constr3)());
+ Expect.equals(3, (C.constr3)<int>());
}
diff --git a/LanguageFeatures/Constructor-tear-offs/named_constructor_A01_t01.dart b/LanguageFeatures/Constructor-tear-offs/named_constructor_A01_t01.dart
index c1128d5..0898fca 100644
--- a/LanguageFeatures/Constructor-tear-offs/named_constructor_A01_t01.dart
+++ b/LanguageFeatures/Constructor-tear-offs/named_constructor_A01_t01.dart
@@ -27,7 +27,7 @@
}
main() {
- var v = C.constr ;
+ var v = C.constr;
C c = v(1);
Expect.isTrue(c.called);
}
diff --git a/LanguageFeatures/Constructor-tear-offs/named_constructor_t09_A03.dart b/LanguageFeatures/Constructor-tear-offs/named_constructor_t09_A03.dart
new file mode 100644
index 0000000..d7935ba
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/named_constructor_t09_A03.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2021, 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 The static type of the named constructor tear-off expression is
+/// the same as the static type of the corresponding constructor function
+/// tear-off.
+///
+/// @description Checks that the static types of the constructor tear off
+/// expressions are the same - test generic class
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+class C<T> {
+ T? i;
+ T? j;
+
+ C();
+ C.constr1(T i) {}
+ C.constr2(int i, String s, x) {}
+ C.constr3({int i=1, required T j}) {}
+ C.constr4(this.i, this.j);
+}
+
+main() {
+ var v1 = C<int>.new;
+ var v2 = (C<int>).new;
+ var v3 = C.new<int>;
+ Expect.equals(v1, v2);
+ Expect.equals(v1, v3);
+
+ var v4 = C<Never>.constr1;
+ var v5 = (C<Never>).constr1;
+ var v6 = (C.constr1)<Never>;
+ Expect.equals(v4, v5);
+ Expect.equals(v5, v6);
+
+ var v7 = C<Null>.constr2;
+ var v8 = (C<Null>).constr2;
+ var v9 = (C.constr2)<Null>;
+ Expect.equals(v7, v8);
+ Expect.equals(v8, v9);
+
+ var v10 = C<List>.constr3;
+ var v11 = (C<List>).constr3;
+ var v12 = (C.constr3)<List>;
+ Expect.equals(v10, v11);
+ Expect.equals(v11, v12);
+
+ var v13 = C<Object?>.constr4;
+ var v14 = (C<Object?>).constr4;
+ var v15 = (C.constr4)<Object?>;
+ Expect.equals(v13, v14);
+ Expect.equals(v13, v15);
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/named_constructor_t10_A01.dart b/LanguageFeatures/Constructor-tear-offs/named_constructor_t10_A01.dart
new file mode 100644
index 0000000..e5b7e56
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/named_constructor_t10_A01.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2021, 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 This introduces an ambiguity in the grammar. If [List.filled] is
+/// a valid expression, then [List.filled(4, 4)] can both be a constructor
+/// invocation and a tear-off followed by a function invocation. We only allow
+/// the constructor invocation when it's not followed by a typeArguments or
+/// arguments production (or, possibly, when it's not followed by a [<] or [(]
+/// character). We don't want to allow [List.filled<int>] to be interpreted as
+/// [(List.filled)<int>]. Just write the [List<int>.filled] to begin with!
+///
+/// @description Checks that constructions like [List.filled<int>] are not
+/// allowed.
+/// @author iarkh@unipro.ru
+
+class C<T> {
+ C() {}
+}
+
+void testList() {
+ List<int>.filled;
+ (List<int>).filled;
+ (List.filled)<int>;
+
+ List.filled<int>;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ List<int>.filled(4, 4);
+ (List<int>).filled(4, 4);
+ (List.filled)<int>(4, 4);
+
+ List.filled<int>(4, 4);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+void testC() {
+ C<int>.ned;
+ (C<int>).new;
+ (C.new)<int>;
+
+ C.new<int>;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ C<int>.new();
+ (C<int>).new();
+ (C.new)<int>();
+
+ C.new<int>();
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+main() {
+ testList();
+ testA();
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A01_t01.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A01_t01.dart
new file mode 100644
index 0000000..288246e
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A01_t01.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, 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 With generalized type-aliases, it's possible to declare a
+/// class-alias like [typedef IntList = List<int>;]. We allow calling
+/// constructors on such a type alias, so we will also allow tearing off such a
+/// constructor.
+///
+/// @description Checks that it's possible to declare [typedef IntList =
+/// List<int>;] and filled constructor is teared of in this case.
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+typedef IntList = List<int>;
+
+main() {
+ IntList list = [1, 2, 3];
+ Expect.listEquals([1, 2, 3], list);
+
+ IntList list1 = IntList.filled(3, 2);
+ Expect.listEquals([2, 2, 2], list1);
+
+ var v = IntList.filled;
+ Expect.listEquals([2, 2, 2], v(3, 2));
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A01_t02.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A01_t02.dart
new file mode 100644
index 0000000..3c66d96
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A01_t02.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, 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 With generalized type-aliases, it's possible to declare a
+/// class-alias like [typedef IntList = List<int>;]. We allow calling
+/// constructors on such a type alias, so we will also allow tearing off such a
+/// constructor.
+///
+/// @description Checks that type parameters are processed correctly for teared
+/// off constructor.
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+typedef IntList = List<int>;
+
+main() {
+ var v = IntList.filled;
+ v(3, "This is a String");
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ v(3, null);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t01.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t01.dart
new file mode 100644
index 0000000..e066471
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t01.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, 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 In general, a non-generic type alias is just expanded to its
+/// aliased type, then the tear-off happens on that type. Tearing off
+/// [IntList.filled] will act like tearing off [List<int>.filled], it
+/// automatically instantiates the class type parameter to the specified type.
+///
+/// @description Checks that tearing-off automatically instantiates the class
+/// type parameter to the specified type for non-generic type alias. Test row
+/// [List].
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+typedef MyList = List;
+
+main() {
+ var v = MytList.filled;
+ List list1 = v(3, 1);
+ Expect.equals([1, 1, 1], list1);
+
+ List list2 = v(4, null);
+ Expect.equals([null, null, null, null], list2);
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t02.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t02.dart
new file mode 100644
index 0000000..eb4e207
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t02.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, 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 In general, a non-generic type alias is just expanded to its
+/// aliased type, then the tear-off happens on that type. Tearing off
+/// [IntList.filled] will act like tearing off [List<int>.filled], it
+/// automatically instantiates the class type parameter to the specified type.
+///
+/// @description Checks that tearing-off automatically instantiates the class
+/// type parameter to the specified type for non-generic type alias. Test
+/// [List<num?>].
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+typedef MyList = List<num?>;
+
+main() {
+ var v = MytList.filled;
+ List list1 = v(3, 1);
+ Expect.equals([1, 1, 1], list1);
+
+ List list2 = v(1, 1.3);
+ Expect.equals([1.3], list2);
+
+ List list3 = v(4, null);
+ Expect.equals([null, null, null, null], list3);
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t03.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t03.dart
new file mode 100644
index 0000000..e02522c
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t03.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2021, 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 In general, a non-generic type alias is just expanded to its
+/// aliased type, then the tear-off happens on that type. Tearing off
+/// [IntList.filled] will act like tearing off [List<int>.filled], it
+/// automatically instantiates the class type parameter to the specified type.
+///
+/// @description Checks that tearing-off automatically instantiates the class
+/// type parameter to the specified type for non-generic type alias. Test
+/// negative static case for raw List.
+/// @author iarkh@unipro.ru
+
+typedef MyList = List;
+
+main() {
+ MyList<int>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<String>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<dynamic>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<Object?>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<Never>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t04.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t04.dart
new file mode 100644
index 0000000..6d55e14
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t04.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2021, 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 In general, a non-generic type alias is just expanded to its
+/// aliased type, then the tear-off happens on that type. Tearing off
+/// [IntList.filled] will act like tearing off [List<int>.filled], it
+/// automatically instantiates the class type parameter to the specified type.
+///
+/// @description Checks that tearing-off automatically instantiates the class
+/// type parameter to the specified type for non-generic type alias. Test
+/// negative static case for [List<int>].
+/// @author iarkh@unipro.ru
+
+typedef MyList = List<int>;
+
+main() {
+ MyList<int>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<String>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<dynamic>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<Object?>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ MyList<Never>.filled;
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ var v = MyList.filled;
+
+ v(1, 1.5);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ v(1, null);
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+ v(2, "");
+// ^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t05.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t05.dart
new file mode 100644
index 0000000..41f05b8
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A02_t05.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2021, 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 In general, a non-generic type alias is just expanded to its
+/// aliased type, then the tear-off happens on that type. Tearing off
+/// [IntList.filled] will act like tearing off [List<int>.filled], it
+/// automatically instantiates the class type parameter to the specified type.
+///
+/// @description Checks that tearing-off automatically instantiates the class
+/// type parameter to the specified type for non-generic type alias. Test
+/// negative dynamic case for [List<int>].
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+typedef MyList = List<int>;
+
+dynamic d = 1.1;
+dynamic str = "123";
+
+main() {
+
+ var v = MyList.filled;
+
+ Expect.throws(() { v(2, d); });
+ Expect.throws(() { v(10, null as dynamic); });
+ Expect.throws(() { v(3, str); });
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A03_t01.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A03_t01.dart
new file mode 100644
index 0000000..dfe743e
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A03_t01.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2021, 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 With generalized type-aliases, it's possible to declare a
+/// class-alias like [typedef IntList = List<int>;]. ... It's constant and
+/// canonicalized to the same function as [List<int>.filled]. In other words,
+/// the alias is treated as an actual alias for the type it aliases.
+///
+/// @description Checks that class-alias [typedef IntList = List] is
+/// constant and canonicalized. Tests raw [List] class.
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+typedef IntList = List;
+
+main() {
+ var v1 = IntList.filled;
+ var v2 = IntList.filled;
+ var v3 = IntList.filled;
+
+ Expect.identical(v1, v2);
+ Expect.identical(v1, v3);
+
+ var v4 = (IntList.filled);
+ Expect.identical(v1, v4);
+}
diff --git a/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A03_t02.dart b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A03_t02.dart
new file mode 100644
index 0000000..94e22a7
--- /dev/null
+++ b/LanguageFeatures/Constructor-tear-offs/tearing_off_from_typedef_A03_t02.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, 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 With generalized type-aliases, it's possible to declare a
+/// class-alias like [typedef IntList = List<int>;]. ... It's constant and
+/// canonicalized to the same function as [List<int>.filled]. In other words,
+/// the alias is treated as an actual alias for the type it aliases.
+///
+/// @description Checks that class-alias [typedef IntList = List] is
+/// constant and canonicalized. Tests raw [List] class.
+/// @author iarkh@unipro.ru
+
+import "../../Utils/expect.dart";
+
+class A<T extends num> {
+ T? i, j;
+ A();
+ A.constr(this.i, this.j);
+}
+
+typedef IntList = List;
+
+typedef AAlias = A<int>;
+
+testList() {
+ var v1 = IntList.filled;
+ var v2 = IntList.filled;
+ var v3 = IntList.filled;
+
+ Expect.identical(v1, v2);
+ Expect.identical(v1, v3);
+
+ var v4 = (IntList.filled);
+ Expect.identical(v1, v4);
+}
+
+testA_new() {
+ var v1 = A.new;
+ var v2 = A.new;
+ var v3 = A.new;
+
+ Expect.identical(v1, v2);
+ Expect.identical(v1, v3);
+
+ var v4 = (A.new);
+ Expect.identical(v1, v4);
+}
+
+testA_constr() {
+ var v1 = A.constr;
+ var v2 = A.constr;
+ var v3 = A.constr;
+
+ Expect.identical(v1, v2);
+ Expect.identical(v1, v3);
+
+ var v4 = (A.constr);
+ Expect.identical(v1, v4);
+}
+
+void main() {
+ testList();
+ testA_new();
+ testA_constr();
+}