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

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

Issue 9327001: Implement super initializers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 10 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
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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 interface TreeElements { 5 interface TreeElements {
6 Element operator[](Node node); 6 Element operator[](Node node);
7 Selector getSelector(Send send); 7 Selector getSelector(Send send);
8 } 8 }
9 9
10 class TreeElementMapping implements TreeElements { 10 class TreeElementMapping implements TreeElements {
11 Map<Node, Element> map; 11 Map<Node, Element> map;
12 Map<Send, Selector> selectors; 12 Map<Send, Selector> selectors;
13 TreeElementMapping() 13 TreeElementMapping()
14 : map = new LinkedHashMap<Node, Element>(), 14 : map = new LinkedHashMap<Node, Element>(),
15 selectors = new LinkedHashMap<Send, Selector>(); 15 selectors = new LinkedHashMap<Send, Selector>();
16 16
17 operator []=(Node node, Element element) => map[node] = element; 17 operator []=(Node node, Element element) => map[node] = element;
18 operator [](Node node) => map[node]; 18 operator [](Node node) => map[node];
19 19
20 void setSelector(Send send, Selector selector) { 20 void setSelector(Send send, Selector selector) {
21 selectors[send] = selector; 21 selectors[send] = selector;
22 } 22 }
23 23
24 Selector getSelector(Send send) => selectors[send]; 24 Selector getSelector(Send send) => selectors[send];
25 } 25 }
26 26
27 class ResolverTask extends CompilerTask { 27 class ResolverTask extends CompilerTask {
28 Queue<ClassElement> toResolve; 28 Queue<ClassElement> toResolve;
29 29
30 // Caches the elements of analyzed constructors to make them available
31 // for inlining in later tasks.
32 Map<FunctionElement, TreeElements> constructorElements;
33
30 ResolverTask(Compiler compiler) 34 ResolverTask(Compiler compiler)
31 : super(compiler), toResolve = new Queue<ClassElement>(); 35 : super(compiler), toResolve = new Queue<ClassElement>(),
36 constructorElements = new Map<FunctionElement, TreeElements>();
32 37
33 String get name() => 'Resolver'; 38 String get name() => 'Resolver';
34 39
35 TreeElements resolve(Element element) { 40 TreeElements resolve(Element element) {
36 return measure(() { 41 return measure(() {
37 switch (element.kind) { 42 switch (element.kind) {
38 case ElementKind.GENERATIVE_CONSTRUCTOR: 43 case ElementKind.GENERATIVE_CONSTRUCTOR:
39 case ElementKind.FUNCTION: 44 case ElementKind.FUNCTION:
40 case ElementKind.GETTER: 45 case ElementKind.GETTER:
41 case ElementKind.SETTER: 46 case ElementKind.SETTER:
42 return resolveMethodElement(element); 47 return resolveMethodElement(element);
43 48
44 case ElementKind.FIELD: 49 case ElementKind.FIELD:
45 case ElementKind.PARAMETER: 50 case ElementKind.PARAMETER:
46 return resolveVariableElement(element); 51 return resolveVariableElement(element);
47 52
48 default: 53 default:
49 compiler.unimplemented( 54 compiler.unimplemented(
50 "resolver", node: element.parseNode(compiler)); 55 "resolver", node: element.parseNode(compiler));
51 } 56 }
52 }); 57 });
53 } 58 }
54 59
55 TreeElements resolveMethodElement(FunctionElement element) { 60 TreeElements resolveMethodElement(FunctionElement element) {
61 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR &&
62 constructorElements[element] !== null) {
63 return constructorElements[element];
64 }
56 FunctionExpression tree = element.parseNode(compiler); 65 FunctionExpression tree = element.parseNode(compiler);
57 ResolverVisitor visitor = new ResolverVisitor(compiler, element); 66 ResolverVisitor visitor = new ResolverVisitor(compiler, element);
58 visitor.useElement(tree, element); 67 visitor.useElement(tree, element);
59 visitor.setupFunction(tree, element); 68 visitor.setupFunction(tree, element);
60 69
61 if (tree.initializers != null) { 70 if (tree.initializers != null) {
62 new InitializerResolver(visitor, element).resolveInitializers(tree); 71 new InitializerResolver(visitor, element).resolveInitializers(tree);
63 } 72 }
64 visitor.visit(tree.body); 73 visitor.visit(tree.body);
65 74
66 // Resolve the type annotations encountered in the method. 75 // Resolve the type annotations encountered in the method.
67 Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>(); 76 Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>();
68 while (!toResolve.isEmpty()) { 77 while (!toResolve.isEmpty()) {
69 ClassElement classElement = toResolve.removeFirst(); 78 ClassElement classElement = toResolve.removeFirst();
70 if (!classElement.isResolved) { 79 if (!classElement.isResolved) {
71 classElement.resolve(compiler); 80 classElement.resolve(compiler);
72 } 81 }
73 newResolvedClasses = newResolvedClasses.prepend(classElement); 82 newResolvedClasses = newResolvedClasses.prepend(classElement);
74 } 83 }
75 checkClassHierarchy(newResolvedClasses); 84 checkClassHierarchy(newResolvedClasses);
85 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) {
86 constructorElements[element] = visitor.mapping;
87 }
76 return visitor.mapping; 88 return visitor.mapping;
77 } 89 }
78 90
79 TreeElements resolveVariableElement(Element element) { 91 TreeElements resolveVariableElement(Element element) {
80 Node tree = element.parseNode(compiler); 92 Node tree = element.parseNode(compiler);
81 ResolverVisitor visitor = new ResolverVisitor(compiler, element); 93 ResolverVisitor visitor = new ResolverVisitor(compiler, element);
82 if (tree is SendSet) { 94 if (tree is SendSet) {
83 SendSet send = tree; 95 SendSet send = tree;
84 visitor.visit(send.arguments.head); 96 visitor.visit(send.arguments.head);
85 } 97 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 166 }
155 } 167 }
156 168
157 class InitializerResolver { 169 class InitializerResolver {
158 final ResolverVisitor visitor; 170 final ResolverVisitor visitor;
159 final FunctionElement constructor; 171 final FunctionElement constructor;
160 final Map<SourceString, Node> initialized; 172 final Map<SourceString, Node> initialized;
161 Link<Node> initializers; 173 Link<Node> initializers;
162 bool hasSuper; 174 bool hasSuper;
163 175
164 bool isSuperConstructorCall(Send node) {
165 return (node.receiver === null &&
166 node.selector.asIdentifier() !== null &&
167 node.selector.asIdentifier().isSuper()) ||
168 (node.receiver !== null &&
169 node.receiver.asIdentifier() !== null &&
170 node.receiver.asIdentifier().isSuper() &&
171 node.selector.asIdentifier() !== null);
172 }
173
174 bool isConstructorRedirect(Send node) {
175 return (node.receiver === null &&
176 node.selector.asIdentifier() !== null &&
177 node.selector.asIdentifier().isThis()) ||
178 (node.receiver !== null &&
179 node.receiver.asIdentifier() !== null &&
180 node.receiver.asIdentifier().isThis() &&
181 node.selector.asIdentifier() !== null);
182 }
183
184 InitializerResolver(this.visitor, this.constructor) 176 InitializerResolver(this.visitor, this.constructor)
185 : initialized = new Map<SourceString, Node>(), hasSuper = false; 177 : initialized = new Map<SourceString, Node>(), hasSuper = false;
186 178
187 error(Node node, MessageKind kind, [arguments = const []]) { 179 error(Node node, MessageKind kind, [arguments = const []]) {
188 visitor.error(node, kind, arguments); 180 visitor.error(node, kind, arguments);
189 } 181 }
190 182
191 warning(Node node, MessageKind kind, [arguments = const []]) { 183 warning(Node node, MessageKind kind, [arguments = const []]) {
192 visitor.warning(node, kind, arguments); 184 visitor.warning(node, kind, arguments);
193 } 185 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 } 229 }
238 } 230 }
239 231
240 void resolveSuperOrThis(Send call) { 232 void resolveSuperOrThis(Send call) {
241 noConstructor(e) { 233 noConstructor(e) {
242 if (e !== null) error(call, MessageKind.NO_CONSTRUCTOR, [e.name, e.kind]); 234 if (e !== null) error(call, MessageKind.NO_CONSTRUCTOR, [e.name, e.kind]);
243 } 235 }
244 236
245 ClassElement lookupTarget = constructor.enclosingElement; 237 ClassElement lookupTarget = constructor.enclosingElement;
246 bool validTarget = true; 238 bool validTarget = true;
247 if (isSuperConstructorCall(call)) { 239 if (Initializers.isSuperConstructorCall(call)) {
248 // Check for invalid initializers. 240 // Check for invalid initializers.
249 if (hasSuper) { 241 if (hasSuper) {
250 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER); 242 error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
251 } 243 }
252 hasSuper = true; 244 hasSuper = true;
253 // Calculate correct lookup target and constructor name. 245 // Calculate correct lookup target and constructor name.
254 if (lookupTarget.name == Types.OBJECT) { 246 if (lookupTarget.name == Types.OBJECT) {
255 error(call, MessageKind.SUPER_INITIALIZER_IN_OBJECT); 247 error(call, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
256 } else { 248 } else {
257 lookupTarget = lookupTarget.supertype.element; 249 lookupTarget = lookupTarget.supertype.element;
258 } 250 }
259 } else if (isConstructorRedirect(call)) { 251 } else if (Initializers.isConstructorRedirect(call)) {
260 // Check that there are no other initializers. 252 // Check that there are no other initializers.
261 if (!initializers.tail.isEmpty()) { 253 if (!initializers.tail.isEmpty()) {
262 error(call, MessageKind.REDIRECTING_CTOR_HAS_INITIALIZER); 254 error(call, MessageKind.REDIRECTING_CTOR_HAS_INITIALIZER);
263 } 255 }
264 } else { 256 } else {
265 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED); 257 visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
266 validTarget = false; 258 validTarget = false;
267 } 259 }
268 260
269 if (validTarget) { 261 if (validTarget) {
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 class TopScope extends Scope { 1156 class TopScope extends Scope {
1165 LibraryElement get library() => element; 1157 LibraryElement get library() => element;
1166 1158
1167 TopScope(LibraryElement library) : super(null, library); 1159 TopScope(LibraryElement library) : super(null, library);
1168 Element lookup(SourceString name) => library.find(name); 1160 Element lookup(SourceString name) => library.find(name);
1169 1161
1170 Element add(Element element) { 1162 Element add(Element element) {
1171 throw "Cannot add an element in the top scope"; 1163 throw "Cannot add an element in the top scope";
1172 } 1164 }
1173 } 1165 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698