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();
+}