Index: tests/compiler/dart2js/generic_method_type_usage_test.dart |
diff --git a/tests/compiler/dart2js/generic_method_type_usage_test.dart b/tests/compiler/dart2js/generic_method_type_usage_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9ec4fbe6cfbcb5f92fa6c29def5d5c6391beca4e |
--- /dev/null |
+++ b/tests/compiler/dart2js/generic_method_type_usage_test.dart |
@@ -0,0 +1,115 @@ |
+// Copyright (c) 2016, 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. |
+ |
+/// Dart test verifying that method type variables are considered to denote |
+/// the type `dynamic`. |
+/// |
+/// NB: This test is intended to succeed with a `dart2js` with the option |
+/// '--generic-method-syntax', but it should fail with a full implementation |
+/// of generic method support, and it should fail with every other tool than |
+/// `dart2js`. |
+ |
+library dart2js.test.generic_method_type_usage; |
+ |
+import 'dart:async'; |
+import 'package:async_helper/async_helper.dart'; |
+import "package:compiler/src/diagnostics/messages.dart"; |
+import 'package:expect/expect.dart'; |
+import 'memory_compiler.dart'; |
+ |
+const MEMORY_SOURCE_FILES = const { |
+ 'type_variable_is_dynamic.dart': ''' |
+class C { |
+ bool aMethod<X>(X x) { |
+ // `dynamic` is assignable to both `int` and `String`: no warnings. |
+ int i = x; |
+ String s = x; |
+ try { |
+ // Only `dynamic` allows unknown member lookup without a warning. |
+ var y = x.undefinedMember; |
+ } on NoSuchMethodError catch (_) { |
+ return true; |
+ } |
+ return false; |
+ } |
+} |
+ |
+bool aFunction<X>(X x) { |
+ // `dynamic` is assignable to both `int` and `String`: no warnings. |
+ int i = x; |
+ String s = x; |
+ try { |
+ // Only `dynamic` allows unknown member lookup without a warning. |
+ var y = x.undefinedMember; |
+ } on NoSuchMethodError catch (_) { |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+main() { |
+ print(new C().aMethod<Set>(null)); |
+ print(aFunction<Set>(null)); |
+} |
+''', |
+ |
+ 'cannot_new_method_type_variable.dart': ''' |
+class C { |
+ X aMethod<X>() => new X(); |
+} |
+ |
+main() { |
+ new C().aMethod<Set>(); |
+} |
+''', |
+ |
+ 'cannot_new_function_type_variable.dart': ''' |
+X aFunction<X>() => new X(42); |
+ |
+main() { |
+ aFunction<Set>(); |
+} |
+''', |
+}; |
+ |
+ |
+Future runTest(Uri main, {MessageKind warning, MessageKind info}) async { |
+ print("----\nentry-point: $main\n"); |
+ |
+ DiagnosticCollector diagnostics = new DiagnosticCollector(); |
+ OutputCollector output = new OutputCollector(); |
+ await runCompiler( |
+ entryPoint: main, |
+ options: const <String>["--generic-method-syntax"], |
+ memorySourceFiles: MEMORY_SOURCE_FILES, |
+ diagnosticHandler: diagnostics, |
+ outputProvider: output); |
+ |
+ Expect.isFalse(output.hasExtraOutput); |
+ Expect.equals(0, diagnostics.errors.length); |
+ Expect.equals(warning != null ? 1 : 0, diagnostics.warnings.length); |
+ if (warning != null) { |
+ Expect.equals(warning, diagnostics.warnings.first.message.kind); |
+ } |
+ Expect.equals(info != null ? 1 : 0, diagnostics.infos.length); |
+ if (info != null) { |
+ Expect.equals(info, diagnostics.infos.first.message.kind); |
+ } |
+ Expect.equals(0, diagnostics.hints.length); |
+} |
+ |
+void main() { |
+ asyncTest(() async { |
+ await runTest( |
+ Uri.parse('memory:type_variable_is_dynamic.dart')); |
+ |
+ await runTest( |
+ Uri.parse('memory:cannot_new_method_type_variable.dart'), |
+ warning: MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE); |
+ |
+ await runTest( |
+ Uri.parse('memory:cannot_new_function_type_variable.dart'), |
+ warning: MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE); |
+ }); |
+} |