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

Side by Side Diff: frog/tests/leg/src/ResolverTest.dart

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

Powered by Google App Engine
This is Rietveld 408576698