OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 // VMOptions=-DUSE_CPS_IR=true | |
5 | |
6 // Test that the CPS IR code generator generates source information. | |
7 | |
8 library source_information_tests; | |
9 | |
10 import 'package:async_helper/async_helper.dart'; | |
11 import 'package:expect/expect.dart'; | |
12 import 'package:compiler/src/apiimpl.dart' | |
floitsch
2015/02/24 19:58:12
Since you keep "Element" and "ClassElement" on the
| |
13 show Compiler; | |
14 import 'memory_compiler.dart'; | |
15 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir; | |
16 import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart' as ir; | |
17 import 'package:compiler/src/js/js.dart' as js; | |
18 import 'package:compiler/src/common.dart' show Element, ClassElement; | |
19 | |
20 const String TEST_MAIN_FILE = 'test.dart'; | |
21 | |
22 class TestEntry { | |
23 final String source; | |
24 final List<String> expectation; | |
25 final String elementName; | |
26 | |
27 const TestEntry(this.source, this.expectation) | |
28 : elementName = null; | |
29 | |
30 const TestEntry.forMethod(this.elementName, | |
31 this.source, this.expectation); | |
32 } | |
33 | |
34 String formatTest(Map test) { | |
35 return test[TEST_MAIN_FILE]; | |
36 } | |
37 | |
38 js.Node getCodeForMain(Compiler compiler) { | |
39 Element mainFunction = compiler.mainFunction; | |
40 return compiler.enqueuer.codegen.generatedCode[mainFunction]; | |
41 } | |
42 | |
43 js.Node getJsNodeForElement(Compiler compiler, | |
44 Element element) { | |
45 return compiler.enqueuer.codegen.generatedCode[element]; | |
46 } | |
47 | |
48 ir.ExecutableDefinition getIrNodeForElement(Compiler compiler, | |
49 Element element) { | |
50 return compiler.irBuilder.getIr(element); | |
51 } | |
52 | |
53 String getCodeForMethod(Compiler compiler, | |
54 String name) { | |
55 Element foundElement; | |
56 for (Element element in compiler.enqueuer.codegen.generatedCode.keys) { | |
57 if (element.toString() == name) { | |
58 if (foundElement != null) { | |
59 Expect.fail('Multiple compiled elements are called $name'); | |
60 } | |
61 foundElement = element; | |
62 } | |
63 } | |
64 | |
65 if (foundElement == null) { | |
66 Expect.fail('There is no compiled element called $name'); | |
67 } | |
68 | |
69 js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement]; | |
70 return js.prettyPrint(ast, compiler).getText(); | |
71 } | |
72 | |
73 runTests(List<TestEntry> tests) { | |
74 Expect.isTrue(const bool.fromEnvironment("USE_CPS_IR"), | |
75 'Run with USE_CPS_IR=true'); | |
76 | |
77 for (TestEntry test in tests) { | |
78 Map files = {TEST_MAIN_FILE: test.source}; | |
79 asyncTest(() { | |
80 Compiler compiler = compilerFor(files); | |
81 Uri uri = Uri.parse('memory:$TEST_MAIN_FILE'); | |
82 return compiler.run(uri).then((bool success) { | |
83 Expect.isTrue(success); | |
84 | |
85 ir.Node irNode = getIrNodeForElement(compiler, compiler.mainFunction); | |
86 IrSourceInformationVisitor irVisitor = new IrSourceInformationVisitor(); | |
87 irNode.accept(irVisitor); | |
88 | |
89 js.Node jsNode = getJsNodeForElement(compiler, compiler.mainFunction); | |
90 JsSourceInformationVisitor jsVisitor = new JsSourceInformationVisitor(); | |
91 jsNode.accept(jsVisitor); | |
92 | |
93 List<String> expectation = test.expectation; | |
94 // Visiting of CPS is in structural order so we check for set equality. | |
95 Expect.setEquals(expectation, irVisitor.sourceInformation, | |
96 'Unexpected IR source information. ' | |
97 'Expected:\n$expectation\n' | |
98 'but found\n${irVisitor.sourceInformation}\n' | |
99 'in\n${test.source}' | |
100 'CPS:\n${irNode.accept(new ir.SExpressionStringifier())}'); | |
101 Expect.listEquals(expectation, jsVisitor.sourceInformation, | |
102 'Unexpected JS source information. ' | |
103 'Expected:\n$expectation\n' | |
104 'but found\n${jsVisitor.sourceInformation}\n' | |
105 'in\n${test.source}'); | |
106 }).catchError((e) { | |
107 print(e); | |
108 Expect.fail('The following test failed to compile:\n' | |
109 '${formatTest(files)}'); | |
110 }); | |
111 }); | |
112 } | |
113 } | |
114 | |
115 class JsSourceInformationVisitor extends js.BaseVisitor { | |
116 List<String> sourceInformation = <String>[]; | |
117 | |
118 @override | |
119 visitCall(js.Call node) { | |
120 sourceInformation.add('${node.sourceInformation}'); | |
121 super.visitCall(node); | |
122 } | |
123 } | |
124 | |
125 class IrSourceInformationVisitor extends ir.RecursiveVisitor { | |
126 List<String> sourceInformation = <String>[]; | |
127 | |
128 @override | |
129 processInvokeStatic(ir.InvokeStatic node) { | |
130 sourceInformation.add('${node.sourceInformation}'); | |
131 } | |
132 } | |
133 | |
134 const List<TestEntry> tests = const [ | |
135 const TestEntry(""" | |
136 main() { print('Hello World'); } | |
137 """, const ['memory:test.dart:[1,10]']), | |
138 const TestEntry(""" | |
139 main() { | |
140 print('Hello'); | |
141 print('World'); | |
142 } | |
143 """, const ['memory:test.dart:[2,3]', | |
144 'memory:test.dart:[3,3]']), | |
145 ]; | |
146 | |
147 void main() { | |
148 runTests(tests); | |
149 } | |
OLD | NEW |