Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Side by Side Diff: tests/compiler/dart2js/cpa_inference_test.dart

Issue 10907028: Standalone concrete type inference (not integrated in the compiler). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix tests Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/types/types.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #import("dart:uri");
2 #import("../../../lib/compiler/implementation/elements/elements.dart");
3 #import('../../../lib/compiler/implementation/scanner/scannerlib.dart');
4 #import('../../../lib/compiler/implementation/source_file.dart');
5 #import('../../../lib/compiler/implementation/types/types.dart');
6 #import('../../../lib/compiler/implementation/tree/tree.dart');
7 #import("../../../lib/compiler/implementation/leg.dart", prefix: "leg");
8
9 #import("parser_helper.dart");
10 #import("compiler_helper.dart");
11 #import("mock_compiler.dart");
12
13 /**
14 * Finds the node corresponding to the last occurence of the substring
15 * [: identifier; :] in the program represented by the visited AST.
16 */
17 class VariableFinderVisitor extends Visitor {
18 final String identifier;
19 Node result;
20
21 VariableFinderVisitor(this.identifier);
22
23 visitSend(Send node) {
24 if (node.isPropertyAccess
25 && node.selector.asIdentifier().source.slowToString() == identifier) {
26 result = node;
27 } else {
28 node.visitChildren(this);
29 }
30 }
31
32 visitNode(Node node) {
33 node.visitChildren(this);
34 }
35 }
36
37 class AnalysisResult {
38 MockCompiler compiler;
39 ConcreteTypesInferrer inferrer;
40 Node ast;
41
42 BaseType int;
43 BaseType double;
44 BaseType bool;
45 BaseType string;
46
47 AnalysisResult(MockCompiler compiler, ConcreteTypesInferrer inferrer)
48 : this.compiler = compiler,
49 this.inferrer = inferrer,
50 int = inferrer.baseTypes.intBaseType,
51 double = inferrer.baseTypes.doubleBaseType,
52 bool = inferrer.baseTypes.boolBaseType,
53 string = inferrer.baseTypes.stringBaseType {
54 Element mainElement = compiler.mainApp.find(buildSourceString('main'));
55 ast = mainElement.parseNode(compiler);
56 }
57
58 BaseType base(String className) {
59 final source = buildSourceString(className);
60 return new ClassBaseType(compiler.mainApp.find(source));
61 }
62
63 /**
64 * Finds the [Node] corresponding to the last occurence of the substring
65 * [: identifier; :] in the program represented by the visited AST. For
66 * instance, returns the AST node representing [: foo; :] in
67 * [: main() { foo = 1; foo; } :].
68 */
69 Node findNode(String identifier) {
70 VariableFinderVisitor finder = new VariableFinderVisitor(identifier);
71 ast.accept(finder);
72 return finder.result;
73 }
74
75 /**
76 * Finds the [Element] corresponding to [: className#fieldName :].
77 */
78 Element findField(String className, String fieldName) {
79 ClassElement element = compiler.mainApp.find(buildSourceString(className));
80 return element.lookupLocalMember(buildSourceString(fieldName));
81 }
82
83 static ConcreteType concreteFrom(List<BaseType> baseTypes) {
84 ConcreteType result = new ConcreteType.empty();
85 for (final baseType in baseTypes) {
86 result = result.union(new ConcreteType.singleton(baseType));
87 }
88 return result;
89 }
90
91 /**
92 * Checks that the inferred type of the node corresponding to the last
93 * occurence of [: variable; :] in the program is the concrete type
94 * made of [baseTypes].
95 */
96 void checkNodeHasType(String variable, List<BaseType> baseTypes) {
97 return Expect.equals(
98 concreteFrom(baseTypes),
99 inferrer.inferredTypes[findNode(variable)]);
100 }
101
102 /**
103 * Checks that [: className#fieldName :]'s inferred type is the concrete type
104 * made of [baseTypes].
105 */
106 void checkFieldHasType(String className, String fieldName,
107 List<BaseType> baseTypes) {
108 return Expect.equals(
109 concreteFrom(baseTypes),
110 inferrer.inferredFieldTypes[findField(className, fieldName)]);
111 }
112 }
113
114 AnalysisResult analyze(String code) {
115 Uri uri = new Uri.fromComponents(scheme: 'source');
116 MockCompiler compiler = new MockCompiler();
117 compiler.sourceFiles[uri.toString()] = new SourceFile(uri.toString(), code);
118 compiler.runCompiler(uri);
119 ConcreteTypesInferrer inferrer = new ConcreteTypesInferrer(compiler);
120 inferrer.analyzeMain(compiler.mainApp.find(const SourceString("main")));
121 return new AnalysisResult(compiler, inferrer);
122 }
123
124 testLiterals() {
125 final String source = r"""
126 main() {
127 var v1 = 42;
128 var v2 = 42.0;
129 var v3 = 'abc';
130 var v4 = true;
131 var v5 = null;
132 v1; v2; v3; v4; v5;
133 }
134 """;
135 AnalysisResult result = analyze(source);
136 result.checkNodeHasType('v1', [result.int]);
137 result.checkNodeHasType('v2', [result.double]);
138 result.checkNodeHasType('v3', [result.string]);
139 result.checkNodeHasType('v4', [result.bool]);
140 result.checkNodeHasType('v5', [new NullBaseType()]);
141 }
142
143 testRedefinition() {
144 final String source = r"""
145 main() {
146 var foo = 42;
147 foo = 'abc';
148 foo;
149 }
150 """;
151 AnalysisResult result = analyze(source);
152 result.checkNodeHasType('foo', [result.string]);
153 }
154
155 testIfThenElse() {
156 final String source = r"""
157 main() {
158 var foo = 42;
159 if (true) {
160 foo = 'abc';
161 } else {
162 foo = false;
163 }
164 foo;
165 }
166 """;
167 AnalysisResult result = analyze(source);
168 result.checkNodeHasType('foo', [result.string, result.bool]);
169 }
170
171 testTernaryIf() {
172 final String source = r"""
173 main() {
174 var foo = 42;
175 foo = true ? 'abc' : false;
176 foo;
177 }
178 """;
179 AnalysisResult result = analyze(source);
180 result.checkNodeHasType('foo', [result.string, result.bool]);
181 }
182
183 testWhile() {
184 final String source = r"""
185 class A { f() => new B(); }
186 class B { f() => new C(); }
187 class C { f() => new A(); }
188 main() {
189 var foo = new A();
190 while(true) {
191 foo = foo.f();
192 }
193 foo;
194 }
195 """;
196 AnalysisResult result = analyze(source);
197 result.checkNodeHasType(
198 'foo',
199 [result.base('A'), result.base('B'), result.base('C')]);
200 }
201
202 testNonRecusiveFunction() {
203 final String source = r"""
204 f(x, y) => true ? x : y;
205 main() { var foo = f(42, "abc"); foo; }
206 """;
207 AnalysisResult result = analyze(source);
208 result.checkNodeHasType('foo', [result.int, result.string]);
209 }
210
211 testRecusiveFunction() {
212 final String source = r"""
213 f(x) {
214 if (true) return x;
215 else return f(true ? x : "abc");
216 }
217 main() { var foo = f(42); foo; }
218 """;
219 AnalysisResult result = analyze(source);
220 result.checkNodeHasType('foo', [result.int, result.string]);
221 }
222
223 testMutuallyRecusiveFunction() {
224 final String source = r"""
225 f() => true ? 42 : g();
226 g() => true ? "abc" : f();
227 main() { var foo = f(); foo; }
228 """;
229 AnalysisResult result = analyze(source);
230 result.checkNodeHasType('foo', [result.int, result.string]);
231 }
232
233 testConstructor() {
234 final String source = r"""
235 class A {
236 var x, y, z;
237 A(this.x, a) : y = a { z = 'abc'; }
238 }
239 main() {
240 new A(42, 'abc');
241 new A(true, null);
242 }
243 """;
244 AnalysisResult result = analyze(source);
245 result.checkFieldHasType('A', 'x', [result.int, result.bool]);
246 result.checkFieldHasType('A', 'y', [result.string, new NullBaseType()]);
247 result.checkFieldHasType('A', 'z', [result.string]);
248 }
249
250 testGetters() {
251 final String source = r"""
252 class A {
253 var x;
254 A(this.x);
255 get y() => x;
256 }
257 main() {
258 var a = new A(42);
259 var foo = a.x;
260 var bar = a.y;
261 foo; bar;
262 }
263 """;
264 AnalysisResult result = analyze(source);
265 result.checkNodeHasType('foo', [result.int]);
266 result.checkNodeHasType('bar', [result.int]);
267 }
268
269 testSetters() {
270 final String source = r"""
271 class A {
272 var x;
273 A(this.x);
274 set y(a) { x = a; }
275 }
276 main() {
277 var a = new A(42);
278 a.x = 'abc';
279 a.y = true;
280 }
281 """;
282 AnalysisResult result = analyze(source);
283 result.checkFieldHasType('A', 'x', [result.int, result.string, result.bool]);
284 }
285
286 testNamedParameters() {
287 final String source = r"""
288 class A {
289 var x, y, z, w;
290 A(this.x, [this.y, this.z, this.w]);
291 }
292 main() {
293 new A(42);
294 new A('abc', w: true, z: 42.0);
295 }
296 """;
297 AnalysisResult result = analyze(source);
298 result.checkFieldHasType('A', 'x', [result.int, result.string]);
299 result.checkFieldHasType('A', 'y', [new NullBaseType()]);
300 result.checkFieldHasType('A', 'z', [new NullBaseType(), result.double]);
301 result.checkFieldHasType('A', 'w', [new NullBaseType(), result.bool]);
302 }
303
304 void main() {
305 testLiterals();
306 testRedefinition();
307 testIfThenElse();
308 testTernaryIf();
309 testWhile();
310 testNonRecusiveFunction();
311 testRecusiveFunction();
312 testMutuallyRecusiveFunction();
313 testConstructor();
314 testGetters();
315 testSetters();
316 testNamedParameters();
317 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/types/types.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698