Index: tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart |
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..29a42adb91721ee62aa92f5ce52b30d2ae00310c |
--- /dev/null |
+++ b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart |
@@ -0,0 +1,149 @@ |
+// Copyright (c) 2015, 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. |
+// VMOptions=-DUSE_CPS_IR=true |
+ |
+// Test that the CPS IR code generator generates source information. |
+ |
+library source_information_tests; |
+ |
+import 'package:async_helper/async_helper.dart'; |
+import 'package:expect/expect.dart'; |
+import 'package:compiler/src/apiimpl.dart' |
floitsch
2015/02/24 19:58:12
Since you keep "Element" and "ClassElement" on the
|
+ show Compiler; |
+import 'memory_compiler.dart'; |
+import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir; |
+import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart' as ir; |
+import 'package:compiler/src/js/js.dart' as js; |
+import 'package:compiler/src/common.dart' show Element, ClassElement; |
+ |
+const String TEST_MAIN_FILE = 'test.dart'; |
+ |
+class TestEntry { |
+ final String source; |
+ final List<String> expectation; |
+ final String elementName; |
+ |
+ const TestEntry(this.source, this.expectation) |
+ : elementName = null; |
+ |
+ const TestEntry.forMethod(this.elementName, |
+ this.source, this.expectation); |
+} |
+ |
+String formatTest(Map test) { |
+ return test[TEST_MAIN_FILE]; |
+} |
+ |
+js.Node getCodeForMain(Compiler compiler) { |
+ Element mainFunction = compiler.mainFunction; |
+ return compiler.enqueuer.codegen.generatedCode[mainFunction]; |
+} |
+ |
+js.Node getJsNodeForElement(Compiler compiler, |
+ Element element) { |
+ return compiler.enqueuer.codegen.generatedCode[element]; |
+} |
+ |
+ir.ExecutableDefinition getIrNodeForElement(Compiler compiler, |
+ Element element) { |
+ return compiler.irBuilder.getIr(element); |
+} |
+ |
+String getCodeForMethod(Compiler compiler, |
+ String name) { |
+ Element foundElement; |
+ for (Element element in compiler.enqueuer.codegen.generatedCode.keys) { |
+ if (element.toString() == name) { |
+ if (foundElement != null) { |
+ Expect.fail('Multiple compiled elements are called $name'); |
+ } |
+ foundElement = element; |
+ } |
+ } |
+ |
+ if (foundElement == null) { |
+ Expect.fail('There is no compiled element called $name'); |
+ } |
+ |
+ js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement]; |
+ return js.prettyPrint(ast, compiler).getText(); |
+} |
+ |
+runTests(List<TestEntry> tests) { |
+ Expect.isTrue(const bool.fromEnvironment("USE_CPS_IR"), |
+ 'Run with USE_CPS_IR=true'); |
+ |
+ for (TestEntry test in tests) { |
+ Map files = {TEST_MAIN_FILE: test.source}; |
+ asyncTest(() { |
+ Compiler compiler = compilerFor(files); |
+ Uri uri = Uri.parse('memory:$TEST_MAIN_FILE'); |
+ return compiler.run(uri).then((bool success) { |
+ Expect.isTrue(success); |
+ |
+ ir.Node irNode = getIrNodeForElement(compiler, compiler.mainFunction); |
+ IrSourceInformationVisitor irVisitor = new IrSourceInformationVisitor(); |
+ irNode.accept(irVisitor); |
+ |
+ js.Node jsNode = getJsNodeForElement(compiler, compiler.mainFunction); |
+ JsSourceInformationVisitor jsVisitor = new JsSourceInformationVisitor(); |
+ jsNode.accept(jsVisitor); |
+ |
+ List<String> expectation = test.expectation; |
+ // Visiting of CPS is in structural order so we check for set equality. |
+ Expect.setEquals(expectation, irVisitor.sourceInformation, |
+ 'Unexpected IR source information. ' |
+ 'Expected:\n$expectation\n' |
+ 'but found\n${irVisitor.sourceInformation}\n' |
+ 'in\n${test.source}' |
+ 'CPS:\n${irNode.accept(new ir.SExpressionStringifier())}'); |
+ Expect.listEquals(expectation, jsVisitor.sourceInformation, |
+ 'Unexpected JS source information. ' |
+ 'Expected:\n$expectation\n' |
+ 'but found\n${jsVisitor.sourceInformation}\n' |
+ 'in\n${test.source}'); |
+ }).catchError((e) { |
+ print(e); |
+ Expect.fail('The following test failed to compile:\n' |
+ '${formatTest(files)}'); |
+ }); |
+ }); |
+ } |
+} |
+ |
+class JsSourceInformationVisitor extends js.BaseVisitor { |
+ List<String> sourceInformation = <String>[]; |
+ |
+ @override |
+ visitCall(js.Call node) { |
+ sourceInformation.add('${node.sourceInformation}'); |
+ super.visitCall(node); |
+ } |
+} |
+ |
+class IrSourceInformationVisitor extends ir.RecursiveVisitor { |
+ List<String> sourceInformation = <String>[]; |
+ |
+ @override |
+ processInvokeStatic(ir.InvokeStatic node) { |
+ sourceInformation.add('${node.sourceInformation}'); |
+ } |
+} |
+ |
+const List<TestEntry> tests = const [ |
+ const TestEntry(""" |
+main() { print('Hello World'); } |
+""", const ['memory:test.dart:[1,10]']), |
+const TestEntry(""" |
+main() { |
+ print('Hello'); |
+ print('World'); |
+} |
+""", const ['memory:test.dart:[2,3]', |
+ 'memory:test.dart:[3,3]']), |
+]; |
+ |
+void main() { |
+ runTests(tests); |
+} |