| 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>(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 : this.collector = collector, | 48 : this.collector = collector, |
| 49 super(elements, collector.compiler); | 49 super(elements, collector.compiler); |
| 50 | 50 |
| 51 visitOperatorSend(Send node) { | 51 visitOperatorSend(Send node) { |
| 52 } | 52 } |
| 53 | 53 |
| 54 visitForeignSend(Send node) {} | 54 visitForeignSend(Send node) {} |
| 55 | 55 |
| 56 visitSuperSend(Send node) { | 56 visitSuperSend(Send node) { |
| 57 Element element = elements[node]; | 57 Element element = elements[node]; |
| 58 if (element != null && element.isConstructor()) { | 58 if (element != null && element.isConstructor) { |
| 59 collector.makeRedirectingConstructorPlaceholder(node.selector, element); | 59 collector.makeRedirectingConstructorPlaceholder(node.selector, element); |
| 60 } else { | 60 } else { |
| 61 collector.tryMakeMemberPlaceholder(node.selector); | 61 collector.tryMakeMemberPlaceholder(node.selector); |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 | 64 |
| 65 visitDynamicSend(Send node) { | 65 visitDynamicSend(Send node) { |
| 66 final element = elements[node]; | 66 final element = elements[node]; |
| 67 if (element == null || !element.isErroneous()) { | 67 if (element == null || !element.isErroneous) { |
| 68 collector.tryMakeMemberPlaceholder(node.selector); | 68 collector.tryMakeMemberPlaceholder(node.selector); |
| 69 } | 69 } |
| 70 } | 70 } |
| 71 | 71 |
| 72 visitClosureSend(Send node) { | 72 visitClosureSend(Send node) { |
| 73 final element = elements[node]; | 73 final element = elements[node]; |
| 74 if (element != null) { | 74 if (element != null) { |
| 75 collector.tryMakeLocalPlaceholder(element, node.selector); | 75 collector.tryMakeLocalPlaceholder(element, node.selector); |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 | 78 |
| 79 visitGetterSend(Send node) { | 79 visitGetterSend(Send node) { |
| 80 final element = elements[node]; | 80 final element = elements[node]; |
| 81 // element == null means dynamic property access. | 81 // element == null means dynamic property access. |
| 82 if (element == null) { | 82 if (element == null) { |
| 83 collector.tryMakeMemberPlaceholder(node.selector); | 83 collector.tryMakeMemberPlaceholder(node.selector); |
| 84 } else if (element.isErroneous()) { | 84 } else if (element.isErroneous) { |
| 85 return; | 85 return; |
| 86 } else if (element.isPrefix()) { | 86 } else if (element.isPrefix) { |
| 87 // Node is prefix part in case of source 'lib.somesetter = 5;' | 87 // Node is prefix part in case of source 'lib.somesetter = 5;' |
| 88 collector.makeNullPlaceholder(node); | 88 collector.makeNullPlaceholder(node); |
| 89 } else if (Elements.isStaticOrTopLevel(element)) { | 89 } else if (Elements.isStaticOrTopLevel(element)) { |
| 90 // Unqualified or prefixed top level or static. | 90 // Unqualified or prefixed top level or static. |
| 91 collector.makeElementPlaceholder(node.selector, element); | 91 collector.makeElementPlaceholder(node.selector, element); |
| 92 } else if (!element.isTopLevel()) { | 92 } else if (!element.isTopLevel) { |
| 93 if (element.isInstanceMember()) { | 93 if (element.isInstanceMember) { |
| 94 collector.tryMakeMemberPlaceholder(node.selector); | 94 collector.tryMakeMemberPlaceholder(node.selector); |
| 95 } else { | 95 } else { |
| 96 // May get FunctionExpression here in selector | 96 // May get FunctionExpression here in selector |
| 97 // in case of A(int this.f()); | 97 // in case of A(int this.f()); |
| 98 if (node.selector is Identifier) { | 98 if (node.selector is Identifier) { |
| 99 collector.tryMakeLocalPlaceholder(element, node.selector); | 99 collector.tryMakeLocalPlaceholder(element, node.selector); |
| 100 } else { | 100 } else { |
| 101 assert(node.selector is FunctionExpression); | 101 assert(node.selector is FunctionExpression); |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 } | 105 } |
| 106 | 106 |
| 107 visitAssert(node) { | 107 visitAssert(node) { |
| 108 visitStaticSend(node); | 108 visitStaticSend(node); |
| 109 } | 109 } |
| 110 | 110 |
| 111 visitStaticSend(Send node) { | 111 visitStaticSend(Send node) { |
| 112 final element = elements[node]; | 112 final element = elements[node]; |
| 113 collector.backend.registerStaticSend(element, node); | 113 collector.backend.registerStaticSend(element, node); |
| 114 | 114 |
| 115 if (Elements.isUnresolved(element) | 115 if (Elements.isUnresolved(element) |
| 116 || identical(element, compiler.assertMethod) | 116 || identical(element, compiler.assertMethod) |
| 117 || element.isDeferredLoaderGetter()) { | 117 || element.isDeferredLoaderGetter) { |
| 118 return; | 118 return; |
| 119 } | 119 } |
| 120 if (element.isConstructor() || element.isFactoryConstructor()) { | 120 if (element.isConstructor || element.isFactoryConstructor) { |
| 121 // Rename named constructor in redirection position: | 121 // Rename named constructor in redirection position: |
| 122 // class C { C.named(); C.redirecting() : this.named(); } | 122 // class C { C.named(); C.redirecting() : this.named(); } |
| 123 if (node.receiver is Identifier | 123 if (node.receiver is Identifier |
| 124 && node.receiver.asIdentifier().isThis()) { | 124 && node.receiver.asIdentifier().isThis()) { |
| 125 assert(node.selector is Identifier); | 125 assert(node.selector is Identifier); |
| 126 collector.makeRedirectingConstructorPlaceholder(node.selector, element); | 126 collector.makeRedirectingConstructorPlaceholder(node.selector, element); |
| 127 } | 127 } |
| 128 return; | 128 return; |
| 129 } | 129 } |
| 130 collector.makeElementPlaceholder(node.selector, element); | 130 collector.makeElementPlaceholder(node.selector, element); |
| 131 // Another ugly case: <lib prefix>.<top level> is represented as | 131 // Another ugly case: <lib prefix>.<top level> is represented as |
| 132 // receiver: lib prefix, selector: top level. | 132 // receiver: lib prefix, selector: top level. |
| 133 if (element.isTopLevel() && node.receiver != null) { | 133 if (element.isTopLevel && node.receiver != null) { |
| 134 assert(elements[node.receiver].isPrefix()); | 134 assert(elements[node.receiver].isPrefix); |
| 135 // Hack: putting null into map overrides receiver of original node. | 135 // Hack: putting null into map overrides receiver of original node. |
| 136 collector.makeNullPlaceholder(node.receiver); | 136 collector.makeNullPlaceholder(node.receiver); |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 | 139 |
| 140 internalError(String reason, {Node node}) { | 140 internalError(String reason, {Node node}) { |
| 141 collector.internalError(reason, node: node); | 141 collector.internalError(reason, node: node); |
| 142 } | 142 } |
| 143 | 143 |
| 144 visitTypeReferenceSend(Send node) { | 144 visitTypeReferenceSend(Send node) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 elementNodes = new Map<Element, Set<Node>>(), | 176 elementNodes = new Map<Element, Set<Node>>(), |
| 177 functionScopes = new Map<FunctionElement, FunctionScope>(), | 177 functionScopes = new Map<FunctionElement, FunctionScope>(), |
| 178 privateNodes = new Map<LibraryElement, Set<Identifier>>(), | 178 privateNodes = new Map<LibraryElement, Set<Identifier>>(), |
| 179 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), | 179 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), |
| 180 memberPlaceholders = new Map<String, Set<Identifier>>(), | 180 memberPlaceholders = new Map<String, Set<Identifier>>(), |
| 181 constructorPlaceholders = | 181 constructorPlaceholders = |
| 182 new Map<Element, List<ConstructorPlaceholder>>(); | 182 new Map<Element, List<ConstructorPlaceholder>>(); |
| 183 | 183 |
| 184 void collectFunctionDeclarationPlaceholders( | 184 void collectFunctionDeclarationPlaceholders( |
| 185 FunctionElement element, FunctionExpression node) { | 185 FunctionElement element, FunctionExpression node) { |
| 186 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { | 186 if (element.isGenerativeConstructor || element.isFactoryConstructor) { |
| 187 DartType type = element.getEnclosingClass().thisType.asRaw(); | 187 DartType type = element.enclosingClass.thisType.asRaw(); |
| 188 makeConstructorPlaceholder(node.name, element, type); | 188 makeConstructorPlaceholder(node.name, element, type); |
| 189 Return bodyAsReturn = node.body.asReturn(); | 189 Return bodyAsReturn = node.body.asReturn(); |
| 190 if (bodyAsReturn != null && bodyAsReturn.isRedirectingFactoryBody) { | 190 if (bodyAsReturn != null && bodyAsReturn.isRedirectingFactoryBody) { |
| 191 // Factory redirection. | 191 // Factory redirection. |
| 192 FunctionElement redirectTarget = element.defaultImplementation; | 192 FunctionElement redirectTarget = element.defaultImplementation; |
| 193 assert(redirectTarget != null && redirectTarget != element); | 193 assert(redirectTarget != null && redirectTarget != element); |
| 194 type = redirectTarget.getEnclosingClass().thisType.asRaw(); | 194 type = redirectTarget.enclosingClass.thisType.asRaw(); |
| 195 makeConstructorPlaceholder( | 195 makeConstructorPlaceholder( |
| 196 bodyAsReturn.expression, redirectTarget, type); | 196 bodyAsReturn.expression, redirectTarget, type); |
| 197 } | 197 } |
| 198 } else if (Elements.isStaticOrTopLevel(element)) { | 198 } else if (Elements.isStaticOrTopLevel(element)) { |
| 199 // Note: this code should only rename private identifiers for class' | 199 // Note: this code should only rename private identifiers for class' |
| 200 // fields/getters/setters/methods. Top-level identifiers are renamed | 200 // fields/getters/setters/methods. Top-level identifiers are renamed |
| 201 // just to escape conflicts and that should be enough as we shouldn't | 201 // just to escape conflicts and that should be enough as we shouldn't |
| 202 // be able to resolve private identifiers for other libraries. | 202 // be able to resolve private identifiers for other libraries. |
| 203 makeElementPlaceholder(node.name, element); | 203 makeElementPlaceholder(node.name, element); |
| 204 } else if (element.isMember()) { | 204 } else if (element.isMember) { |
| 205 if (node.name is Identifier) { | 205 if (node.name is Identifier) { |
| 206 tryMakeMemberPlaceholder(node.name); | 206 tryMakeMemberPlaceholder(node.name); |
| 207 } else { | 207 } else { |
| 208 assert(node.name.asSend().isOperator); | 208 assert(node.name.asSend().isOperator); |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 | 212 |
| 213 void collectFieldDeclarationPlaceholders(Element element, Node node) { | 213 void collectFieldDeclarationPlaceholders(Element element, Node node) { |
| 214 Identifier name = node is Identifier ? node : node.asSend().selector; | 214 Identifier name = node is Identifier ? node : node.asSend().selector; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 242 currentLocalPlaceholders = new Map<String, LocalPlaceholder>(); | 242 currentLocalPlaceholders = new Map<String, LocalPlaceholder>(); |
| 243 compiler.withCurrentElement(element, () { | 243 compiler.withCurrentElement(element, () { |
| 244 elementNode.accept(this); | 244 elementNode.accept(this); |
| 245 }); | 245 }); |
| 246 } | 246 } |
| 247 | 247 |
| 248 // TODO(karlklose): should we create placeholders for these? | 248 // TODO(karlklose): should we create placeholders for these? |
| 249 bool isTypedefParameter(Element element) { | 249 bool isTypedefParameter(Element element) { |
| 250 return element != null && | 250 return element != null && |
| 251 element.enclosingElement != null && | 251 element.enclosingElement != null && |
| 252 element.enclosingElement.isTypedef(); | 252 element.enclosingElement.isTypedef; |
| 253 } | 253 } |
| 254 | 254 |
| 255 void tryMakeLocalPlaceholder(Element element, Identifier node) { | 255 void tryMakeLocalPlaceholder(Element element, Identifier node) { |
| 256 bool isNamedOptionalParameter() { | 256 bool isNamedOptionalParameter() { |
| 257 FunctionElement function = element.enclosingElement; | 257 FunctionElement function = element.enclosingElement; |
| 258 FunctionSignature signature = function.functionSignature; | 258 FunctionSignature signature = function.functionSignature; |
| 259 if (!signature.optionalParametersAreNamed) return false; | 259 if (!signature.optionalParametersAreNamed) return false; |
| 260 for (Element parameter in signature.optionalParameters) { | 260 for (Element parameter in signature.optionalParameters) { |
| 261 if (identical(parameter, element)) return true; | 261 if (identical(parameter, element)) return true; |
| 262 } | 262 } |
| 263 return false; | 263 return false; |
| 264 } | 264 } |
| 265 | 265 |
| 266 // TODO(smok): Maybe we should rename privates as well, their privacy | 266 // TODO(smok): Maybe we should rename privates as well, their privacy |
| 267 // should not matter if they are local vars. | 267 // should not matter if they are local vars. |
| 268 if (isPrivateName(node.source)) return; | 268 if (isPrivateName(node.source)) return; |
| 269 if (element.isParameter() && !isTypedefParameter(element) && | 269 if (element.isParameter && !isTypedefParameter(element) && |
| 270 isNamedOptionalParameter()) { | 270 isNamedOptionalParameter()) { |
| 271 currentFunctionScope.registerParameter(node); | 271 currentFunctionScope.registerParameter(node); |
| 272 } else if (Elements.isLocal(element) && !isTypedefParameter(element)) { | 272 } else if (Elements.isLocal(element) && !isTypedefParameter(element)) { |
| 273 makeLocalPlaceholder(node); | 273 makeLocalPlaceholder(node); |
| 274 } | 274 } |
| 275 } | 275 } |
| 276 | 276 |
| 277 void tryMakeMemberPlaceholder(Identifier node) { | 277 void tryMakeMemberPlaceholder(Identifier node) { |
| 278 assert(node != null); | 278 assert(node != null); |
| 279 if (isPrivateName(node.source)) return; | 279 if (isPrivateName(node.source)) return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 302 new DeclarationTypePlaceholder(type, false)); | 302 new DeclarationTypePlaceholder(type, false)); |
| 303 } | 303 } |
| 304 | 304 |
| 305 void makeVarDeclarationTypePlaceholder(VariableDefinitions node) { | 305 void makeVarDeclarationTypePlaceholder(VariableDefinitions node) { |
| 306 // TODO(smok): Maybe instead of calling this method and | 306 // TODO(smok): Maybe instead of calling this method and |
| 307 // makeDeclaratioTypePlaceholder have type declaration placeholder | 307 // makeDeclaratioTypePlaceholder have type declaration placeholder |
| 308 // collector logic in visitVariableDefinitions when resolver becomes better | 308 // collector logic in visitVariableDefinitions when resolver becomes better |
| 309 // and/or catch syntax changes. | 309 // and/or catch syntax changes. |
| 310 if (node.type == null) return; | 310 if (node.type == null) return; |
| 311 Element definitionElement = treeElements[node.definitions.nodes.head]; | 311 Element definitionElement = treeElements[node.definitions.nodes.head]; |
| 312 bool requiresVar = !node.modifiers.isFinalOrConst(); | 312 bool requiresVar = !node.modifiers.isFinalOrConst; |
| 313 declarationTypePlaceholders.add( | 313 declarationTypePlaceholders.add( |
| 314 new DeclarationTypePlaceholder(node.type, requiresVar)); | 314 new DeclarationTypePlaceholder(node.type, requiresVar)); |
| 315 } | 315 } |
| 316 | 316 |
| 317 void makeNullPlaceholder(Node node) { | 317 void makeNullPlaceholder(Node node) { |
| 318 assert(node is Identifier || node is Send); | 318 assert(node is Identifier || node is Send); |
| 319 nullNodes.add(node); | 319 nullNodes.add(node); |
| 320 } | 320 } |
| 321 | 321 |
| 322 void makeElementPlaceholder(Node node, Element element) { | 322 void makeElementPlaceholder(Node node, Element element) { |
| 323 assert(node != null); | 323 assert(node != null); |
| 324 assert(element != null); | 324 assert(element != null); |
| 325 if (identical(element, entryFunction)) return; | 325 if (identical(element, entryFunction)) return; |
| 326 if (identical(element.getLibrary(), coreLibrary)) return; | 326 if (identical(element.library, coreLibrary)) return; |
| 327 if (element.getLibrary().isPlatformLibrary && !element.isTopLevel()) { | 327 if (element.library.isPlatformLibrary && !element.isTopLevel) { |
| 328 return; | 328 return; |
| 329 } | 329 } |
| 330 if (element == compiler.dynamicClass) { | 330 if (element == compiler.dynamicClass) { |
| 331 return; | 331 return; |
| 332 } | 332 } |
| 333 elementNodes.putIfAbsent(element, () => new Set<Node>()).add(node); | 333 elementNodes.putIfAbsent(element, () => new Set<Node>()).add(node); |
| 334 } | 334 } |
| 335 | 335 |
| 336 void makePrivateIdentifier(Identifier node) { | 336 void makePrivateIdentifier(Identifier node) { |
| 337 assert(node != null); | 337 assert(node != null); |
| 338 privateNodes.putIfAbsent( | 338 privateNodes.putIfAbsent( |
| 339 currentElement.getLibrary(), () => new Set<Identifier>()).add(node); | 339 currentElement.library, () => new Set<Identifier>()).add(node); |
| 340 } | 340 } |
| 341 | 341 |
| 342 void makeUnresolvedPlaceholder(Node node) { | 342 void makeUnresolvedPlaceholder(Node node) { |
| 343 unresolvedNodes.add(node); | 343 unresolvedNodes.add(node); |
| 344 } | 344 } |
| 345 | 345 |
| 346 void makeLocalPlaceholder(Identifier identifier) { | 346 void makeLocalPlaceholder(Identifier identifier) { |
| 347 LocalPlaceholder getLocalPlaceholder() { | 347 LocalPlaceholder getLocalPlaceholder() { |
| 348 String name = identifier.source; | 348 String name = identifier.source; |
| 349 return currentLocalPlaceholders.putIfAbsent(name, () { | 349 return currentLocalPlaceholders.putIfAbsent(name, () { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 Element element = treeElements[send]; | 424 Element element = treeElements[send]; |
| 425 if (Elements.isErroneousElement(element)) { | 425 if (Elements.isErroneousElement(element)) { |
| 426 // Complicated case: constructs like receiver.selector++ can resolve | 426 // Complicated case: constructs like receiver.selector++ can resolve |
| 427 // to ErroneousElement. Fortunately, receiver.selector still | 427 // to ErroneousElement. Fortunately, receiver.selector still |
| 428 // can be resoved via treeElements[send.selector], that's all | 428 // can be resoved via treeElements[send.selector], that's all |
| 429 // that is needed to rename the construct properly. | 429 // that is needed to rename the construct properly. |
| 430 element = treeElements[send.selector]; | 430 element = treeElements[send.selector]; |
| 431 } | 431 } |
| 432 if (element == null) { | 432 if (element == null) { |
| 433 if (send.receiver != null) tryMakeMemberPlaceholder(send.selector); | 433 if (send.receiver != null) tryMakeMemberPlaceholder(send.selector); |
| 434 } else if (!element.isErroneous()) { | 434 } else if (!element.isErroneous) { |
| 435 if (Elements.isStaticOrTopLevel(element)) { | 435 if (Elements.isStaticOrTopLevel(element)) { |
| 436 // TODO(smok): Worth investigating why sometimes we get getter/setter | 436 // TODO(smok): Worth investigating why sometimes we get getter/setter |
| 437 // here and sometimes abstract field. | 437 // here and sometimes abstract field. |
| 438 assert(element.isClass() || element is VariableElement || | 438 assert(element.isClass || element is VariableElement || |
| 439 element.isAccessor() || element.isAbstractField() || | 439 element.isAccessor || element.isAbstractField || |
| 440 element.isFunction() || element.isTypedef() || | 440 element.isFunction || element.isTypedef || |
| 441 element is TypeVariableElement); | 441 element is TypeVariableElement); |
| 442 makeElementPlaceholder(send.selector, element); | 442 makeElementPlaceholder(send.selector, element); |
| 443 } else { | 443 } else { |
| 444 Identifier identifier = send.selector.asIdentifier(); | 444 Identifier identifier = send.selector.asIdentifier(); |
| 445 if (identifier == null) { | 445 if (identifier == null) { |
| 446 // Handle optional function expression parameters with default values. | 446 // Handle optional function expression parameters with default values. |
| 447 identifier = send.selector.asFunctionExpression().name; | 447 identifier = send.selector.asFunctionExpression().name; |
| 448 } | 448 } |
| 449 if (Elements.isInstanceField(element)) { | 449 if (Elements.isInstanceField(element)) { |
| 450 tryMakeMemberPlaceholder(identifier); | 450 tryMakeMemberPlaceholder(identifier); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 | 595 |
| 596 visitBlock(Block node) { | 596 visitBlock(Block node) { |
| 597 for (Node statement in node.statements.nodes) { | 597 for (Node statement in node.statements.nodes) { |
| 598 if (statement is VariableDefinitions) { | 598 if (statement is VariableDefinitions) { |
| 599 makeVarDeclarationTypePlaceholder(statement); | 599 makeVarDeclarationTypePlaceholder(statement); |
| 600 } | 600 } |
| 601 } | 601 } |
| 602 node.visitChildren(this); | 602 node.visitChildren(this); |
| 603 } | 603 } |
| 604 } | 604 } |
| OLD | NEW |