Index: tests/compiler/dart2js/message_span_test.dart |
diff --git a/tests/compiler/dart2js/message_span_test.dart b/tests/compiler/dart2js/message_span_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..655b814cfc26d5ec0fb052eb4a0ac13eed7ab228 |
--- /dev/null |
+++ b/tests/compiler/dart2js/message_span_test.dart |
@@ -0,0 +1,182 @@ |
+// 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. |
+ |
+import 'package:async_helper/async_helper.dart'; |
+import 'package:compiler/src/commandline_options.dart'; |
+import 'package:compiler/src/diagnostics/messages.dart'; |
+import 'package:compiler/src/io/source_file.dart'; |
+import 'package:expect/expect.dart'; |
+import 'memory_compiler.dart'; |
+import 'memory_source_file_helper.dart'; |
+ |
+const List<Test> TESTS = const <Test>[ |
+ const Test(''' |
+class A { A(b); } |
+class B extends A { |
+ a() {} |
+ |
+ lot() {} |
+ |
+ of() {} |
+ |
+ var members; |
+} |
+main() => new B();''', |
+ const { |
+ MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: ''' |
+class B extends A { |
+^^^^^^^^^^^^^^^^^'''}), |
+ |
+ const Test(''' |
+class I {} |
+class A { A(b); } |
+class B extends A implements I { |
+ a() {} |
+ |
+ lot() {} |
+ |
+ of() {} |
+ |
+ var members; |
+} |
+main() => new B();''', |
+ const { |
+ MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: ''' |
+class B extends A implements I { |
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'''}), |
+ |
+ const Test(''' |
+class M<T> {} |
+class A { A(b); } |
+class B extends A with M<int> { |
+ a() {} |
+ |
+ lot() {} |
+ |
+ of() {} |
+ |
+ var members; |
+} |
+main() => new B();''', |
+ const { |
+ MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: ''' |
+class B extends A with M<int> { |
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'''}), |
+ |
+ const Test(''' |
+class A { A(b); } |
+class B |
+ extends A { |
+ a() {} |
+ |
+ lot() {} |
+ |
+ of() {} |
+ |
+ var members; |
+} |
+main() => new B();''', |
+ const { |
+ MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: ''' |
+class B |
+ extends A { |
+'''}), |
+ |
+ const Test(''' |
+void foo(int a) { |
+ // a |
+ // non-empty |
+ // body |
+} |
+main() => foo('');''', |
+ const { |
+ MessageKind.THIS_IS_THE_METHOD: ''' |
+void foo(int a) { |
+^^^^^^^^^^^^^^^'''}), |
+ |
+ const Test(''' |
+void foo(int a, |
+ int b) { |
+ // a |
+ // non-empty |
+ // body |
+} |
+main() => foo('', 0);''', |
+ const { |
+ MessageKind.THIS_IS_THE_METHOD: ''' |
+void foo(int a, |
+ int b) { |
+'''}), |
+ |
+ const Test(''' |
+class A { |
+ int foo() { |
+ // a |
+ // non-empty |
+ // body |
+ } |
+} |
+class B extends A { |
+ int get foo { |
+ // a |
+ // non-empty |
+ // body |
+ return 0; |
+ } |
+} |
+main() => new B();''', |
+ const { |
+ MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER: ''' |
+ int get foo { |
+ ^^^^^^^^^^^''', |
+ MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT: ''' |
+ int foo() { |
+ ^^^^^^^^^'''}), |
+]; |
+ |
+class Test { |
+ final String code; |
+ final Map<MessageKind, String> kindToSpan; |
+ |
+ const Test(this.code, this.kindToSpan); |
+} |
+ |
+const String MARKER = '---marker---'; |
+ |
+main() { |
+ asyncTest(() async { |
+ var cachedCompiler; |
+ for (Test test in TESTS) { |
+ DiagnosticCollector collector = new DiagnosticCollector(); |
+ CompilationResult result = await runCompiler( |
+ memorySourceFiles: {'main.dart': test.code}, |
+ options: [Flags.analyzeOnly], |
+ diagnosticHandler: collector, |
+ cachedCompiler: cachedCompiler); |
+ cachedCompiler = result.compiler; |
+ MemorySourceFileProvider provider = cachedCompiler.provider; |
+ Map<MessageKind, String> kindToSpan = |
+ new Map<MessageKind, String>.from(test.kindToSpan); |
+ for (CollectedMessage message in collector.messages) { |
+ String expectedSpanText = kindToSpan[message.messageKind]; |
+ if (expectedSpanText != null) { |
+ SourceFile sourceFile = provider.getSourceFile(message.uri); |
+ String locationMessage = |
+ sourceFile.getLocationMessage(MARKER, message.begin, message.end); |
+ // Remove `filename:line:column:` and message. |
+ String strippedLocationMessage = locationMessage.substring( |
+ locationMessage.indexOf(MARKER) + MARKER.length + 1); |
+ Expect.equals(expectedSpanText, strippedLocationMessage, |
+ "Unexpected span for ${message.messageKind} in\n${test.code}" |
+ "\nExpected:${expectedSpanText.codeUnits}" |
+ "\nActual :${strippedLocationMessage.codeUnits}"); |
+ kindToSpan.remove(message.messageKind); |
+ } |
+ } |
+ kindToSpan.forEach((MessageKind kind, _) { |
+ Expect.fail("Missing message kin $kind in\n${test.code}"); |
+ }); |
+ } |
+ }); |
+} |