| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #import("../../../leg/leg.dart"); | 5 #import("../../../leg/leg.dart"); |
| 6 #import("../../../leg/elements/elements.dart"); | 6 #import("../../../leg/elements/elements.dart"); |
| 7 #import("../../../leg/tree/tree.dart"); | 7 #import("../../../leg/tree/tree.dart"); |
| 8 #import("../../../leg/util/util.dart"); | 8 #import("../../../leg/util/util.dart"); |
| 9 #import("mock_compiler.dart"); | 9 #import("mock_compiler.dart"); |
| 10 #import("parser_helper.dart"); | 10 #import("parser_helper.dart"); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 testParametersOne(); | 57 testParametersOne(); |
| 58 testFor(); | 58 testFor(); |
| 59 testTypeAnnotation(); | 59 testTypeAnnotation(); |
| 60 testSuperclass(); | 60 testSuperclass(); |
| 61 // testVarSuperclass(); // The parser crashes with 'class Foo extends var'. | 61 // testVarSuperclass(); // The parser crashes with 'class Foo extends var'. |
| 62 // testOneInterface(); // The parser does not handle interfaces. | 62 // testOneInterface(); // The parser does not handle interfaces. |
| 63 // testTwoInterfaces(); // The parser does not handle interfaces. | 63 // testTwoInterfaces(); // The parser does not handle interfaces. |
| 64 testFunctionExpression(); | 64 testFunctionExpression(); |
| 65 testNewExpression(); | 65 testNewExpression(); |
| 66 testTopLevelFields(); | 66 testTopLevelFields(); |
| 67 testInitializers(); |
| 67 testThis(); | 68 testThis(); |
| 68 } | 69 } |
| 69 | 70 |
| 70 testThis() { | 71 testThis() { |
| 71 MockCompiler compiler = new MockCompiler(); | 72 MockCompiler compiler = new MockCompiler(); |
| 72 Universe universe = compiler.universe; | 73 Universe universe = compiler.universe; |
| 73 compiler.parseScript("class Foo { foo() { return this; } }"); | 74 compiler.parseScript("class Foo { foo() { return this; } }"); |
| 74 compiler.resolveStatement("Foo foo;"); | 75 compiler.resolveStatement("Foo foo;"); |
| 75 ClassElement fooElement = universe.find(buildSourceString("Foo")); | 76 ClassElement fooElement = universe.find(buildSourceString("Foo")); |
| 76 FunctionElement funElement = | 77 FunctionElement funElement = |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 compiler.errors[0].message); | 127 compiler.errors[0].message); |
| 127 } | 128 } |
| 128 | 129 |
| 129 | 130 |
| 130 testLocalsTwo() { | 131 testLocalsTwo() { |
| 131 MockCompiler compiler = new MockCompiler(); | 132 MockCompiler compiler = new MockCompiler(); |
| 132 ResolverVisitor visitor = compiler.resolverVisitor(); | 133 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 133 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); | 134 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); |
| 134 Element element = visitor.visit(tree); | 135 Element element = visitor.visit(tree); |
| 135 Expect.equals(null, element); | 136 Expect.equals(null, element); |
| 136 Expect.equals(0, visitor.context.elements.length); | 137 BlockScope scope = visitor.context; |
| 138 Expect.equals(0, scope.elements.length); |
| 137 Expect.equals(2, visitor.mapping.map.length); | 139 Expect.equals(2, visitor.mapping.map.length); |
| 138 | 140 |
| 139 List<Element> elements = visitor.mapping.map.getValues(); | 141 List<Element> elements = visitor.mapping.map.getValues(); |
| 140 Expect.notEquals(elements[0], elements[1]); | 142 Expect.notEquals(elements[0], elements[1]); |
| 141 } | 143 } |
| 142 | 144 |
| 143 testLocalsThree() { | 145 testLocalsThree() { |
| 144 MockCompiler compiler = new MockCompiler(); | 146 MockCompiler compiler = new MockCompiler(); |
| 145 ResolverVisitor visitor = compiler.resolverVisitor(); | 147 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 146 Node tree = parseStatement("{ var a = 1; if (true) { a; } }"); | 148 Node tree = parseStatement("{ var a = 1; if (true) { a; } }"); |
| 147 Element element = visitor.visit(tree); | 149 Element element = visitor.visit(tree); |
| 148 Expect.equals(null, element); | 150 Expect.equals(null, element); |
| 149 Expect.equals(0, visitor.context.elements.length); | 151 BlockScope scope = visitor.context; |
| 152 Expect.equals(0, scope.elements.length); |
| 150 Expect.equals(2, visitor.mapping.map.length); | 153 Expect.equals(2, visitor.mapping.map.length); |
| 151 List<Element> elements = visitor.mapping.map.getValues(); | 154 List<Element> elements = visitor.mapping.map.getValues(); |
| 152 Expect.equals(elements[0], elements[1]); | 155 Expect.equals(elements[0], elements[1]); |
| 153 } | 156 } |
| 154 | 157 |
| 155 testLocalsFour() { | 158 testLocalsFour() { |
| 156 MockCompiler compiler = new MockCompiler(); | 159 MockCompiler compiler = new MockCompiler(); |
| 157 ResolverVisitor visitor = compiler.resolverVisitor(); | 160 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 158 Node tree = parseStatement("{ var a = 1; if (true) { var a = 1; } }"); | 161 Node tree = parseStatement("{ var a = 1; if (true) { var a = 1; } }"); |
| 159 Element element = visitor.visit(tree); | 162 Element element = visitor.visit(tree); |
| 160 Expect.equals(null, element); | 163 Expect.equals(null, element); |
| 161 Expect.equals(0, visitor.context.elements.length); | 164 BlockScope scope = visitor.context; |
| 165 Expect.equals(0, scope.elements.length); |
| 162 Expect.equals(2, visitor.mapping.map.length); | 166 Expect.equals(2, visitor.mapping.map.length); |
| 163 List<Element> elements = visitor.mapping.map.getValues(); | 167 List<Element> elements = visitor.mapping.map.getValues(); |
| 164 Expect.notEquals(elements[0], elements[1]); | 168 Expect.notEquals(elements[0], elements[1]); |
| 165 } | 169 } |
| 166 | 170 |
| 167 testLocalsFive() { | 171 testLocalsFive() { |
| 168 MockCompiler compiler = new MockCompiler(); | 172 MockCompiler compiler = new MockCompiler(); |
| 169 ResolverVisitor visitor = compiler.resolverVisitor(); | 173 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 170 If tree = parseStatement("if (true) { var a = 1; a; } else { var a = 2; a;}"); | 174 If tree = parseStatement("if (true) { var a = 1; a; } else { var a = 2; a;}"); |
| 171 Element element = visitor.visit(tree); | 175 Element element = visitor.visit(tree); |
| 172 Expect.equals(null, element); | 176 Expect.equals(null, element); |
| 173 Expect.equals(0, visitor.context.elements.length); | 177 BlockScope scope = visitor.context; |
| 178 Expect.equals(0, scope.elements.length); |
| 174 Expect.equals(4, visitor.mapping.map.length); | 179 Expect.equals(4, visitor.mapping.map.length); |
| 175 | 180 |
| 176 Block thenPart = tree.thenPart; | 181 Block thenPart = tree.thenPart; |
| 177 List statements1 = thenPart.statements.nodes.toList(); | 182 List statements1 = thenPart.statements.nodes.toList(); |
| 178 Node def1 = statements1[0].definitions.nodes.head; | 183 Node def1 = statements1[0].definitions.nodes.head; |
| 179 Node id1 = statements1[1].expression; | 184 Node id1 = statements1[1].expression; |
| 180 Expect.equals(visitor.mapping[def1], visitor.mapping[id1]); | 185 Expect.equals(visitor.mapping[def1], visitor.mapping[id1]); |
| 181 | 186 |
| 182 Block elsePart = tree.elsePart; | 187 Block elsePart = tree.elsePart; |
| 183 List statements2 = elsePart.statements.nodes.toList(); | 188 List statements2 = elsePart.statements.nodes.toList(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 209 Expect.equals(ElementKind.PARAMETER, visitor.mapping[use].kind); | 214 Expect.equals(ElementKind.PARAMETER, visitor.mapping[use].kind); |
| 210 Expect.equals(visitor.mapping[param], visitor.mapping[use]); | 215 Expect.equals(visitor.mapping[param], visitor.mapping[use]); |
| 211 } | 216 } |
| 212 | 217 |
| 213 testFor() { | 218 testFor() { |
| 214 MockCompiler compiler = new MockCompiler(); | 219 MockCompiler compiler = new MockCompiler(); |
| 215 ResolverVisitor visitor = compiler.resolverVisitor(); | 220 ResolverVisitor visitor = compiler.resolverVisitor(); |
| 216 For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }"); | 221 For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }"); |
| 217 visitor.visit(tree); | 222 visitor.visit(tree); |
| 218 | 223 |
| 219 Expect.equals(0, visitor.context.elements.length); | 224 BlockScope scope = visitor.context; |
| 225 Expect.equals(0, scope.elements.length); |
| 220 Expect.equals(7, visitor.mapping.map.length); | 226 Expect.equals(7, visitor.mapping.map.length); |
| 221 | 227 |
| 222 VariableDefinitions initializer = tree.initializer; | 228 VariableDefinitions initializer = tree.initializer; |
| 223 Node iNode = initializer.definitions.nodes.head; | 229 Node iNode = initializer.definitions.nodes.head; |
| 224 Element iElement = visitor.mapping[iNode]; | 230 Element iElement = visitor.mapping[iNode]; |
| 225 | 231 |
| 226 // Check that we have the expected nodes. This test relies on the mapping | 232 // Check that we have the expected nodes. This test relies on the mapping |
| 227 // field to be a linked hash map (preserving insertion order). | 233 // field to be a linked hash map (preserving insertion order). |
| 228 Expect.isTrue(visitor.mapping.map is LinkedHashMap); | 234 Expect.isTrue(visitor.mapping.map is LinkedHashMap); |
| 229 List<Node> nodes = visitor.mapping.map.getKeys(); | 235 List<Node> nodes = visitor.mapping.map.getKeys(); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 Expect.equals(ElementKind.FIELD, cElement.kind); | 417 Expect.equals(ElementKind.FIELD, cElement.kind); |
| 412 Expect.isTrue(bElement != cElement); | 418 Expect.isTrue(bElement != cElement); |
| 413 | 419 |
| 414 VariableDefinitions bNode = bElement.parseNode(compiler, compiler); | 420 VariableDefinitions bNode = bElement.parseNode(compiler, compiler); |
| 415 VariableDefinitions cNode = cElement.parseNode(compiler, compiler); | 421 VariableDefinitions cNode = cElement.parseNode(compiler, compiler); |
| 416 Expect.equals(bNode, cNode); | 422 Expect.equals(bNode, cNode); |
| 417 Expect.isNull(bNode.type); | 423 Expect.isNull(bNode.type); |
| 418 Expect.isTrue(bNode.modifiers.isVar()); | 424 Expect.isTrue(bNode.modifiers.isVar()); |
| 419 } | 425 } |
| 420 | 426 |
| 427 resolveConstructor(String script, String statement, String className, |
| 428 String constructor, int expectedElementCount, |
| 429 [List expectedWarnings = const [], |
| 430 List expectedErrors = const []]) { |
| 431 MockCompiler compiler = new MockCompiler(); |
| 432 compiler.parseScript(script); |
| 433 compiler.resolveStatement(statement); |
| 434 ClassElement classElement = |
| 435 compiler.universe.find(buildSourceString(className)); |
| 436 Element element = |
| 437 classElement.lookupLocalElement(buildSourceString(constructor)); |
| 438 FunctionExpression tree = element.parseNode(compiler, compiler); |
| 439 ResolverVisitor visitor = new FullResolverVisitor(compiler, element); |
| 440 compiler.resolver.resolveInitializers(element, tree, visitor); |
| 441 Expect.equals(expectedElementCount, visitor.mapping.map.length); |
| 442 |
| 443 compareWarningKinds(script, expectedWarnings, compiler.warnings); |
| 444 compareWarningKinds(script, expectedErrors, compiler.errors); |
| 445 } |
| 446 |
| 447 testInitializers() { |
| 448 String script; |
| 449 script = """class A { |
| 450 int foo; int bar; |
| 451 A() : this.foo = 1, bar = 2; |
| 452 }"""; |
| 453 resolveConstructor(script, "A a = new A();", "A", "A", 2); |
| 454 |
| 455 script = """class A { |
| 456 int foo; A a; |
| 457 A() : a.foo = 1; |
| 458 }"""; |
| 459 resolveConstructor(script, "A a = new A();", "A", "A", 1, |
| 460 [], [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]); |
| 461 |
| 462 script = """class A { |
| 463 int foo; |
| 464 A() : this.foo = 1, this.foo = 2; |
| 465 }"""; |
| 466 resolveConstructor(script, "A a = new A();", "A", "A", 2, |
| 467 [MessageKind.ALREADY_INITIALIZED], |
| 468 [MessageKind.DUPLICATE_INITIALIZER]); |
| 469 |
| 470 script = """class A { |
| 471 A() : this.foo = 1; |
| 472 }"""; |
| 473 resolveConstructor(script, "A a = new A();", "A", "A", 0, |
| 474 [], [MessageKind.CANNOT_RESOLVE]); |
| 475 |
| 476 script = """class A { |
| 477 int foo; |
| 478 int bar; |
| 479 A() : this.foo = bar; |
| 480 }"""; |
| 481 resolveConstructor(script, "A a = new A();", "A", "A", 2, |
| 482 [], [MessageKind.NOT_STATIC]); |
| 483 } |
| 484 |
| 421 length(Link link) => link.isEmpty() ? 0 : length(link.tail) + 1; | 485 length(Link link) => link.isEmpty() ? 0 : length(link.tail) + 1; |
| 422 | 486 |
| 423 at(Link link, int index) => (index == 0) ? link.head : at(link.tail, index - 1); | 487 at(Link link, int index) => (index == 0) ? link.head : at(link.tail, index - 1); |
| OLD | NEW |