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

Side by Side Diff: frog/leg/resolver.dart

Issue 8974014: Resolve initializers in constructors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add tests. Created 9 years 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
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 class TreeElements { 5 class TreeElements {
6 Map<Node, Element> map; 6 Map<Node, Element> map;
7 TreeElements() : map = new LinkedHashMap<Node, Element>(); 7 TreeElements() : map = new LinkedHashMap<Node, Element>();
8 operator []=(Node node, Element element) => map[node] = element; 8 operator []=(Node node, Element element) => map[node] = element;
9 operator [](Node node) => map[node]; 9 operator [](Node node) => map[node];
10 } 10 }
11 11
12 class ResolverTask extends CompilerTask { 12 class ResolverTask extends CompilerTask {
13 Queue<ClassElement> toResolve; 13 Queue<ClassElement> toResolve;
14 14
15 ResolverTask(Compiler compiler) 15 ResolverTask(Compiler compiler)
16 : super(compiler), toResolve = new Queue<ClassElement>(); 16 : super(compiler), toResolve = new Queue<ClassElement>();
17 17
18 String get name() => 'Resolver'; 18 String get name() => 'Resolver';
19 19
20 TreeElements resolve(FunctionElement element) { 20 TreeElements resolve(FunctionElement element) {
21 return measure(() { 21 return measure(() {
22 FunctionExpression tree = element.parseNode(compiler, compiler); 22 FunctionExpression tree = element.parseNode(compiler, compiler);
23 if (tree.initializers !== null) {
24 compiler.cancel('initializers are not implemented',
25 node: tree.initializers);
26 }
27 ResolverVisitor visitor = new SignatureResolverVisitor(compiler, element); 23 ResolverVisitor visitor = new SignatureResolverVisitor(compiler, element);
28 visitor.visit(tree); 24 visitor.visit(tree);
29 25
26 if (tree.initializers != null) {
27 visitor = new FullResolverVisitor.from(visitor);
28 for (Link<Node> link = tree.initializers.nodes;
29 !link.isEmpty();
30 link = link.tail) {
31 SendSet init = link.head;
floitsch 2011/12/19 17:25:29 How can you be sure that this is a SendSet? What a
karlklose 2011/12/21 10:19:44 Done, added a test.
32 Node value = init.arguments.head;
33 visitor.visitIn(value, new StaticScope(visitor.context));
34 }
35 }
36
30 visitor = new FullResolverVisitor.from(visitor); 37 visitor = new FullResolverVisitor.from(visitor);
31 visitor.visit(tree.body); 38 visitor.visit(tree.body);
32 39
33 // Resolve the type annotations encountered in the method. 40 // Resolve the type annotations encountered in the method.
34 while (!toResolve.isEmpty()) { 41 while (!toResolve.isEmpty()) {
35 toResolve.removeFirst().resolve(compiler); 42 toResolve.removeFirst().resolve(compiler);
36 } 43 }
37 return visitor.mapping; 44 return visitor.mapping;
38 }); 45 });
39 } 46 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 143
137 class SignatureResolverVisitor extends ResolverVisitor { 144 class SignatureResolverVisitor extends ResolverVisitor {
138 FunctionElement element; 145 FunctionElement element;
139 146
140 SignatureResolverVisitor(Compiler compiler, FunctionElement element) 147 SignatureResolverVisitor(Compiler compiler, FunctionElement element)
141 : super(compiler, element), this.element = element; 148 : super(compiler, element), this.element = element;
142 149
143 visitFunctionExpression(FunctionExpression node) { 150 visitFunctionExpression(FunctionExpression node) {
144 useElement(node, element); 151 useElement(node, element);
145 context = new MethodScope(context, element); 152 context = new MethodScope(context, element);
146
147 if (element.parameters == null) { 153 if (element.parameters == null) {
148 ParametersVisitor visitor = new ParametersVisitor(this); 154 ParametersVisitor visitor = new ParametersVisitor(this);
149 visitor.visit(node.parameters); 155 visitor.visit(node.parameters);
150 element.parameters = visitor.elements.toLink(); 156 element.parameters = visitor.elements.toLink();
151 } else { 157 } else {
152 Link<Node> parameterNodes = node.parameters.nodes; 158 Link<Node> parameterNodes = node.parameters.nodes;
153 for (Link<Element> link = element.parameters; 159 for (Link<Element> link = element.parameters;
154 !link.isEmpty() && !parameterNodes.isEmpty(); 160 !link.isEmpty() && !parameterNodes.isEmpty();
155 link = link.tail, parameterNodes = parameterNodes.tail) { 161 link = link.tail, parameterNodes = parameterNodes.tail) {
156 defineElement(parameterNodes.head.definitions.nodes.head, link.head); 162 defineElement(parameterNodes.head.definitions.nodes.head, link.head);
157 } 163 }
158 } 164 }
159 165
166 if (node.initializers !== null) {
ngeoffray 2011/12/20 15:09:51 As discussed, I don't think this is the right plac
karlklose 2011/12/21 10:19:44 Done.
167 Set<SourceString> initializedNames = new Set<SourceString>();
168 for (Link<Node> link = node.initializers.nodes;
169 !link.isEmpty();
170 link = link.tail) {
171 SendSet init = link.head.asSendSet();
172 if (init == null
floitsch 2011/12/19 17:25:29 super call is missing. Add TODO?
ahe 2011/12/19 18:07:26 In addition, there might be a this(...) send.
karlklose 2011/12/21 10:19:44 Done, added a todo for super(...) and this(...).
173 || init.assignmentOperator.token.stringValue != '=') {
174 compiler.cancel('internal error: invalid initializer',
175 node: node.initializers);
ahe 2011/12/19 18:07:26 "node.initializers" should be "link.head".
karlklose 2011/12/21 10:19:44 Done.
176 } else {
177 if (init.receiver != null &&
178 (init.receiver.asIdentifier() == null
179 || init.receiver.asIdentifier().source.stringValue != 'this')) {
180 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
181 }
182 SourceString name = init.selector.asIdentifier().source;
ahe 2011/12/19 18:07:26 The above code looks a bit brittle and seems to re
karlklose 2011/12/21 10:19:44 Done.
183 ClassElement classElement = element.enclosingElement;
184 Element target = classElement.lookupLocalElement(name);
185 if (target == null) {
186 error(init, MessageKind.CANNOT_RESOLVE, [name]);
187 }
188 if (initializedNames.contains(name)) {
189 warning(init, MessageKind.DUPLICATION_INITIALIZATION, [name]);
190 }
191 initializedNames.add(name);
192 useElement(init.selector, target);
floitsch 2011/12/20 14:18:27 This should be useElement(init, target);
karlklose 2011/12/21 10:19:44 Done.
193 }
194 }
195 }
196
160 return element; 197 return element;
161 } 198 }
162 } 199 }
163 200
164 class FullResolverVisitor extends ResolverVisitor { 201 class FullResolverVisitor extends ResolverVisitor {
165 202
166 FullResolverVisitor(Compiler compiler, Element element) 203 FullResolverVisitor(Compiler compiler, Element element)
167 : super(compiler, element); 204 : super(compiler, element);
168 FullResolverVisitor.from(ResolverVisitor other) : super.from(other); 205 FullResolverVisitor.from(ResolverVisitor other) : super.from(other);
169 206
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 } 585 }
549 586
550 class Scope { 587 class Scope {
551 final Element element; 588 final Element element;
552 final Scope parent; 589 final Scope parent;
553 590
554 Map<SourceString, Element> get elements() => const {}; 591 Map<SourceString, Element> get elements() => const {};
555 592
556 Scope(this.parent, this.element); 593 Scope(this.parent, this.element);
557 abstract Element add(Element element); 594 abstract Element add(Element element);
558 abstract Element lookup(Element element); 595 abstract Element lookup(SourceString name);
ngeoffray 2011/12/20 15:09:51 Thanks!
559 } 596 }
560 597
561 class MethodScope extends Scope { 598 class MethodScope extends Scope {
562 final Map<SourceString, Element> elements; 599 final Map<SourceString, Element> elements;
563 600
564 MethodScope(Scope parent, Element element) 601 MethodScope(Scope parent, Element element)
565 : super(parent, element), this.elements = {}; 602 : super(parent, element), this.elements = {};
566 603
567 Element lookup(SourceString name) { 604 Element lookup(SourceString name) {
568 Element element = elements[name]; 605 Element element = elements[name];
(...skipping 24 matching lines...) Expand all
593 if (element != null) return element; 630 if (element != null) return element;
594 // TODO(ngeoffray): Lookup in the super class. 631 // TODO(ngeoffray): Lookup in the super class.
595 return null; 632 return null;
596 } 633 }
597 634
598 Element add(Element element) { 635 Element add(Element element) {
599 throw "Cannot add an element in a class scope"; 636 throw "Cannot add an element in a class scope";
600 } 637 }
601 } 638 }
602 639
640 class StaticScope extends Scope {
641 StaticScope(Scope parent) : super(parent, null);
642
643 Element lookup(SourceString name) {
ahe 2011/12/19 18:07:26 This concerns me as it seems to create an extra na
ngeoffray 2011/12/20 15:09:51 Two suggestions to address this problem. 1) Create
644 Element result = parent.lookup(name);
645 return (result != null && !result.isInstanceMember()) ? result : null;
646 }
647
648 Element add(Element element) => parent.add(element);
ngeoffray 2011/12/20 15:09:51 Do we expect to add to this scope?
649 }
650
603 // TODO(ngeoffray): this top scope should have libraryElement as 651 // TODO(ngeoffray): this top scope should have libraryElement as
604 // element. 652 // element.
605 class TopScope extends Scope { 653 class TopScope extends Scope {
606 Universe universe; 654 Universe universe;
607 655
608 TopScope(Universe this.universe) : super(null, null); 656 TopScope(Universe this.universe) : super(null, null);
609 Element lookup(SourceString name) => universe.find(name); 657 Element lookup(SourceString name) => universe.find(name);
610 658
611 Element add(Element element) { 659 Element add(Element element) {
612 throw "Cannot add an element in the top scope"; 660 throw "Cannot add an element in the top scope";
613 } 661 }
614 } 662 }
OLDNEW
« no previous file with comments | « frog/leg/elements/elements.dart ('k') | frog/leg/warnings.dart » ('j') | frog/leg/warnings.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698