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

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: Don't call function that does not exist. 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
30 visitor = new FullResolverVisitor.from(visitor); 26 visitor = new FullResolverVisitor.from(visitor);
27 if (tree.initializers != null) {
28 resolveInitializers(element, tree, visitor);
29 }
31 visitor.visit(tree.body); 30 visitor.visit(tree.body);
32 31
33 // Resolve the type annotations encountered in the method. 32 // Resolve the type annotations encountered in the method.
34 while (!toResolve.isEmpty()) { 33 while (!toResolve.isEmpty()) {
35 toResolve.removeFirst().resolve(compiler); 34 toResolve.removeFirst().resolve(compiler);
36 } 35 }
37 return visitor.mapping; 36 return visitor.mapping;
38 }); 37 });
39 } 38 }
40 39
40 void resolveInitializers(element, node, visitor) {
ngeoffray 2011/12/21 11:52:11 Types on parameters?
ahe 2011/12/21 12:01:58 I'd like a type on node.
karlklose 2011/12/21 16:33:46 Done.
karlklose 2011/12/21 16:33:46 Done.
41 Map<SourceString, Node> initialized = new Map<SourceString, Node>();
42 for (Link<Node> link = node.initializers.nodes;
43 !link.isEmpty();
44 link = link.tail) {
45 if (link.head.asSendSet() != null) {
46 SendSet init = link.head;
47 SourceString name = init.getInitializerFieldName(
48 () => visitor.error(init,
49 MessageKind.INVALID_RECEIVER_IN_INITIALIZER));
50 ClassElement classElement = element.enclosingElement;
51 Element target = classElement.lookupLocalElement(name);
52 Node selector = init.selector;
53 if (target == null) {
54 visitor.error(selector, MessageKind.CANNOT_RESOLVE, [name]);
55 } else if (target.kind != ElementKind.FIELD) {
56 visitor.error(selector, MessageKind.NOT_A_FIELD, [name]);
57 } else if (!target.isInstanceMember()) {
58 visitor.error(selector, MessageKind.INIT_STATIC_FIELD, [name]);
59 }
60 visitor.useElement(init, target);
61 if (initialized.containsKey(name)) {
62 visitor.warning(init, MessageKind.DUPLICATE_INITIALIZER,
ngeoffray 2011/12/21 11:52:11 The spec says it's a compile time error, so should
karlklose 2011/12/21 16:33:46 Done.
63 [name, initialized[name]]);
64 }
65 initialized[name] = init;
66 Node value = init.arguments.head;
67 visitor.visitInStaticContext(value);
68 } else {
69 // TODO(karlklose): super(...), this(...).
70 compiler.cancel('internal error: invalid initializer',
ngeoffray 2011/12/21 11:52:11 invalid -> unimplemented
ahe 2011/12/21 12:01:58 This is not an internal error, and the initializer
karlklose 2011/12/21 16:33:46 Done.
karlklose 2011/12/21 16:33:46 Done.
71 node: link.head);
72 }
73 }
74 }
75
41 void resolveType(ClassElement element) { 76 void resolveType(ClassElement element) {
42 measure(() { 77 measure(() {
43 ClassNode tree = element.node; 78 ClassNode tree = element.node;
44 ClassResolverVisitor visitor = new ClassResolverVisitor(compiler); 79 ClassResolverVisitor visitor = new ClassResolverVisitor(compiler);
45 visitor.visit(tree); 80 visitor.visit(tree);
46 }); 81 });
47 } 82 }
48 83
49 void resolveSignature(FunctionElement element) { 84 void resolveSignature(FunctionElement element) {
50 measure(() { 85 measure(() {
51 FunctionExpression node = element.node; 86 FunctionExpression node = element.node;
52 SignatureResolverVisitor visitor = 87 SignatureResolverVisitor visitor =
53 new SignatureResolverVisitor(compiler, element); 88 new SignatureResolverVisitor(compiler, element);
54 visitor.visitFunctionExpression(node); 89 visitor.visitFunctionExpression(node);
55 }); 90 });
56 } 91 }
57 } 92 }
58 93
59 class ResolverVisitor implements Visitor<Element> { 94 class ResolverVisitor implements Visitor<Element> {
60 final Compiler compiler; 95 final Compiler compiler;
61 final TreeElements mapping; 96 final TreeElements mapping;
62 final Element enclosingElement; 97 final Element enclosingElement;
63 Scope context; 98 Scope context;
99 bool isStaticContext;
ngeoffray 2011/12/21 11:52:11 isStaticContext always looks weird to me (is it a
karlklose 2011/12/21 16:33:46 Done.
64 100
65 ResolverVisitor(Compiler compiler, Element element) 101 ResolverVisitor(Compiler compiler, Element element)
66 : this.compiler = compiler, 102 : this.compiler = compiler,
67 this.mapping = new TreeElements(), 103 this.mapping = new TreeElements(),
68 this.enclosingElement = element, 104 this.enclosingElement = element,
69 this.context = element.isMember() 105 this.context = element.isMember()
70 ? new ClassScope(element.enclosingElement, compiler.universe) 106 ? new ClassScope(element.enclosingElement, compiler.universe)
71 : new TopScope(compiler.universe); 107 : new TopScope(compiler.universe),
108 this.isStaticContext = false;
72 109
73 ResolverVisitor.from(ResolverVisitor other) 110 ResolverVisitor.from(ResolverVisitor other)
74 : compiler = other.compiler, 111 : compiler = other.compiler,
75 mapping = other.mapping, 112 mapping = other.mapping,
76 enclosingElement = other.enclosingElement, 113 enclosingElement = other.enclosingElement,
77 context = other.context; 114 context = other.context;
78 115
79 error(Node node, MessageKind kind, [arguments = const []]) { 116 error(Node node, MessageKind kind, [arguments = const []]) {
80 ResolutionError error = new ResolutionError(kind, arguments); 117 ResolutionError error = new ResolutionError(kind, arguments);
81 compiler.reportError(node, error); 118 compiler.reportError(node, error);
82 } 119 }
83 120
84 warning(Node node, MessageKind kind, [arguments = const []]) { 121 warning(Node node, MessageKind kind, [arguments = const []]) {
85 ResolutionWarning warning = new ResolutionWarning(kind, arguments); 122 ResolutionWarning warning = new ResolutionWarning(kind, arguments);
86 compiler.reportWarning(node, warning); 123 compiler.reportWarning(node, warning);
87 } 124 }
88 125
89 cancel(Node node, String message) { 126 cancel(Node node, String message) {
90 compiler.cancel(message); 127 compiler.cancel(message);
91 } 128 }
92 129
130 Element lookup(Node node, SourceString name) {
131 Element result = context.lookup(name);
132 if (isStaticContext && result != null && result.isInstanceMember()) {
133 error(node, MessageKind.NOT_STATIC, [node]);
134 }
135 return result;
136 }
137
138 visitInStaticContext(Node node) {
139 bool wasStaticContext = isStaticContext;
140 isStaticContext = true;
141 visit(node);
142 isStaticContext = wasStaticContext;
143 }
144
93 visit(Node node) { 145 visit(Node node) {
94 if (node == null) return null; 146 if (node == null) return null;
95 return node.accept(this); 147 return node.accept(this);
96 } 148 }
97 149
98 visitIdentifier(Identifier node) { 150 visitIdentifier(Identifier node) {
99 Element element = context.lookup(node.source); 151 Element element = lookup(node, node.source);
100 if (element == null) { 152 if (element == null) {
101 error(node, MessageKind.CANNOT_RESOLVE, [node]); 153 error(node, MessageKind.CANNOT_RESOLVE, [node]);
102 } 154 }
103 return useElement(node, element); 155 return useElement(node, element);
104 } 156 }
105 157
106 visitTypeAnnotation(TypeAnnotation node) { 158 visitTypeAnnotation(TypeAnnotation node) {
107 Identifier name = node.typeName; 159 Identifier name = node.typeName;
108 if (name.source == const SourceString('var')) return null; 160 if (name.source == const SourceString('var')) return null;
109 if (name.source == const SourceString('void')) return null; 161 if (name.source == const SourceString('void')) return null;
(...skipping 29 matching lines...) Expand all
139 191
140 class SignatureResolverVisitor extends ResolverVisitor { 192 class SignatureResolverVisitor extends ResolverVisitor {
141 FunctionElement element; 193 FunctionElement element;
142 194
143 SignatureResolverVisitor(Compiler compiler, FunctionElement element) 195 SignatureResolverVisitor(Compiler compiler, FunctionElement element)
144 : super(compiler, element), this.element = element; 196 : super(compiler, element), this.element = element;
145 197
146 visitFunctionExpression(FunctionExpression node) { 198 visitFunctionExpression(FunctionExpression node) {
147 useElement(node, element); 199 useElement(node, element);
148 context = new MethodScope(context, element); 200 context = new MethodScope(context, element);
149
150 if (element.parameters == null) { 201 if (element.parameters == null) {
151 ParametersVisitor visitor = new ParametersVisitor(this); 202 ParametersVisitor visitor = new ParametersVisitor(this);
152 visitor.visit(node.parameters); 203 visitor.visit(node.parameters);
153 element.parameters = visitor.elements.toLink(); 204 element.parameters = visitor.elements.toLink();
154 } else { 205 } else {
155 Link<Node> parameterNodes = node.parameters.nodes; 206 Link<Node> parameterNodes = node.parameters.nodes;
156 for (Link<Element> link = element.parameters; 207 for (Link<Element> link = element.parameters;
157 !link.isEmpty() && !parameterNodes.isEmpty(); 208 !link.isEmpty() && !parameterNodes.isEmpty();
158 link = link.tail, parameterNodes = parameterNodes.tail) { 209 link = link.tail, parameterNodes = parameterNodes.tail) {
159 defineElement(parameterNodes.head.definitions.nodes.head, link.head); 210 defineElement(parameterNodes.head.definitions.nodes.head, link.head);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 Identifier selector = node.selector; 344 Identifier selector = node.selector;
294 SourceString name = selector.source; 345 SourceString name = selector.source;
295 // No need to assign an element for a logical operation. 346 // No need to assign an element for a logical operation.
296 if (isLogicalOperator(selector)) return null; 347 if (isLogicalOperator(selector)) return null;
297 348
298 Element target = null; 349 Element target = null;
299 if (node.isOperator) { 350 if (node.isOperator) {
300 SourceString opName = mapOperatorToMethodName(name, node.isPrefix); 351 SourceString opName = mapOperatorToMethodName(name, node.isPrefix);
301 target = compiler.universe.find(opName); 352 target = compiler.universe.find(opName);
302 } else if (node.receiver === null) { 353 } else if (node.receiver === null) {
303 target = context.lookup(name); 354 target = lookup(node, name);
ngeoffray 2011/12/21 11:52:11 I think this should be changed to target = visit(n
karlklose 2011/12/21 16:33:46 Done.
304 if (target == null && !enclosingElement.isInstanceMember()) { 355 if (target == null && !enclosingElement.isInstanceMember()) {
305 error(node, MessageKind.CANNOT_RESOLVE, [name]); 356 error(node, MessageKind.CANNOT_RESOLVE, [name]);
306 } 357 }
307 } else if (receiver === null) { 358 } else if (receiver === null) {
308 return null; 359 return null;
309 } else if (receiver.kind === ElementKind.CLASS) { 360 } else if (receiver.kind === ElementKind.CLASS) {
310 ClassElement receiverClass = receiver; 361 ClassElement receiverClass = receiver;
311 target = receiverClass.lookupLocalElement(name); 362 target = receiverClass.lookupLocalElement(name);
312 if (target == null) { 363 if (target == null) {
313 error(node, MessageKind.METHOD_NOT_FOUND, [receiver, name]); 364 error(node, MessageKind.METHOD_NOT_FOUND, [receiver, name]);
(...skipping 23 matching lines...) Expand all
337 SourceString name = mapAssignmentOperatorToMethodName(op.source); 388 SourceString name = mapAssignmentOperatorToMethodName(op.source);
338 Element operatorElement = compiler.universe.find(name); 389 Element operatorElement = compiler.universe.find(name);
339 useElement(op, operatorElement); 390 useElement(op, operatorElement);
340 // Resolve the getter for the lhs (receiver+selector). 391 // Resolve the getter for the lhs (receiver+selector).
341 // Currently this is the same as the setter. 392 // Currently this is the same as the setter.
342 // TODO(ngeoffray): Adapt for fields. 393 // TODO(ngeoffray): Adapt for fields.
343 Element getter; 394 Element getter;
344 if (node.isIndex) { 395 if (node.isIndex) {
345 getter = target; 396 getter = target;
346 } else { 397 } else {
347 getter = context.lookup(node.selector.asIdentifier().source); 398 getter = lookup(node, node.selector.asIdentifier().source);
ngeoffray 2011/12/21 11:52:11 ditto.
karlklose 2011/12/21 16:33:46 Done.
348 } 399 }
349 useElement(node.selector, getter); 400 useElement(node.selector, getter);
350 } 401 }
351 if (node.isIndex) { 402 if (node.isIndex) {
352 assert(target.name.stringValue === 'index'); 403 assert(target.name.stringValue === 'index');
353 target = compiler.universe.find(const SourceString('indexSet')); 404 target = compiler.universe.find(const SourceString('indexSet'));
354 } 405 }
355 return useElement(node, target); 406 return useElement(node, target);
356 } 407 }
357 408
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 610 }
560 611
561 class Scope { 612 class Scope {
562 final Element element; 613 final Element element;
563 final Scope parent; 614 final Scope parent;
564 615
565 Map<SourceString, Element> get elements() => const {}; 616 Map<SourceString, Element> get elements() => const {};
566 617
567 Scope(this.parent, this.element); 618 Scope(this.parent, this.element);
568 abstract Element add(Element element); 619 abstract Element add(Element element);
569 abstract Element lookup(Element element); 620 abstract Element lookup(SourceString name);
570 } 621 }
571 622
572 class MethodScope extends Scope { 623 class MethodScope extends Scope {
573 final Map<SourceString, Element> elements; 624 final Map<SourceString, Element> elements;
574 625
575 MethodScope(Scope parent, Element element) 626 MethodScope(Scope parent, Element element)
576 : super(parent, element), this.elements = {}; 627 : super(parent, element), this.elements = {};
577 628
578 Element lookup(SourceString name) { 629 Element lookup(SourceString name) {
579 Element element = elements[name]; 630 Element element = elements[name];
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 class TopScope extends Scope { 667 class TopScope extends Scope {
617 Universe universe; 668 Universe universe;
618 669
619 TopScope(Universe this.universe) : super(null, null); 670 TopScope(Universe this.universe) : super(null, null);
620 Element lookup(SourceString name) => universe.find(name); 671 Element lookup(SourceString name) => universe.find(name);
621 672
622 Element add(Element element) { 673 Element add(Element element) {
623 throw "Cannot add an element in the top scope"; 674 throw "Cannot add an element in the top scope";
624 } 675 }
625 } 676 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698