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

Side by Side Diff: frog/tests/leg/resolver_test.dart

Issue 10536169: Move frog/tests/{leg,leg_only,frog_native} to tests/compiler/. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | « frog/tests/leg/redundant_phi_eliminator_test.dart ('k') | frog/tests/leg/scanner_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, 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
5 #import("../../../lib/compiler/implementation/leg.dart");
6 #import("../../../lib/compiler/implementation/elements/elements.dart");
7 #import("../../../lib/compiler/implementation/tree/tree.dart");
8 #import("../../../lib/compiler/implementation/util/util.dart");
9 #import("mock_compiler.dart");
10 #import("parser_helper.dart");
11
12 Node buildIdentifier(String name) => new Identifier(scan(name));
13
14 Node buildInitialization(String name) =>
15 parseBodyCode('$name = 1',
16 (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens));
17
18 createLocals(List variables) {
19 var locals = [];
20 for (final variable in variables) {
21 String name = variable[0];
22 bool init = variable[1];
23 if (init) {
24 locals.add(buildInitialization(name));
25 } else {
26 locals.add(buildIdentifier(name));
27 }
28 }
29 var definitions = new NodeList(null, new Link.fromList(locals), null, null);
30 return new VariableDefinitions(null, null, definitions, null);
31 }
32
33 testLocals(List variables) {
34 MockCompiler compiler = new MockCompiler();
35 ResolverVisitor visitor = compiler.resolverVisitor();
36 Element element = visitor.visit(createLocals(variables));
37 // A VariableDefinitions does not have an element.
38 Expect.equals(null, element);
39 Expect.equals(variables.length, map(visitor).length);
40
41 for (final variable in variables) {
42 final name = variable[0];
43 Identifier id = buildIdentifier(name);
44 final VariableElement variableElement = visitor.visit(id);
45 MethodScope scope = visitor.context;
46 Expect.equals(variableElement, scope.elements[buildSourceString(name)]);
47 }
48 return compiler;
49 }
50
51 main() {
52 testLocalsOne();
53 testLocalsTwo();
54 testLocalsThree();
55 testLocalsFour();
56 testLocalsFive();
57 testParametersOne();
58 testFor();
59 testTypeAnnotation();
60 testSuperclass();
61 // testVarSuperclass(); // The parser crashes with 'class Foo extends var'.
62 // testOneInterface(); // Generates unexpected error message.
63 // testTwoInterfaces(); // Generates unexpected error message.
64 testFunctionExpression();
65 testNewExpression();
66 testTopLevelFields();
67 testClassHierarchy();
68 testInitializers();
69 testThis();
70 testSuperCalls();
71 testTypeVariables();
72 }
73
74 testTypeVariables() {
75 matchResolvedTypes(visitor, text, name, expectedElements) {
76 VariableDefinitions definition = parseStatement(text);
77 visitor.visit(definition.type);
78 InterfaceType type = visitor.mapping.getType(definition.type);
79 Expect.equals(definition.type.typeArguments.length(),
80 length(type.arguments));
81 int index = 0;
82 Link<Type> arguments = type.arguments;
83 while (!arguments.isEmpty()) {
84 Expect.equals(true, index < expectedElements.length);
85 Expect.equals(expectedElements[index], arguments.head.element);
86 index++;
87 arguments = arguments.tail;
88 }
89 Expect.equals(index, expectedElements.length);
90 }
91
92 MockCompiler compiler = new MockCompiler();
93 ResolverVisitor visitor = compiler.resolverVisitor();
94 compiler.parseScript('class Foo<T, U> {}');
95 ClassElement foo = compiler.mainApp.find(buildSourceString('Foo'));
96 matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo',
97 [compiler.intClass, compiler.stringClass]);
98 matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo',
99 [foo, foo]);
100
101 compiler = new MockCompiler();
102 compiler.parseScript('class Foo<T, U> {}');
103 compiler.resolveStatement('Foo<notype, int> x;');
104 Expect.equals(1, compiler.warnings.length);
105 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
106 compiler.warnings[0].message.kind);
107 Expect.equals(0, compiler.errors.length);
108
109 compiler = new MockCompiler();
110 compiler.parseScript('class Foo<T, U> {}');
111 compiler.resolveStatement('var x = new Foo<notype, int>();');
112 Expect.equals(0, compiler.warnings.length);
113 Expect.equals(1, compiler.errors.length);
114 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
115 compiler.errors[0].message.kind);
116
117 compiler = new MockCompiler();
118 compiler.parseScript('class Foo<T> {'
119 ' Foo<T> t;'
120 ' foo(Foo<T> f) {}'
121 ' bar() { g(Foo<T> f) {}; g(); }'
122 '}');
123 foo = compiler.mainApp.find(buildSourceString('Foo'));
124 compiler.resolveClass(foo);
125 foo.lookupLocalMember(buildSourceString('t')).computeType(compiler);;
126 foo.lookupLocalMember(buildSourceString('foo')).computeType(compiler);;
127 compiler.resolver.resolve(foo.lookupLocalMember(buildSourceString('bar')));
128 Expect.equals(0, compiler.warnings.length);
129 Expect.equals(0, compiler.errors.length);
130 }
131
132 testSuperCalls() {
133 MockCompiler compiler = new MockCompiler();
134 String script = """class A { foo() {} }
135 class B extends A { foo() => super.foo(); }""";
136 compiler.parseScript(script);
137 compiler.resolveStatement("B b;");
138
139 ClassElement classB = compiler.mainApp.find(buildSourceString("B"));
140 FunctionElement fooB = classB.lookupLocalMember(buildSourceString("foo"));
141 ClassElement classA = compiler.mainApp.find(buildSourceString("A"));
142 FunctionElement fooA = classA.lookupLocalMember(buildSourceString("foo"));
143
144 ResolverVisitor visitor = new ResolverVisitor(compiler, fooB);
145 FunctionExpression node = fooB.parseNode(compiler);
146 visitor.visit(node.body);
147 Map mapping = map(visitor);
148
149 Send superCall = node.body.asReturn().expression;
150 FunctionElement called = mapping[superCall];
151 Expect.isTrue(called !== null);
152 Expect.equals(fooA, called);
153 }
154
155 testThis() {
156 MockCompiler compiler = new MockCompiler();
157 compiler.parseScript("class Foo { foo() { return this; } }");
158 compiler.resolveStatement("Foo foo;");
159 ClassElement fooElement = compiler.mainApp.find(buildSourceString("Foo"));
160 FunctionElement funElement =
161 fooElement.lookupLocalMember(buildSourceString("foo"));
162 ResolverVisitor visitor = new ResolverVisitor(compiler, funElement);
163 FunctionExpression function = funElement.parseNode(compiler);
164 visitor.visit(function.body);
165 Map mapping = map(visitor);
166 List<Element> values = mapping.getValues();
167 Expect.equals(0, mapping.length);
168 Expect.equals(0, compiler.warnings.length);
169
170 compiler = new MockCompiler();
171 compiler.resolveStatement("main() { return this; }");
172 Expect.equals(0, compiler.warnings.length);
173 Expect.equals(1, compiler.errors.length);
174 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
175 compiler.errors[0].message.kind);
176
177 compiler = new MockCompiler();
178 compiler.parseScript("class Foo { static foo() { return this; } }");
179 compiler.resolveStatement("Foo foo;");
180 fooElement = compiler.mainApp.find(buildSourceString("Foo"));
181 funElement =
182 fooElement.lookupLocalMember(buildSourceString("foo"));
183 visitor = new ResolverVisitor(compiler, funElement);
184 function = funElement.parseNode(compiler);
185 visitor.visit(function.body);
186 Expect.equals(0, compiler.warnings.length);
187 Expect.equals(1, compiler.errors.length);
188 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
189 compiler.errors[0].message.kind);
190 }
191
192 testLocalsOne() {
193 testLocals([["foo", false]]);
194 testLocals([["foo", false], ["bar", false]]);
195 testLocals([["foo", false], ["bar", false], ["foobar", false]]);
196
197 testLocals([["foo", true]]);
198 testLocals([["foo", false], ["bar", true]]);
199 testLocals([["foo", true], ["bar", true]]);
200
201 testLocals([["foo", false], ["bar", false], ["foobar", true]]);
202 testLocals([["foo", false], ["bar", true], ["foobar", true]]);
203 testLocals([["foo", true], ["bar", true], ["foobar", true]]);
204
205 MockCompiler compiler = testLocals([["foo", false], ["foo", false]]);
206 Expect.equals(1, compiler.errors.length);
207 Expect.equals(
208 new Message(MessageKind.DUPLICATE_DEFINITION, ['foo']),
209 compiler.errors[0].message);
210 }
211
212
213 testLocalsTwo() {
214 MockCompiler compiler = new MockCompiler();
215 ResolverVisitor visitor = compiler.resolverVisitor();
216 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }");
217 Element element = visitor.visit(tree);
218 Expect.equals(null, element);
219 BlockScope scope = visitor.context;
220 Expect.equals(0, scope.elements.length);
221 Expect.equals(2, map(visitor).length);
222
223 List<Element> elements = map(visitor).getValues();
224 Expect.notEquals(elements[0], elements[1]);
225 }
226
227 testLocalsThree() {
228 MockCompiler compiler = new MockCompiler();
229 ResolverVisitor visitor = compiler.resolverVisitor();
230 Node tree = parseStatement("{ var a = 1; if (true) { a; } }");
231 Element element = visitor.visit(tree);
232 Expect.equals(null, element);
233 BlockScope scope = visitor.context;
234 Expect.equals(0, scope.elements.length);
235 Expect.equals(3, map(visitor).length);
236 List<Element> elements = map(visitor).getValues();
237 Expect.equals(elements[0], elements[1]);
238 }
239
240 testLocalsFour() {
241 MockCompiler compiler = new MockCompiler();
242 ResolverVisitor visitor = compiler.resolverVisitor();
243 Node tree = parseStatement("{ var a = 1; if (true) { var a = 1; } }");
244 Element element = visitor.visit(tree);
245 Expect.equals(null, element);
246 BlockScope scope = visitor.context;
247 Expect.equals(0, scope.elements.length);
248 Expect.equals(2, map(visitor).length);
249 List<Element> elements = map(visitor).getValues();
250 Expect.notEquals(elements[0], elements[1]);
251 }
252
253 testLocalsFive() {
254 MockCompiler compiler = new MockCompiler();
255 ResolverVisitor visitor = compiler.resolverVisitor();
256 If tree = parseStatement("if (true) { var a = 1; a; } else { var a = 2; a;}");
257 Element element = visitor.visit(tree);
258 Expect.equals(null, element);
259 BlockScope scope = visitor.context;
260 Expect.equals(0, scope.elements.length);
261 Expect.equals(6, map(visitor).length);
262
263 Block thenPart = tree.thenPart;
264 List statements1 = thenPart.statements.nodes.toList();
265 Node def1 = statements1[0].definitions.nodes.head;
266 Node id1 = statements1[1].expression;
267 Expect.equals(visitor.mapping[def1], visitor.mapping[id1]);
268
269 Block elsePart = tree.elsePart;
270 List statements2 = elsePart.statements.nodes.toList();
271 Node def2 = statements2[0].definitions.nodes.head;
272 Node id2 = statements2[1].expression;
273 Expect.equals(visitor.mapping[def2], visitor.mapping[id2]);
274
275 Expect.notEquals(visitor.mapping[def1], visitor.mapping[def2]);
276 Expect.notEquals(visitor.mapping[id1], visitor.mapping[id2]);
277 }
278
279 testParametersOne() {
280 MockCompiler compiler = new MockCompiler();
281 ResolverVisitor visitor = compiler.resolverVisitor();
282 FunctionExpression tree =
283 parseFunction("void foo(int a) { return a; }", compiler);
284 visitor.visit(tree);
285
286 // Check that an element has been created for the parameter.
287 VariableDefinitions vardef = tree.parameters.nodes.head;
288 Node param = vardef.definitions.nodes.head;
289 Expect.equals(ElementKind.PARAMETER, visitor.mapping[param].kind);
290
291 // Check that 'a' in 'return a' is resolved to the parameter.
292 Block body = tree.body;
293 Return ret = body.statements.nodes.head;
294 Send use = ret.expression;
295 Expect.equals(ElementKind.PARAMETER, visitor.mapping[use].kind);
296 Expect.equals(visitor.mapping[param], visitor.mapping[use]);
297 }
298
299 testFor() {
300 MockCompiler compiler = new MockCompiler();
301 ResolverVisitor visitor = compiler.resolverVisitor();
302 For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }");
303 visitor.visit(tree);
304
305 BlockScope scope = visitor.context;
306 Expect.equals(0, scope.elements.length);
307 Expect.equals(10, map(visitor).length);
308
309 VariableDefinitions initializer = tree.initializer;
310 Node iNode = initializer.definitions.nodes.head;
311 Element iElement = visitor.mapping[iNode];
312
313 // Check that we have the expected nodes. This test relies on the mapping
314 // field to be a linked hash map (preserving insertion order).
315 Expect.isTrue(map(visitor) is LinkedHashMap);
316 List<Node> nodes = map(visitor).getKeys();
317 List<Element> elements = map(visitor).getValues();
318
319
320 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
321 // ^^^
322 Expect.isTrue(nodes[0] is TypeAnnotation);
323
324 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
325 // ^^^^^
326 checkSendSet(iElement, nodes[1], elements[1]);
327
328 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
329 // ^
330 checkIdentifier(iElement, nodes[2], elements[2]);
331
332 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
333 // ^
334 checkSend(iElement, nodes[3], elements[3]);
335
336 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
337 // ^
338 checkIdentifier(iElement, nodes[4], elements[4]);
339
340 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
341 // ^
342 checkIdentifier(iElement, nodes[5], elements[5]);
343
344 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
345 // ^
346 checkSend(iElement, nodes[6], elements[6]);
347
348 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
349 // ^^^^^^^^^
350 checkSendSet(iElement, nodes[7], elements[7]);
351
352 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
353 // ^
354 checkIdentifier(iElement, nodes[8], elements[8]);
355
356 // for (int i = 0; i < 10; i = i + 1) { i = 5; };
357 // ^^^^^
358 checkSendSet(iElement, nodes[9], elements[9]);
359 }
360
361 checkIdentifier(Element expected, Node node, Element actual) {
362 Expect.isTrue(node is Identifier, node.toDebugString());
363 Expect.equals(expected, actual);
364 }
365
366 checkSend(Element expected, Node node, Element actual) {
367 Expect.isTrue(node is Send, node.toDebugString());
368 Expect.isTrue(node is !SendSet, node.toDebugString());
369 Expect.equals(expected, actual);
370 }
371
372 checkSendSet(Element expected, Node node, Element actual) {
373 Expect.isTrue(node is SendSet, node.toDebugString());
374 Expect.equals(expected, actual);
375 }
376
377 testTypeAnnotation() {
378 MockCompiler compiler = new MockCompiler();
379 String statement = "Foo bar;";
380
381 // Test that we get a warning when Foo is not defined.
382 Map mapping = compiler.resolveStatement(statement).map;
383
384 Expect.equals(1, mapping.length); // bar has an element.
385 Expect.equals(1, compiler.warnings.length);
386
387 Node warningNode = compiler.warnings[0].node;
388
389 Expect.equals(
390 new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Foo']),
391 compiler.warnings[0].message);
392 VariableDefinitions definition = compiler.parsedTree;
393 Expect.equals(warningNode, definition.type);
394 compiler.clearWarnings();
395
396 // Test that there is no warning after defining Foo.
397 compiler.parseScript("class Foo {}");
398 mapping = compiler.resolveStatement(statement).map;
399 Expect.equals(2, mapping.length);
400 Expect.equals(0, compiler.warnings.length);
401
402 // Test that 'var' does not create a warning.
403 mapping = compiler.resolveStatement("var foo;").map;
404 Expect.equals(1, mapping.length);
405 Expect.equals(0, compiler.warnings.length);
406 }
407
408 testSuperclass() {
409 MockCompiler compiler = new MockCompiler();
410 compiler.parseScript("class Foo extends Bar {}");
411 compiler.resolveStatement("Foo bar;");
412 Expect.equals(1, compiler.errors.length);
413 Expect.equals(
414 new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Bar']),
415 compiler.errors[0].message);
416 compiler.clearErrors();
417
418 compiler = new MockCompiler();
419 compiler.parseScript("class Foo extends Bar {}");
420 compiler.parseScript("class Bar {}");
421 Map mapping = compiler.resolveStatement("Foo bar;").map;
422 Expect.equals(2, mapping.length);
423
424 ClassElement fooElement = compiler.mainApp.find(buildSourceString('Foo'));
425 ClassElement barElement = compiler.mainApp.find(buildSourceString('Bar'));
426 Expect.equals(barElement.computeType(compiler),
427 fooElement.supertype);
428 Expect.isTrue(fooElement.interfaces.isEmpty());
429 Expect.isTrue(barElement.interfaces.isEmpty());
430 }
431
432 testVarSuperclass() {
433 MockCompiler compiler = new MockCompiler();
434 compiler.parseScript("class Foo extends var {}");
435 compiler.resolveStatement("Foo bar;");
436 Expect.equals(1, compiler.errors.length);
437 Expect.equals(
438 new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['var']),
439 compiler.errors[0].message);
440 compiler.clearErrors();
441 }
442
443 testOneInterface() {
444 MockCompiler compiler = new MockCompiler();
445 compiler.parseScript("class Foo implements Bar {}");
446 compiler.resolveStatement("Foo bar;");
447 Expect.equals(1, compiler.errors.length);
448 Expect.equals(
449 new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['bar']),
450 compiler.errors[0].message);
451 compiler.clearErrors();
452
453 // Add the interface to the world and make sure everything is setup correctly.
454 compiler.parseScript("interface Bar {}");
455
456 ResolverVisitor visitor = new ResolverVisitor(compiler, null);
457 compiler.resolveStatement("Foo bar;");
458
459 ClassElement fooElement = compiler.mainApp.find(buildSourceString('Foo'));
460 ClassElement barElement = compiler.mainApp.find(buildSourceString('Bar'));
461
462 Expect.equals(null, barElement.supertype);
463 Expect.isTrue(barElement.interfaces.isEmpty());
464
465 Expect.equals(barElement.computeType(compiler),
466 fooElement.interfaces.head);
467 Expect.equals(1, length(fooElement.interfaces));
468 }
469
470 testTwoInterfaces() {
471 MockCompiler compiler = new MockCompiler();
472 compiler.parseScript(
473 "interface I1 {} interface I2 {} class C implements I1, I2 {}");
474 compiler.resolveStatement("Foo bar;");
475
476 ClassElement c = compiler.mainApp.find(buildSourceString('C'));
477 Element i1 = compiler.mainApp.find(buildSourceString('I1'));
478 Element i2 = compiler.mainApp.find(buildSourceString('I2'));
479
480 Expect.equals(2, length(c.interfaces));
481 Expect.equals(i1.computeType(compiler), at(c.interfaces, 0));
482 Expect.equals(i2.computeType(compiler), at(c.interfaces, 1));
483 }
484
485 testFunctionExpression() {
486 MockCompiler compiler = new MockCompiler();
487 ResolverVisitor visitor = compiler.resolverVisitor();
488 Map mapping = compiler.resolveStatement("int f() {}").map;
489 Expect.equals(3, mapping.length);
490 Element element;
491 Node node;
492 mapping.forEach((Node n, Element e) {
493 if (n is FunctionExpression) {
494 element = e;
495 node = n;
496 }
497 });
498 Expect.equals(ElementKind.FUNCTION, element.kind);
499 Expect.equals(buildSourceString('f'), element.name);
500 Expect.equals(element.parseNode(compiler), node);
501 }
502
503 testNewExpression() {
504 MockCompiler compiler = new MockCompiler();
505 compiler.parseScript("class A {} foo() { print(new A()); }");
506 ClassElement aElement = compiler.mainApp.find(buildSourceString('A'));
507 FunctionElement fooElement = compiler.mainApp.find(buildSourceString('foo'));
508 Expect.isTrue(aElement !== null);
509 Expect.isTrue(fooElement !== null);
510
511 fooElement.parseNode(compiler);
512 compiler.resolver.resolve(fooElement);
513
514 TreeElements elements = compiler.resolveStatement("new A();");
515 NewExpression expression =
516 compiler.parsedTree.asExpressionStatement().expression;
517 Element element = elements[expression.send];
518 Expect.equals(ElementKind.GENERATIVE_CONSTRUCTOR, element.kind);
519 Expect.isTrue(element is SynthesizedConstructorElement);
520 }
521
522 testTopLevelFields() {
523 MockCompiler compiler = new MockCompiler();
524 compiler.parseScript("int a;");
525 VariableElement element = compiler.mainApp.find(buildSourceString("a"));
526 Expect.equals(ElementKind.FIELD, element.kind);
527 VariableDefinitions node = element.variables.parseNode(compiler);
528 Identifier typeName = node.type.typeName;
529 Expect.equals(typeName.source.slowToString(), 'int');
530
531 compiler.parseScript("var b, c;");
532 VariableElement bElement = compiler.mainApp.find(buildSourceString("b"));
533 VariableElement cElement = compiler.mainApp.find(buildSourceString("c"));
534 Expect.equals(ElementKind.FIELD, bElement.kind);
535 Expect.equals(ElementKind.FIELD, cElement.kind);
536 Expect.isTrue(bElement != cElement);
537
538 VariableDefinitions bNode = bElement.variables.parseNode(compiler);
539 VariableDefinitions cNode = cElement.variables.parseNode(compiler);
540 Expect.equals(bNode, cNode);
541 Expect.isNull(bNode.type);
542 Expect.isTrue(bNode.modifiers.isVar());
543 }
544
545 resolveConstructor(String script, String statement, String className,
546 String constructor, int expectedElementCount,
547 [List expectedWarnings = const [],
548 List expectedErrors = const [],
549 String corelib = DEFAULT_CORELIB]) {
550 MockCompiler compiler = new MockCompiler(corelib);
551 compiler.parseScript(script);
552 compiler.resolveStatement(statement);
553 ClassElement classElement =
554 compiler.mainApp.find(buildSourceString(className));
555 Element element =
556 classElement.lookupConstructor(buildSourceString(constructor));
557 FunctionExpression tree = element.parseNode(compiler);
558 ResolverVisitor visitor = new ResolverVisitor(compiler, element);
559 new InitializerResolver(visitor).resolveInitializers(element, tree);
560 visitor.visit(tree.body);
561 Expect.equals(expectedElementCount, map(visitor).length);
562
563 compareWarningKinds(script, expectedWarnings, compiler.warnings);
564 compareWarningKinds(script, expectedErrors, compiler.errors);
565 }
566
567 testClassHierarchy() {
568 final MAIN = buildSourceString("main");
569 MockCompiler compiler = new MockCompiler();
570 compiler.parseScript("""class A extends B {}
571 class B extends A {}
572 main() { return new A(); }""");
573 FunctionElement mainElement = compiler.mainApp.find(MAIN);
574 compiler.resolver.resolve(mainElement);
575 Expect.equals(0, compiler.warnings.length);
576 Expect.equals(1, compiler.errors.length);
577 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
578 compiler.errors[0].message.kind);
579
580 compiler = new MockCompiler();
581 compiler.parseScript("""interface A extends B {}
582 interface B extends A {}
583 class C implements A {}
584 main() { return new C(); }""");
585 mainElement = compiler.mainApp.find(MAIN);
586 compiler.resolver.resolve(mainElement);
587 Expect.equals(0, compiler.warnings.length);
588 Expect.equals(1, compiler.errors.length);
589 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
590 compiler.errors[0].message.kind);
591
592 compiler = new MockCompiler();
593 compiler.parseScript("""class A extends B {}
594 class B extends C {}
595 class C {}
596 main() { return new A(); }""");
597 mainElement = compiler.mainApp.find(MAIN);
598 compiler.resolver.resolve(mainElement);
599 Expect.equals(0, compiler.warnings.length);
600 Expect.equals(0, compiler.errors.length);
601 ClassElement aElement = compiler.mainApp.find(buildSourceString("A"));
602 Link<Type> supertypes = aElement.allSupertypes;
603 Expect.equals(<String>['B', 'C', 'Object'].toString(),
604 asSortedStrings(supertypes).toString());
605 }
606
607 testInitializers() {
608 String script;
609 script = """class A {
610 int foo; int bar;
611 A() : this.foo = 1, bar = 2;
612 }""";
613 resolveConstructor(script, "A a = new A();", "A", "A", 2);
614
615 script = """class A {
616 int foo; A a;
617 A() : a.foo = 1;
618 }""";
619 resolveConstructor(script, "A a = new A();", "A", "A", 0,
620 [], [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]);
621
622 script = """class A {
623 int foo;
624 A() : this.foo = 1, this.foo = 2;
625 }""";
626 resolveConstructor(script, "A a = new A();", "A", "A", 2,
627 [MessageKind.ALREADY_INITIALIZED],
628 [MessageKind.DUPLICATE_INITIALIZER]);
629
630 script = """class A {
631 A() : this.foo = 1;
632 }""";
633 resolveConstructor(script, "A a = new A();", "A", "A", 0,
634 [], [MessageKind.CANNOT_RESOLVE]);
635
636 script = """class A {
637 int foo;
638 int bar;
639 A() : this.foo = bar;
640 }""";
641 resolveConstructor(script, "A a = new A();", "A", "A", 3,
642 [], [MessageKind.NO_INSTANCE_AVAILABLE]);
643
644 script = """class A {
645 int foo() => 42;
646 A() : foo();
647 }""";
648 resolveConstructor(script, "A a = new A();", "A", "A", 0,
649 [], [MessageKind.CONSTRUCTOR_CALL_EXPECTED]);
650
651 script = """class A {
652 int i;
653 A.a() : this.b(0);
654 A.b(int i);
655 }""";
656 resolveConstructor(script, "A a = new A.a();", "A", @"A$a", 1,
657 [], []);
658
659 script = """class A {
660 int i;
661 A.a() : i = 42, this(0);
662 A(int i);
663 }""";
664 resolveConstructor(script, "A a = new A.a();", "A", @"A$a", 2,
665 [], [MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER]);
666
667 script = """class A {
668 int i;
669 A(i);
670 }
671 class B extends A {
672 B() : super(0);
673 }""";
674 resolveConstructor(script, "B a = new B();", "B", "B", 1,
675 [], []);
676
677 script = """class A {
678 int i;
679 A(i);
680 }
681 class B extends A {
682 B() : super(0), super(1);
683 }""";
684 resolveConstructor(script, "B b = new B();", "B", "B", 2,
685 [], [MessageKind.DUPLICATE_SUPER_INITIALIZER]);
686
687 script = "";
688 final String CORELIB_WITH_INVALID_OBJECT =
689 '''print(var obj) {}
690 class int {}
691 class double {}
692 class bool {}
693 class String {}
694 class num {}
695 class Function {}
696 class List {}
697 class Closure {}
698 class Null {}
699 class Dynamic {}
700 class Object { Object() : super(); }''';
701 resolveConstructor(script, "Object o = new Object();", "Object", "Object", 1,
702 [], [MessageKind.SUPER_INITIALIZER_IN_OBJECT],
703 corelib: CORELIB_WITH_INVALID_OBJECT);
704 }
705
706 map(ResolverVisitor visitor) {
707 TreeElementMapping elements = visitor.mapping;
708 return elements.map;
709 }
710
711 length(Link link) => link.isEmpty() ? 0 : length(link.tail) + 1;
712
713 at(Link link, int index) => (index == 0) ? link.head : at(link.tail, index - 1);
714
715 List<String> asSortedStrings(Link link) {
716 List<String> result = <String>[];
717 for (; !link.isEmpty(); link = link.tail) result.add(link.head.toString());
718 result.sort((s1, s2) => s1.compareTo(s2));
719 return result;
720 }
OLDNEW
« no previous file with comments | « frog/tests/leg/redundant_phi_eliminator_test.dart ('k') | frog/tests/leg/scanner_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698