Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 part of dart_backend; | 5 part of dart_backend; |
| 6 | 6 |
| 7 class LocalPlaceholder { | 7 class LocalPlaceholder { |
| 8 final String identifier; | 8 final String identifier; |
| 9 final Set<Node> nodes; | 9 final Set<Node> nodes; |
| 10 LocalPlaceholder(this.identifier) : nodes = new Set<Node>(); | 10 LocalPlaceholder(this.identifier) : nodes = new Set<Node>(); |
| 11 int get hashCode => identifier.hashCode; | 11 int get hashCode => identifier.hashCode; |
| 12 String toString() => | 12 String toString() => |
| 13 'local_placeholder[id($identifier), nodes($nodes)]'; | 13 'local_placeholder[id($identifier), nodes($nodes)]'; |
| 14 } | 14 } |
| 15 | 15 |
| 16 class FunctionScope { | 16 class FunctionScope { |
| 17 final Set<String> parameterIdentifiers; | 17 final Set<String> parameterIdentifiers; |
| 18 final Set<LocalPlaceholder> localPlaceholders; | 18 final Set<LocalPlaceholder> localPlaceholders; |
| 19 FunctionScope() | 19 FunctionScope() |
| 20 : parameterIdentifiers = new Set<String>(), | 20 : parameterIdentifiers = new Set<String>(), |
| 21 localPlaceholders = new Set<LocalPlaceholder>(); | 21 localPlaceholders = new Set<LocalPlaceholder>(); |
| 22 void registerParameter(Identifier node) { | 22 void registerParameter(Identifier node) { |
| 23 parameterIdentifiers.add(node.source.slowToString()); | 23 parameterIdentifiers.add(node.source.slowToString()); |
| 24 } | 24 } |
| 25 } | 25 } |
| 26 | 26 |
| 27 class ConstructorPlaceholder { | 27 class ConstructorPlaceholder { |
| 28 final Node node; | 28 final Node node; |
| 29 final DartType type; | 29 final DartType type; |
| 30 ConstructorPlaceholder(this.node, this.type); | 30 final bool isRedirectingCall; |
| 31 ConstructorPlaceholder(this.node, this.type, this.isRedirectingCall) { | |
|
Anton Muhin
2012/10/30 15:23:44
it looks like as of now in all the call sites you
Roman
2012/10/30 15:52:09
Done.
| |
| 32 assert(isRedirectingCall != (type != null)); | |
| 33 } | |
| 31 } | 34 } |
| 32 | 35 |
| 33 class DeclarationTypePlaceholder { | 36 class DeclarationTypePlaceholder { |
| 34 final TypeAnnotation typeNode; | 37 final TypeAnnotation typeNode; |
| 35 final bool requiresVar; | 38 final bool requiresVar; |
| 36 DeclarationTypePlaceholder(this.typeNode, this.requiresVar); | 39 DeclarationTypePlaceholder(this.typeNode, this.requiresVar); |
| 37 } | 40 } |
| 38 | 41 |
| 39 class SendVisitor extends ResolvedVisitor { | 42 class SendVisitor extends ResolvedVisitor { |
| 40 final PlaceholderCollector collector; | 43 final PlaceholderCollector collector; |
| 41 | 44 |
| 42 get compiler => collector.compiler; | 45 get compiler => collector.compiler; |
| 43 | 46 |
| 44 SendVisitor(this.collector, TreeElements elements) : super(elements); | 47 SendVisitor(this.collector, TreeElements elements) : super(elements); |
| 45 | 48 |
| 46 visitOperatorSend(Send node) {} | 49 visitOperatorSend(Send node) {} |
| 47 visitForeignSend(Send node) {} | 50 visitForeignSend(Send node) {} |
| 48 | 51 |
| 49 visitSuperSend(Send node) { | 52 visitSuperSend(Send node) { |
| 50 collector.tryMakeMemberPlaceholder(node.selector); | 53 Element element = elements[node]; |
| 54 if (element != null && element.isConstructor()) { | |
| 55 collector.makeConstructorPlaceholder(node.selector, element, null, true); | |
|
Anton Muhin
2012/10/30 15:23:44
my original understanding of constructor placehold
Roman
2012/10/30 15:52:09
1) We cannot add declarations to one placeholder t
| |
| 56 } else { | |
| 57 collector.tryMakeMemberPlaceholder(node.selector); | |
| 58 } | |
| 51 } | 59 } |
| 52 | 60 |
| 53 visitDynamicSend(Send node) { | 61 visitDynamicSend(Send node) { |
| 54 final element = elements[node]; | 62 final element = elements[node]; |
| 55 if (element == null || !element.isErroneous()) { | 63 if (element == null || !element.isErroneous()) { |
| 56 collector.tryMakeMemberPlaceholder(node.selector); | 64 collector.tryMakeMemberPlaceholder(node.selector); |
| 57 } | 65 } |
| 58 } | 66 } |
| 59 | 67 |
| 60 visitClosureSend(Send node) { | 68 visitClosureSend(Send node) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 91 } | 99 } |
| 92 } | 100 } |
| 93 } | 101 } |
| 94 | 102 |
| 95 visitStaticSend(Send node) { | 103 visitStaticSend(Send node) { |
| 96 final element = elements[node]; | 104 final element = elements[node]; |
| 97 if (Elements.isUnresolved(element) | 105 if (Elements.isUnresolved(element) |
| 98 || identical(element, compiler.assertMethod)) { | 106 || identical(element, compiler.assertMethod)) { |
| 99 return; | 107 return; |
| 100 } | 108 } |
| 101 // TODO(smok): We should never go inside this IF, check? | |
| 102 if (element.isConstructor() || element.isFactoryConstructor()) { | 109 if (element.isConstructor() || element.isFactoryConstructor()) { |
| 103 // Rename named constructor in redirection position: | 110 // Rename named constructor in redirection position: |
| 104 // class C { C.named(); C.redirecting() : this.named(); } | 111 // class C { C.named(); C.redirecting() : this.named(); } |
| 105 // TODO(smok): Fix redirecting constructors. | |
| 106 if (node.receiver is Identifier | 112 if (node.receiver is Identifier |
| 107 && node.receiver.asIdentifier().isThis()) { | 113 && node.receiver.asIdentifier().isThis()) { |
| 108 assert(node.selector is Identifier); | 114 assert(node.selector is Identifier); |
| 109 collector.tryMakeMemberPlaceholder(node.selector); | 115 collector.makeConstructorPlaceholder( |
| 116 node.selector, element, null, true); | |
| 110 } | 117 } |
| 111 return; | 118 return; |
| 112 } | 119 } |
| 113 collector.makeElementPlaceholder(node.selector, element); | 120 collector.makeElementPlaceholder(node.selector, element); |
| 114 // Another ugly case: <lib prefix>.<top level> is represented as | 121 // Another ugly case: <lib prefix>.<top level> is represented as |
| 115 // receiver: lib prefix, selector: top level. | 122 // receiver: lib prefix, selector: top level. |
| 116 if (element.isTopLevel() && node.receiver != null) { | 123 if (element.isTopLevel() && node.receiver != null) { |
| 117 assert(elements[node.receiver].isPrefix()); | 124 assert(elements[node.receiver].isPrefix()); |
| 118 // Hack: putting null into map overrides receiver of original node. | 125 // Hack: putting null into map overrides receiver of original node. |
| 119 collector.makeNullPlaceholder(node.receiver); | 126 collector.makeNullPlaceholder(node.receiver); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 nullNodes = new Set<Node>(), | 159 nullNodes = new Set<Node>(), |
| 153 unresolvedNodes = new Set<Identifier>(), | 160 unresolvedNodes = new Set<Identifier>(), |
| 154 elementNodes = new Map<Element, Set<Node>>(), | 161 elementNodes = new Map<Element, Set<Node>>(), |
| 155 functionScopes = new Map<FunctionElement, FunctionScope>(), | 162 functionScopes = new Map<FunctionElement, FunctionScope>(), |
| 156 privateNodes = new Map<LibraryElement, Set<Identifier>>(), | 163 privateNodes = new Map<LibraryElement, Set<Identifier>>(), |
| 157 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), | 164 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), |
| 158 memberPlaceholders = new Map<String, Set<Identifier>>(), | 165 memberPlaceholders = new Map<String, Set<Identifier>>(), |
| 159 constructorPlaceholders = | 166 constructorPlaceholders = |
| 160 new Map<Element, List<ConstructorPlaceholder>>(); | 167 new Map<Element, List<ConstructorPlaceholder>>(); |
| 161 | 168 |
| 162 void tryMakeConstructorPlaceholder( | |
| 163 FunctionExpression constructor, FunctionElement constructorElement) { | |
| 164 DartType type = constructorElement.getEnclosingClass().type.asRaw(); | |
| 165 makeConstructorPlaceholder(constructor.name, constructorElement, type); | |
| 166 } | |
| 167 | |
| 168 void collectFunctionDeclarationPlaceholders( | 169 void collectFunctionDeclarationPlaceholders( |
| 169 FunctionElement element, FunctionExpression node) { | 170 FunctionElement element, FunctionExpression node) { |
| 170 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { | 171 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { |
| 171 // Two complicated cases for class/interface renaming: | 172 // Two complicated cases for class/interface renaming: |
|
Anton Muhin
2012/10/30 15:23:44
cannot this comment go away now?
Roman
2012/10/30 15:52:09
Done.
| |
| 172 // 1) class which implements constructors of other interfaces, but not | 173 // 1) class which implements constructors of other interfaces, but not |
| 173 // implements interfaces themselves: | 174 // implements interfaces themselves: |
| 174 // 0.dart: class C { I(); } | 175 // 0.dart: class C { I(); } |
| 175 // 1.dart and 2.dart: interface I default C { I(); } | 176 // 1.dart and 2.dart: interface I default C { I(); } |
| 176 // now we have to duplicate our I() constructor in C class with | 177 // now we have to duplicate our I() constructor in C class with |
| 177 // proper names. | 178 // proper names. |
| 178 // 2) (even worse for us): | 179 // 2) (even worse for us): |
| 179 // 0.dart: class C { C(); } | 180 // 0.dart: class C { C(); } |
| 180 // 1.dart: interface C default p0.C { C(); } | 181 // 1.dart: interface C default p0.C { C(); } |
| 181 // the second case is just a bug now. | 182 // the second case is just a bug now. |
| 182 tryMakeConstructorPlaceholder(node, element); | 183 DartType type = element.getEnclosingClass().type.asRaw(); |
| 184 makeConstructorPlaceholder(node.name, element, type, false); | |
| 183 } else if (Elements.isStaticOrTopLevel(element)) { | 185 } else if (Elements.isStaticOrTopLevel(element)) { |
| 184 // Note: this code should only rename private identifiers for class' | 186 // Note: this code should only rename private identifiers for class' |
| 185 // fields/getters/setters/methods. Top-level identifiers are renamed | 187 // fields/getters/setters/methods. Top-level identifiers are renamed |
| 186 // just to escape conflicts and that should be enough as we shouldn't | 188 // just to escape conflicts and that should be enough as we shouldn't |
| 187 // be able to resolve private identifiers for other libraries. | 189 // be able to resolve private identifiers for other libraries. |
| 188 makeElementPlaceholder(node.name, element); | 190 makeElementPlaceholder(node.name, element); |
| 189 } else if (element.isMember()) { | 191 } else if (element.isMember()) { |
| 190 if (node.name is Identifier) { | 192 if (node.name is Identifier) { |
| 191 tryMakeMemberPlaceholder(node.name); | 193 tryMakeMemberPlaceholder(node.name); |
| 192 } else { | 194 } else { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 return currentLocalPlaceholders.putIfAbsent(name, () { | 326 return currentLocalPlaceholders.putIfAbsent(name, () { |
| 325 LocalPlaceholder localPlaceholder = new LocalPlaceholder(name); | 327 LocalPlaceholder localPlaceholder = new LocalPlaceholder(name); |
| 326 currentFunctionScope.localPlaceholders.add(localPlaceholder); | 328 currentFunctionScope.localPlaceholders.add(localPlaceholder); |
| 327 return localPlaceholder; | 329 return localPlaceholder; |
| 328 }); | 330 }); |
| 329 } | 331 } |
| 330 | 332 |
| 331 getLocalPlaceholder().nodes.add(identifier); | 333 getLocalPlaceholder().nodes.add(identifier); |
| 332 } | 334 } |
| 333 | 335 |
| 334 void makeConstructorPlaceholder(Node node, Element element, DartType type) { | 336 void makeConstructorPlaceholder(Node node, Element element, DartType type, |
| 337 bool isRedirecting) { | |
| 335 constructorPlaceholders | 338 constructorPlaceholders |
| 336 .putIfAbsent(element, () => <ConstructorPlaceholder>[]) | 339 .putIfAbsent(element, () => <ConstructorPlaceholder>[]) |
| 337 .add(new ConstructorPlaceholder(node, type)); | 340 .add(new ConstructorPlaceholder(node, type, isRedirecting)); |
| 338 } | 341 } |
| 339 | 342 |
| 340 void internalError(String reason, {Node node}) { | 343 void internalError(String reason, {Node node}) { |
| 341 compiler.cancel(reason, node: node); | 344 compiler.cancel(reason, node: node); |
| 342 } | 345 } |
| 343 | 346 |
| 344 void unreachable() { internalError('Unreachable case'); } | 347 void unreachable() { internalError('Unreachable case'); } |
| 345 | 348 |
| 346 visit(Node node) => (node == null) ? null : node.accept(this); | 349 visit(Node node) => (node == null) ? null : node.accept(this); |
| 347 | 350 |
| 348 visitNode(Node node) { node.visitChildren(this); } // We must go deeper. | 351 visitNode(Node node) { node.visitChildren(this); } // We must go deeper. |
| 349 | 352 |
| 350 visitNewExpression(NewExpression node) { | 353 visitNewExpression(NewExpression node) { |
| 351 Send send = node.send; | 354 Send send = node.send; |
| 352 InterfaceType type = treeElements.getType(node); | 355 InterfaceType type = treeElements.getType(node); |
| 353 assert(type != null); | 356 assert(type != null); |
| 354 Element constructor = treeElements[send]; | 357 Element constructor = treeElements[send]; |
| 355 assert(constructor != null); | 358 assert(constructor != null); |
| 356 assert(send.receiver == null); | 359 assert(send.receiver == null); |
| 357 if (constructor is !ErroneousElement) { | 360 if (constructor is !ErroneousElement) { |
| 358 makeConstructorPlaceholder(node.send.selector, constructor, type); | 361 makeConstructorPlaceholder(node.send.selector, constructor, type, false); |
| 359 // TODO(smok): Should this be in visitNamedArgument? | 362 // TODO(smok): Should this be in visitNamedArgument? |
| 360 // Field names can be exposed as names of optional arguments, e.g. | 363 // Field names can be exposed as names of optional arguments, e.g. |
| 361 // class C { | 364 // class C { |
| 362 // final field; | 365 // final field; |
| 363 // C([this.field]); | 366 // C([this.field]); |
| 364 // } | 367 // } |
| 365 // Do not forget to rename them as well. | 368 // Do not forget to rename them as well. |
| 366 Link<Element> optionalParameters = | 369 Link<Element> optionalParameters = |
| 367 constructor.functionSignature.optionalParameters; | 370 constructor.functionSignature.optionalParameters; |
| 368 for (final argument in send.argumentsNode) { | 371 for (final argument in send.argumentsNode) { |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 | 606 |
| 604 visitBlock(Block node) { | 607 visitBlock(Block node) { |
| 605 for (Node statement in node.statements.nodes) { | 608 for (Node statement in node.statements.nodes) { |
| 606 if (statement is VariableDefinitions) { | 609 if (statement is VariableDefinitions) { |
| 607 makeVarDeclarationTypePlaceholder(statement); | 610 makeVarDeclarationTypePlaceholder(statement); |
| 608 } | 611 } |
| 609 } | 612 } |
| 610 node.visitChildren(this); | 613 node.visitChildren(this); |
| 611 } | 614 } |
| 612 } | 615 } |
| OLD | NEW |