Add tests for rti emission on function types

Change-Id: Iee612110afbb83947a7869df3c49138a9ba34832
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96906
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/tests/compiler/dart2js/rti/emission/function_typed_arguments.dart b/tests/compiler/dart2js/rti/emission/function_typed_arguments.dart
new file mode 100644
index 0000000..08b5e64
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/function_typed_arguments.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2019, 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.
+
+import 'package:expect/expect.dart';
+
+/*class: A:checkedInstance,checks=[],instance*/
+class A<T> {}
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+}
+
+/*class: B1:checks=[],typeArgument*/
+class B1<T> {}
+
+/*class: C1:checkedTypeArgument,checks=[],typeArgument*/
+class C1 extends B1<int> {}
+
+@pragma('dart2js:noInline')
+test1() {
+  Expect.isTrue(_test1(new A<void Function(C1)>()));
+  Expect.isTrue(_test1(new A<void Function(B1<int>)>()));
+  Expect.isFalse(_test1(new A<void Function(B1<String>)>()));
+}
+
+@pragma('dart2js:noInline')
+_test1(f) => f is A<void Function(C1)>;
+
+/*class: B2:checks=[],typeArgument*/
+class B2<T> {}
+
+/*class: C2:checkedTypeArgument,checks=[],typeArgument*/
+class C2 extends B2<int> {}
+
+@pragma('dart2js:noInline')
+test2() {
+  Expect.isTrue(_test2(new A<C2 Function()>()));
+  Expect.isFalse(_test2(new A<B2<int> Function()>()));
+  Expect.isFalse(_test2(new A<B2<String> Function()>()));
+}
+
+@pragma('dart2js:noInline')
+_test2(f) => f is A<C2 Function()>;
+
+/*class: B3:checkedTypeArgument,checks=[],typeArgument*/
+class B3<T> {}
+
+/*class: C3:checks=[$asB3],typeArgument*/
+class C3 extends B3<int> {}
+
+@pragma('dart2js:noInline')
+test3() {
+  Expect.isFalse(_test3(new A<void Function(C3)>()));
+  Expect.isTrue(_test3(new A<void Function(B3<int>)>()));
+  Expect.isFalse(_test3(new A<void Function(B3<String>)>()));
+}
+
+@pragma('dart2js:noInline')
+_test3(f) => f is A<void Function(B3<int>)>;
+
+/*class: B4:checkedTypeArgument,checks=[],typeArgument*/
+class B4<T> {}
+
+/*class: C4:checks=[$asB4],typeArgument*/
+class C4 extends B4<int> {}
+
+@pragma('dart4js:noInline')
+test4() {
+  Expect.isTrue(_test4(new A<C4 Function()>()));
+  Expect.isTrue(_test4(new A<B4<int> Function()>()));
+  Expect.isFalse(_test4(new A<B4<String> Function()>()));
+}
+
+@pragma('dart4js:noInline')
+_test4(f) => f is A<B4<int> Function()>;
+
+/*class: B5:checks=[],typeArgument*/
+class B5<T> {}
+
+/*class: C5:checkedTypeArgument,checks=[],typeArgument*/
+class C5 extends B5<int> {}
+
+@pragma('dart2js:noInline')
+test5() {
+  Expect.isTrue(_test5(new A<void Function(C5 Function())>()));
+  Expect.isTrue(_test5(new A<void Function(B5<int> Function())>()));
+  Expect.isFalse(_test5(new A<void Function(B5<String> Function())>()));
+}
+
+@pragma('dart2js:noInline')
+_test5(f) => f is A<void Function(C5 Function())>;
+
+/*class: B6:checks=[],typeArgument*/
+class B6<T> {}
+
+/*class: C6:checkedTypeArgument,checks=[],typeArgument*/
+class C6 extends B6<int> {}
+
+@pragma('dart2js:noInline')
+test6() {
+  Expect.isTrue(_test6(new A<void Function(void Function(C6))>()));
+  Expect.isFalse(_test6(new A<void Function(void Function(B6<int>))>()));
+  Expect.isFalse(_test6(new A<void Function(void Function(B6<String>))>()));
+}
+
+@pragma('dart2js:noInline')
+_test6(f) => f is A<void Function(void Function(C6))>;
diff --git a/tests/compiler/dart2js/rti/emission/tear_off_types.dart b/tests/compiler/dart2js/rti/emission/tear_off_types.dart
new file mode 100644
index 0000000..d9adf72
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/tear_off_types.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2019, 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.
+
+import 'package:expect/expect.dart';
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+  test7();
+}
+
+/*class: A1:checkedTypeArgument,checks=[],typeArgument*/
+class A1<T> {}
+
+/*class: B1:checkedTypeArgument,checks=[$asA1],typeArgument*/
+class B1 extends A1<int> {}
+
+@pragma('dart2js:noInline')
+test1() {
+  Expect.isTrue(_test1(method1a));
+  Expect.isTrue(_test1(method1b));
+  Expect.isFalse(_test1(method1c));
+}
+
+B1 method1a() => null;
+A1<int> method1b() => null;
+A1<String> method1c() => null;
+
+@pragma('dart2js:noInline')
+bool _test1(f) => f is A1<int> Function();
+
+/*strong.class: A2:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*omit.class: A2:checkedTypeArgument,checks=[],typeArgument*/
+class A2<T> {}
+
+/*strong.class: B2:checkedInstance,checkedTypeArgument,checks=[$asA2],typeArgument*/
+/*omit.class: B2:checkedTypeArgument,checks=[$asA2],typeArgument*/
+class B2 extends A2<int> {}
+
+@pragma('dart2js:noInline')
+test2() {
+  Expect.isFalse(_test2(method2a));
+  Expect.isTrue(_test2(method2b));
+  Expect.isFalse(_test2(method2c));
+}
+
+void method2a(B2 b) {}
+void method2b(A2<int> a) {}
+void method2c(A2<String> a) {}
+
+@pragma('dart2js:noInline')
+bool _test2(f) => f is void Function(A2<int>);
+
+/*strong.class: A3:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*omit.class: A3:checkedTypeArgument,checks=[],typeArgument*/
+class A3<T> {}
+
+/*strong.class: B3:checkedInstance,checkedTypeArgument,checks=[$asA3],typeArgument*/
+/*omit.class: B3:checkedTypeArgument,checks=[$asA3],typeArgument*/
+class B3 extends A3<int> {}
+
+@pragma('dart3js:noInline')
+test3() {
+  Expect.isTrue(_test3(method3a));
+  Expect.isTrue(_test3(method3b));
+  Expect.isFalse(_test3(method3c));
+}
+
+void method3a(B3 b) {}
+void method3b(A3<int> a) {}
+void method3c(A3<String> a) {}
+
+@pragma('dart3js:noInline')
+_test3(f) => f is void Function(B3);
+
+/*class: A4:checkedTypeArgument,checks=[],typeArgument*/
+class A4<T> {}
+
+/*class: B4:checkedTypeArgument,checks=[$asA4],typeArgument*/
+class B4 extends A4<int> {}
+
+@pragma('dart4js:noInline')
+test4() {
+  Expect.isTrue(_test4(method4a));
+  Expect.isFalse(_test4(method4b));
+  Expect.isFalse(_test4(method4c));
+}
+
+B4 method4a() => null;
+A4<int> method4b() => null;
+A4<String> method4c() => null;
+
+@pragma('dart4js:noInline')
+_test4(f) => f is B4 Function();
+
+/*class: A5:checkedTypeArgument,checks=[],typeArgument*/
+class A5<T> {}
+
+/*strong.class: B5:checkedTypeArgument,checks=[$asA5],typeArgument*/
+/*omit.class: B5:checkedTypeArgument,checks=[$asA5],typeArgument*/
+class B5 extends A5<int> {}
+
+@pragma('dart2js:noInline')
+test5() {
+  Expect.isTrue(_test5(method5a));
+  Expect.isTrue(_test5(method5b));
+  Expect.isFalse(_test5(method5c));
+}
+
+void method5a(void Function(B5) f) => null;
+void method5b(void Function(A5<int>) f) => null;
+void method5c(void Function(A5<String>) f) => null;
+
+@pragma('dart2js:noInline')
+bool _test5(f) => f is void Function(void Function(A5<int>));
+
+/*strong.class: A6:checkedTypeArgument,checks=[],typeArgument*/
+/*omit.class: A6:checkedTypeArgument,checks=[],typeArgument*/
+class A6<T> {}
+
+/*strong.class: B6:checkedTypeArgument,checks=[$asA6],typeArgument*/
+/*omit.class: B6:checkedTypeArgument,checks=[$asA6],typeArgument*/
+class B6 extends A6<int> {}
+
+@pragma('dart6js:noInline')
+test6() {
+  Expect.isTrue(_test6(method6a));
+  Expect.isTrue(_test6(method6b));
+  Expect.isFalse(_test6(method6c));
+}
+
+void Function(B6) method6a() => null;
+void Function(A6<int>) method6b() => null;
+void Function(A6<String>) method6c() => null;
+
+@pragma('dart6js:noInline')
+_test6(f) => f is void Function(B6) Function();
+
+/*strong.class: A7:checkedTypeArgument,checks=[],typeArgument*/
+/*omit.class: A7:checkedTypeArgument,checks=[],typeArgument*/
+class A7<T> {}
+
+/*strong.class: B7:checkedTypeArgument,checks=[$asA7],typeArgument*/
+/*omit.class: B7:checkedTypeArgument,checks=[$asA7],typeArgument*/
+class B7 extends A7<int> {}
+
+@pragma('dart7js:noInline')
+test7() {
+  Expect.isTrue(_test7(method7a));
+  Expect.isFalse(_test7(method7b));
+  Expect.isFalse(_test7(method7c));
+}
+
+void method7a(void Function(B7) f) => null;
+void method7b(void Function(A7<int>) f) => null;
+void method7c(void Function(A7<String>) f) => null;
+
+@pragma('dart7js:noInline')
+_test7(f) => f is void Function(void Function(B7));
diff --git a/tests/compiler/dart2js_extra/function_typed_arguments_test.dart b/tests/compiler/dart2js_extra/function_typed_arguments_test.dart
new file mode 100644
index 0000000..f18daee
--- /dev/null
+++ b/tests/compiler/dart2js_extra/function_typed_arguments_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2019, 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+// Test type tests of function types used a type argument.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+}
+
+class B1<T> {}
+
+class C1 extends B1<int> {}
+
+@pragma('dart2js:noInline')
+test1() {
+  Expect.isTrue(_test1(new A<void Function(C1)>()));
+  Expect.isTrue(_test1(new A<void Function(B1<int>)>())); //# 01: ok
+  Expect.isFalse(_test1(new A<void Function(B1<String>)>()));
+}
+
+@pragma('dart2js:noInline')
+_test1(f) => f is A<void Function(C1)>;
+
+class B2<T> {}
+
+class C2 extends B2<int> {}
+
+@pragma('dart2js:noInline')
+test2() {
+  Expect.isTrue(_test2(new A<C2 Function()>()));
+  Expect.isFalse(_test2(new A<B2<int> Function()>()));
+  Expect.isFalse(_test2(new A<B2<String> Function()>()));
+}
+
+@pragma('dart2js:noInline')
+_test2(f) => f is A<C2 Function()>;
+
+class B3<T> {}
+
+class C3 extends B3<int> {}
+
+@pragma('dart2js:noInline')
+test3() {
+  Expect.isFalse(_test3(new A<void Function(C3)>()));
+  Expect.isTrue(_test3(new A<void Function(B3<int>)>()));
+  Expect.isFalse(_test3(new A<void Function(B3<String>)>()));
+}
+
+@pragma('dart2js:noInline')
+_test3(f) => f is A<void Function(B3<int>)>;
+
+class B4<T> {}
+
+class C4 extends B4<int> {}
+
+@pragma('dart4js:noInline')
+test4() {
+  Expect.isTrue(_test4(new A<C4 Function()>()));
+  Expect.isTrue(_test4(new A<B4<int> Function()>()));
+  Expect.isFalse(_test4(new A<B4<String> Function()>()));
+}
+
+@pragma('dart4js:noInline')
+_test4(f) => f is A<B4<int> Function()>;
+
+class B5<T> {}
+
+class C5 extends B5<int> {}
+
+@pragma('dart2js:noInline')
+test5() {
+  Expect.isTrue(_test5(new A<void Function(C5 Function())>()));
+  Expect.isTrue(_test5(new A<void Function(B5<int> Function())>())); //# 02: ok
+  Expect.isFalse(_test5(new A<void Function(B5<String> Function())>()));
+}
+
+@pragma('dart2js:noInline')
+_test5(f) => f is A<void Function(C5 Function())>;
+
+class B6<T> {}
+
+class C6 extends B6<int> {}
+
+@pragma('dart2js:noInline')
+test6() {
+  Expect.isTrue(_test6(new A<void Function(void Function(C6))>()));
+  Expect.isFalse(_test6(new A<void Function(void Function(B6<int>))>()));
+  Expect.isFalse(_test6(new A<void Function(void Function(B6<String>))>()));
+}
+
+@pragma('dart2js:noInline')
+_test6(f) => f is A<void Function(void Function(C6))>;
diff --git a/tests/compiler/dart2js_extra/tear_off_types_test.dart b/tests/compiler/dart2js_extra/tear_off_types_test.dart
new file mode 100644
index 0000000..d7f6c41
--- /dev/null
+++ b/tests/compiler/dart2js_extra/tear_off_types_test.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2019, 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+import 'package:expect/expect.dart';
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+  test7();
+}
+
+class A1<T> {}
+
+class B1 extends A1<int> {}
+
+@pragma('dart2js:noInline')
+test1() {
+  Expect.isTrue(_test1(method1a));
+  Expect.isTrue(_test1(method1b));
+  Expect.isFalse(_test1(method1c));
+}
+
+B1 method1a() => null;
+A1<int> method1b() => null;
+A1<String> method1c() => null;
+
+@pragma('dart2js:noInline')
+bool _test1(f) => f is A1<int> Function();
+
+class A2<T> {}
+
+class B2 extends A2<int> {}
+
+@pragma('dart2js:noInline')
+test2() {
+  Expect.isFalse(_test2(method2a));
+  Expect.isTrue(_test2(method2b));
+  Expect.isFalse(_test2(method2c));
+}
+
+void method2a(B2 b) {}
+void method2b(A2<int> a) {}
+void method2c(A2<String> a) {}
+
+@pragma('dart2js:noInline')
+bool _test2(f) => f is void Function(A2<int>);
+
+class A3<T> {}
+
+class B3 extends A3<int> {}
+
+@pragma('dart3js:noInline')
+test3() {
+  Expect.isTrue(_test3(method3a));
+  Expect.isTrue(_test3(method3b));
+  Expect.isFalse(_test3(method3c));
+}
+
+void method3a(B3 b) {}
+void method3b(A3<int> a) {}
+void method3c(A3<String> a) {}
+
+@pragma('dart3js:noInline')
+_test3(f) => f is void Function(B3);
+
+class A4<T> {}
+
+class B4 extends A4<int> {}
+
+@pragma('dart4js:noInline')
+test4() {
+  Expect.isTrue(_test4(method4a));
+  Expect.isFalse(_test4(method4b));
+  Expect.isFalse(_test4(method4c));
+}
+
+B4 method4a() => null;
+A4<int> method4b() => null;
+A4<String> method4c() => null;
+
+@pragma('dart4js:noInline')
+_test4(f) => f is B4 Function();
+
+class A5<T> {}
+
+class B5 extends A5<int> {}
+
+@pragma('dart2js:noInline')
+test5() {
+  Expect.isTrue(_test5(method5a));
+  Expect.isTrue(_test5(method5b));
+  Expect.isFalse(_test5(method5c));
+}
+
+void method5a(void Function(B5) f) => null;
+void method5b(void Function(A5<int>) f) => null;
+void method5c(void Function(A5<String>) f) => null;
+
+@pragma('dart2js:noInline')
+bool _test5(f) => f is void Function(void Function(A5<int>));
+
+class A6<T> {}
+
+class B6 extends A6<int> {}
+
+@pragma('dart6js:noInline')
+test6() {
+  Expect.isTrue(_test6(method6a));
+  Expect.isTrue(_test6(method6b));
+  Expect.isFalse(_test6(method6c));
+}
+
+void Function(B6) method6a() => null;
+void Function(A6<int>) method6b() => null;
+void Function(A6<String>) method6c() => null;
+
+@pragma('dart6js:noInline')
+_test6(f) => f is void Function(B6) Function();
+
+class A7<T> {}
+
+class B7 extends A7<int> {}
+
+@pragma('dart7js:noInline')
+test7() {
+  Expect.isTrue(_test7(method7a));
+  Expect.isFalse(_test7(method7b));
+  Expect.isFalse(_test7(method7c));
+}
+
+void method7a(void Function(B7) f) => null;
+void method7b(void Function(A7<int>) f) => null;
+void method7c(void Function(A7<String>) f) => null;
+
+@pragma('dart7js:noInline')
+_test7(f) => f is void Function(void Function(B7));