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>(); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 memberPlaceholders = new Map<String, Set<Identifier>>(), | 188 memberPlaceholders = new Map<String, Set<Identifier>>(), |
| 189 constructorPlaceholders = | 189 constructorPlaceholders = |
| 190 new Map<Element, List<ConstructorPlaceholder>>(); | 190 new Map<Element, List<ConstructorPlaceholder>>(); |
| 191 | 191 |
| 192 void collectFunctionDeclarationPlaceholders( | 192 void collectFunctionDeclarationPlaceholders( |
| 193 FunctionElement element, FunctionExpression node) { | 193 FunctionElement element, FunctionExpression node) { |
| 194 if (element.isConstructor) { | 194 if (element.isConstructor) { |
| 195 ConstructorElement constructor = element; | 195 ConstructorElement constructor = element; |
| 196 DartType type = element.enclosingClass.thisType.asRaw(); | 196 DartType type = element.enclosingClass.thisType.asRaw(); |
| 197 makeConstructorPlaceholder(node.name, element, type); | 197 makeConstructorPlaceholder(node.name, element, type); |
| 198 Return bodyAsReturn = node.body.asReturn(); | 198 RedirectingFactoryBody bodyAsRedirectingFactoryBody = |
| 199 if (bodyAsReturn != null && bodyAsReturn.isRedirectingFactoryBody) { | 199 node.body.asRedirectingFactoryBody(); |
| 200 if (bodyAsRedirectingFactoryBody != null) { | |
| 200 // Factory redirection. | 201 // Factory redirection. |
| 201 FunctionElement redirectTarget = constructor.immediateRedirectionTarget; | 202 FunctionElement redirectTarget = constructor.immediateRedirectionTarget; |
| 202 assert(redirectTarget != null && redirectTarget != element); | 203 assert(redirectTarget != null && redirectTarget != element); |
| 203 type = redirectTarget.enclosingClass.thisType.asRaw(); | 204 type = redirectTarget.enclosingClass.thisType.asRaw(); |
| 204 makeConstructorPlaceholder( | 205 makeConstructorPlaceholder( |
| 205 bodyAsReturn.expression, redirectTarget, type); | 206 bodyAsRedirectingFactoryBody.constructorReference, |
| 207 redirectTarget, type); | |
| 206 } | 208 } |
| 207 } else if (Elements.isStaticOrTopLevel(element)) { | 209 } else if (Elements.isStaticOrTopLevel(element)) { |
| 208 // Note: this code should only rename private identifiers for class' | 210 // Note: this code should only rename private identifiers for class' |
| 209 // fields/getters/setters/methods. Top-level identifiers are renamed | 211 // fields/getters/setters/methods. Top-level identifiers are renamed |
| 210 // just to escape conflicts and that should be enough as we shouldn't | 212 // just to escape conflicts and that should be enough as we shouldn't |
| 211 // be able to resolve private identifiers for other libraries. | 213 // be able to resolve private identifiers for other libraries. |
| 212 makeElementPlaceholder(node.name, element); | 214 makeElementPlaceholder(node.name, element); |
| 213 } else if (element.isClassMember) { | 215 } else if (element.isClassMember) { |
| 214 if (node.name is Identifier) { | 216 if (node.name is Identifier) { |
| 215 tryMakeMemberPlaceholder(node.name); | 217 tryMakeMemberPlaceholder(node.name); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 232 this.currentElement = element; | 234 this.currentElement = element; |
| 233 this.topmostEnclosingFunction = null; | 235 this.topmostEnclosingFunction = null; |
| 234 final ElementAst elementAst = elementAsts[element]; | 236 final ElementAst elementAst = elementAsts[element]; |
| 235 this.treeElements = elementAst.treeElements; | 237 this.treeElements = elementAst.treeElements; |
| 236 Node elementNode = elementAst.ast; | 238 Node elementNode = elementAst.ast; |
| 237 if (element is FunctionElement) { | 239 if (element is FunctionElement) { |
| 238 collectFunctionDeclarationPlaceholders(element, elementNode); | 240 collectFunctionDeclarationPlaceholders(element, elementNode); |
| 239 } else if (element is VariableElement) { | 241 } else if (element is VariableElement) { |
| 240 VariableDefinitions definitions = elementNode; | 242 VariableDefinitions definitions = elementNode; |
| 241 Node definition = definitions.definitions.nodes.head; | 243 Node definition = definitions.definitions.nodes.head; |
| 242 final definitionElement = treeElements[elementNode]; | 244 collectFieldDeclarationPlaceholders(element, definition); |
| 243 // definitionElement == null if variable is actually unused. | |
|
Johnni Winther
2014/07/25 10:22:20
Not true.
| |
| 244 if (definitionElement != null) { | |
| 245 collectFieldDeclarationPlaceholders(definitionElement, definition); | |
| 246 } | |
| 247 makeVarDeclarationTypePlaceholder(definitions); | 245 makeVarDeclarationTypePlaceholder(definitions); |
| 248 } else { | 246 } else { |
| 249 assert(element is ClassElement || element is TypedefElement); | 247 assert(element is ClassElement || element is TypedefElement); |
| 250 } | 248 } |
| 251 currentLocalPlaceholders = new Map<String, LocalPlaceholder>(); | 249 currentLocalPlaceholders = new Map<String, LocalPlaceholder>(); |
| 252 compiler.withCurrentElement(element, () { | 250 compiler.withCurrentElement(element, () { |
| 253 elementNode.accept(this); | 251 elementNode.accept(this); |
| 254 }); | 252 }); |
| 253 if (element == backend.mirrorHelperSymbolsMap) { | |
| 254 backend.registerMirrorHelperElement(element, elementNode); | |
| 255 } | |
| 255 } | 256 } |
| 256 | 257 |
| 257 // TODO(karlklose): should we create placeholders for these? | 258 // TODO(karlklose): should we create placeholders for these? |
| 258 bool isTypedefParameter(Element element) { | 259 bool isTypedefParameter(Element element) { |
| 259 return element != null && | 260 return element != null && |
| 260 element.enclosingElement != null && | 261 element.enclosingElement != null && |
| 261 element.enclosingElement.isTypedef; | 262 element.enclosingElement.isTypedef; |
| 262 } | 263 } |
| 263 | 264 |
| 264 void tryMakeLocalPlaceholder(Element element, Identifier node) { | 265 void tryMakeLocalPlaceholder(Element element, Identifier node) { |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 477 makeUnresolvedPlaceholder(node.typeName); | 478 makeUnresolvedPlaceholder(node.typeName); |
| 478 } | 479 } |
| 479 } | 480 } |
| 480 // Visit only type arguments, otherwise in case of lib.Class type | 481 // Visit only type arguments, otherwise in case of lib.Class type |
| 481 // annotation typeName is Send and we go to visitGetterSend, as a result | 482 // annotation typeName is Send and we go to visitGetterSend, as a result |
| 482 // "Class" is added to member placeholders. | 483 // "Class" is added to member placeholders. |
| 483 visit(node.typeArguments); | 484 visit(node.typeArguments); |
| 484 } | 485 } |
| 485 | 486 |
| 486 visitVariableDefinitions(VariableDefinitions node) { | 487 visitVariableDefinitions(VariableDefinitions node) { |
| 487 Element definitionElement = treeElements[node]; | |
| 488 if (definitionElement == backend.mirrorHelperSymbolsMap) { | |
| 489 backend.registerMirrorHelperElement(definitionElement, node); | |
| 490 } | |
| 491 // Collect only local placeholders. | 488 // Collect only local placeholders. |
| 492 for (Node definition in node.definitions.nodes) { | 489 for (Node definition in node.definitions.nodes) { |
| 493 Element definitionElement = treeElements[definition]; | 490 Element definitionElement = treeElements[definition]; |
| 494 // definitionElement may be null if we're inside variable definitions | 491 // definitionElement may be null if we're inside variable definitions |
| 495 // of a function that is a parameter of another function. | 492 // of a function that is a parameter of another function. |
| 496 // TODO(smok): Fix this when resolver correctly deals with | 493 // TODO(smok): Fix this when resolver correctly deals with |
| 497 // such cases. | 494 // such cases. |
| 498 if (definitionElement == null) continue; | 495 if (definitionElement == null) continue; |
| 499 Send send = definition.asSend(); | 496 Send send = definition.asSend(); |
| 500 if (send != null) { | 497 if (send != null) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 | 598 |
| 602 visitBlock(Block node) { | 599 visitBlock(Block node) { |
| 603 for (Node statement in node.statements.nodes) { | 600 for (Node statement in node.statements.nodes) { |
| 604 if (statement is VariableDefinitions) { | 601 if (statement is VariableDefinitions) { |
| 605 makeVarDeclarationTypePlaceholder(statement); | 602 makeVarDeclarationTypePlaceholder(statement); |
| 606 } | 603 } |
| 607 } | 604 } |
| 608 node.visitChildren(this); | 605 node.visitChildren(this); |
| 609 } | 606 } |
| 610 } | 607 } |
| OLD | NEW |