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 class LocalPlaceholder implements Hashable { | 5 class LocalPlaceholder implements Hashable { |
| 6 final String identifier; | 6 final String identifier; |
| 7 final Set<Node> nodes; | 7 final Set<Node> nodes; |
| 8 LocalPlaceholder(this.identifier) : nodes = new Set<Node>(); | 8 LocalPlaceholder(this.identifier) : nodes = new Set<Node>(); |
| 9 int hashCode() => identifier.hashCode(); | 9 int hashCode() => identifier.hashCode(); |
| 10 String toString() => | 10 String toString() => |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 final TypeAnnotation typeNode; | 26 final TypeAnnotation typeNode; |
| 27 final bool requiresVar; | 27 final bool requiresVar; |
| 28 DeclarationTypePlaceholder(this.typeNode, this.requiresVar); | 28 DeclarationTypePlaceholder(this.typeNode, this.requiresVar); |
| 29 } | 29 } |
| 30 | 30 |
| 31 class SendVisitor extends ResolvedVisitor { | 31 class SendVisitor extends ResolvedVisitor { |
| 32 final PlaceholderCollector collector; | 32 final PlaceholderCollector collector; |
| 33 | 33 |
| 34 SendVisitor(this.collector, TreeElements elements) : super(elements); | 34 SendVisitor(this.collector, TreeElements elements) : super(elements); |
| 35 | 35 |
| 36 visitDynamicSend(Send node) {} | |
| 37 visitSuperSend(Send node) {} | |
| 38 visitOperatorSend(Send node) {} | 36 visitOperatorSend(Send node) {} |
| 39 visitForeignSend(Send node) {} | 37 visitForeignSend(Send node) {} |
| 40 | 38 |
| 39 visitSuperSend(Send node) { | |
| 40 collector.tryMakeMemberPlaceholder(node.selector); | |
|
Roman
2012/08/29 08:40:08
Just to confirm, this is for calls like "super.foo
Anton Muhin
2012/08/29 09:43:46
Exactly
| |
| 41 } | |
| 42 | |
| 43 visitDynamicSend(Send node) { | |
| 44 final element = elements[node]; | |
| 45 if (element === null || !element.isErroneous()) { | |
| 46 collector.tryMakeMemberPlaceholder(node.selector); | |
| 47 } | |
| 48 } | |
| 49 | |
| 41 visitClosureSend(Send node) { | 50 visitClosureSend(Send node) { |
| 42 final element = elements[node]; | 51 final element = elements[node]; |
| 43 if (element !== null) { | 52 if (element !== null) { |
| 44 collector.tryMakeLocalPlaceholder(element, node.selector); | 53 collector.tryMakeLocalPlaceholder(element, node.selector); |
| 45 } | 54 } |
| 46 } | 55 } |
| 47 | 56 |
| 48 visitGetterSend(Send node) { | 57 visitGetterSend(Send node) { |
| 49 final element = elements[node]; | 58 final element = elements[node]; |
| 50 // element === null means dynamic property access. | 59 // element === null means dynamic property access. |
| 51 if (element === null) return; | 60 if (element === null) { |
| 52 if (element.isPrefix()) { | 61 collector.tryMakeMemberPlaceholder(node.selector); |
| 62 } else if (element.isPrefix()) { | |
| 53 // Node is prefix part in case of source 'lib.somesetter = 5;' | 63 // Node is prefix part in case of source 'lib.somesetter = 5;' |
| 54 collector.makeNullPlaceholder(node); | 64 collector.makeNullPlaceholder(node); |
| 55 } else if (Elements.isStaticOrTopLevel(element)) { | 65 } else if (Elements.isStaticOrTopLevel(element)) { |
| 56 // Unqualified or prefixed top level or static. | 66 // Unqualified or prefixed top level or static. |
| 57 collector.makeElementPlaceholder(node.selector, element); | 67 collector.makeElementPlaceholder(node.selector, element); |
| 58 } else if (!element.isTopLevel()) { | 68 } else if (!element.isTopLevel()) { |
| 59 // May get FunctionExpression here in selector | 69 if (element.isInstanceMember()) { |
| 60 // in case of A(int this.f()); | 70 collector.tryMakeMemberPlaceholder(node.selector); |
| 61 if (node.selector is Identifier) { | |
| 62 collector.tryMakeLocalPlaceholder(element, node.selector); | |
| 63 } else { | 71 } else { |
| 64 assert(node.selector is FunctionExpression); | 72 // May get FunctionExpression here in selector |
| 73 // in case of A(int this.f()); | |
| 74 if (node.selector is Identifier) { | |
| 75 collector.tryMakeLocalPlaceholder(element, node.selector); | |
| 76 } else { | |
| 77 assert(node.selector is FunctionExpression); | |
| 78 } | |
| 65 } | 79 } |
| 66 } | 80 } |
| 67 } | 81 } |
| 68 | 82 |
| 69 visitStaticSend(Send node) { | 83 visitStaticSend(Send node) { |
| 70 final element = elements[node]; | 84 final element = elements[node]; |
| 71 if (element.isConstructor() || element.isFactoryConstructor()) return; | 85 if (element.isConstructor() || element.isFactoryConstructor()) { |
| 86 if (node.receiver is Identifier && node.receiver.asIdentifier().isThis()) { | |
|
Roman
2012/08/29 08:40:08
I don't quite understand when this happens, can yo
Anton Muhin
2012/08/29 09:43:46
Done.
| |
| 87 assert(node.selector is Identifier); | |
| 88 collector.tryMakeMemberPlaceholder(node.selector); | |
| 89 } | |
| 90 FunctionElement functionElement = element; | |
|
Roman
2012/08/29 08:40:08
Please add a comment explaining what you are doing
Anton Muhin
2012/08/29 09:43:46
Done.
| |
| 91 Link<Element> optionalParameters = | |
| 92 functionElement.functionSignature.optionalParameters; | |
| 93 for (final argument in node.argumentsNode) { | |
| 94 NamedArgument named = argument.asNamedArgument(); | |
| 95 if (named === null) continue; | |
| 96 Identifier name = named.name; | |
| 97 String nameAsString = name.source.slowToString(); | |
| 98 for (final parameter in optionalParameters) { | |
| 99 if (parameter.kind === ElementKind.FIELD_PARAMETER) { | |
| 100 if (parameter.name.slowToString() == nameAsString) { | |
| 101 collector.tryMakeMemberPlaceholder(name); | |
| 102 break; | |
| 103 } | |
| 104 } | |
| 105 } | |
| 106 } | |
| 107 return; | |
| 108 } | |
| 72 collector.makeElementPlaceholder(node.selector, element); | 109 collector.makeElementPlaceholder(node.selector, element); |
| 73 // Another ugly case: <lib prefix>.<top level> is represented as | 110 // Another ugly case: <lib prefix>.<top level> is represented as |
| 74 // receiver: lib prefix, selector: top level. | 111 // receiver: lib prefix, selector: top level. |
| 75 if (element.isTopLevel() && node.receiver !== null) { | 112 if (element.isTopLevel() && node.receiver !== null) { |
| 76 assert(elements[node.receiver].isPrefix()); | 113 assert(elements[node.receiver].isPrefix()); |
| 77 // Hack: putting null into map overrides receiver of original node. | 114 // Hack: putting null into map overrides receiver of original node. |
| 78 collector.makeNullPlaceholder(node.receiver); | 115 collector.makeNullPlaceholder(node.receiver); |
| 79 } | 116 } |
| 80 } | 117 } |
| 81 | 118 |
| 82 internalError(String reason, [Node node]) { | 119 internalError(String reason, [Node node]) { |
| 83 collector.internalError(reason, node); | 120 collector.internalError(reason, node); |
| 84 } | 121 } |
| 85 } | 122 } |
| 86 | 123 |
| 87 class PlaceholderCollector extends AbstractVisitor { | 124 class PlaceholderCollector extends AbstractVisitor { |
| 88 final Compiler compiler; | 125 final Compiler compiler; |
| 126 final Set<String> fixedMemberNames; // member names which cannot be renamed. | |
| 89 final Set<Node> nullNodes; // Nodes that should not be in output. | 127 final Set<Node> nullNodes; // Nodes that should not be in output. |
| 90 final Set<Identifier> unresolvedNodes; | 128 final Set<Identifier> unresolvedNodes; |
| 91 final Map<Element, Set<Node>> elementNodes; | 129 final Map<Element, Set<Node>> elementNodes; |
| 92 final Map<FunctionElement, FunctionScope> functionScopes; | 130 final Map<FunctionElement, FunctionScope> functionScopes; |
| 93 final Map<LibraryElement, Set<Identifier>> privateNodes; | 131 final Map<LibraryElement, Set<Identifier>> privateNodes; |
| 94 final List<DeclarationTypePlaceholder> declarationTypePlaceholders; | 132 final List<DeclarationTypePlaceholder> declarationTypePlaceholders; |
| 133 final Map<String, Set<Identifier>> memberPlaceholders; | |
| 95 Map<String, LocalPlaceholder> currentLocalPlaceholders; | 134 Map<String, LocalPlaceholder> currentLocalPlaceholders; |
| 96 Element currentElement; | 135 Element currentElement; |
| 97 TreeElements treeElements; | 136 TreeElements treeElements; |
| 98 | 137 |
| 99 LibraryElement get coreLibrary => compiler.coreLibrary; | 138 LibraryElement get coreLibrary => compiler.coreLibrary; |
| 100 FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN); | 139 FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN); |
| 101 | 140 |
| 102 PlaceholderCollector(this.compiler) : | 141 PlaceholderCollector(this.compiler, this.fixedMemberNames) : |
| 103 nullNodes = new Set<Node>(), | 142 nullNodes = new Set<Node>(), |
| 104 unresolvedNodes = new Set<Identifier>(), | 143 unresolvedNodes = new Set<Identifier>(), |
| 105 elementNodes = new Map<Element, Set<Node>>(), | 144 elementNodes = new Map<Element, Set<Node>>(), |
| 106 functionScopes = new Map<FunctionElement, FunctionScope>(), | 145 functionScopes = new Map<FunctionElement, FunctionScope>(), |
| 107 privateNodes = new Map<LibraryElement, Set<Identifier>>(), | 146 privateNodes = new Map<LibraryElement, Set<Identifier>>(), |
| 108 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(); | 147 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), |
| 148 memberPlaceholders = new Map<String, Set<Identifier>>(); | |
| 109 | 149 |
| 110 void tryMakeConstructorNamePlaceholder( | 150 void tryMakeConstructorNamePlaceholder( |
| 111 FunctionExpression constructor, ClassElement element) { | 151 FunctionExpression constructor, ClassElement element) { |
| 112 Node nameNode = constructor.name; | 152 Node nameNode = constructor.name; |
| 113 if (nameNode is Send) nameNode = nameNode.receiver; | 153 if (nameNode is Send) nameNode = nameNode.receiver; |
| 114 if (nameNode.asIdentifier().token.slowToString() | 154 if (nameNode.asIdentifier().token.slowToString() |
| 115 == element.name.slowToString()) { | 155 == element.name.slowToString()) { |
| 116 makeElementPlaceholder(nameNode, element); | 156 makeElementPlaceholder(nameNode, element); |
| 117 } | 157 } |
| 118 } | 158 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 FunctionElement implementingFactory = element.defaultImplementation; | 190 FunctionElement implementingFactory = element.defaultImplementation; |
| 151 tryMakeConstructorNamePlaceholder(implementingFactory.cachedNode, | 191 tryMakeConstructorNamePlaceholder(implementingFactory.cachedNode, |
| 152 element.getEnclosingClass()); | 192 element.getEnclosingClass()); |
| 153 } | 193 } |
| 154 } else if (Elements.isStaticOrTopLevel(element)) { | 194 } else if (Elements.isStaticOrTopLevel(element)) { |
| 155 // Note: this code should only rename private identifiers for class' | 195 // Note: this code should only rename private identifiers for class' |
| 156 // fields/getters/setters/methods. Top-level identifiers are renamed | 196 // fields/getters/setters/methods. Top-level identifiers are renamed |
| 157 // just to escape conflicts and that should be enough as we shouldn't | 197 // just to escape conflicts and that should be enough as we shouldn't |
| 158 // be able to resolve private identifiers for other libraries. | 198 // be able to resolve private identifiers for other libraries. |
| 159 makeElementPlaceholder(node.name, element); | 199 makeElementPlaceholder(node.name, element); |
| 200 } else if (element.isMember()) { | |
| 201 if (node.name is Identifier) { | |
| 202 tryMakeMemberPlaceholder(node.name); | |
| 203 } else { | |
| 204 assert(node.name.asSend().isOperator); | |
| 205 } | |
| 160 } | 206 } |
| 161 } | 207 } |
| 162 | 208 |
| 163 void collectFieldDeclarationPlaceholders( | 209 void collectFieldDeclarationPlaceholders( |
| 164 Element element, VariableDefinitions node) { | 210 Element element, VariableDefinitions node) { |
| 211 Node fieldNode = element.parseNode(compiler); | |
| 212 Identifier name = | |
| 213 fieldNode is Identifier ? fieldNode : fieldNode.asSend().selector; | |
| 165 if (Elements.isStaticOrTopLevel(element)) { | 214 if (Elements.isStaticOrTopLevel(element)) { |
| 166 Node fieldNode = element.parseNode(compiler); | 215 makeElementPlaceholder(name, element); |
| 167 if (fieldNode is Identifier) { | 216 } else if (Elements.isInstanceField(element)) { |
| 168 makeElementPlaceholder(fieldNode, element); | 217 tryMakeMemberPlaceholder(name); |
| 169 } else if (fieldNode is SendSet) { | |
| 170 makeElementPlaceholder(fieldNode.selector, element); | |
| 171 } else { | |
| 172 unreachable(); | |
| 173 } | |
| 174 } | 218 } |
| 175 makeVarDeclarationTypePlaceholder(node); | 219 makeVarDeclarationTypePlaceholder(node); |
| 176 } | 220 } |
| 177 | 221 |
| 178 void collect(Element element, TreeElements elements) { | 222 void collect(Element element, TreeElements elements) { |
| 179 treeElements = elements; | 223 treeElements = elements; |
| 180 Node elementNode; | 224 Node elementNode; |
| 181 if (element is FunctionElement) { | 225 if (element is FunctionElement) { |
| 182 currentElement = element; | 226 currentElement = element; |
| 183 elementNode = currentElement.parseNode(compiler); | 227 elementNode = currentElement.parseNode(compiler); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 // should not matter if they are local vars. | 259 // should not matter if they are local vars. |
| 216 if (node.source.isPrivate()) return; | 260 if (node.source.isPrivate()) return; |
| 217 if (element.isParameter() && isOptionalParameter()) { | 261 if (element.isParameter() && isOptionalParameter()) { |
| 218 functionScopes.putIfAbsent(currentElement, () => new FunctionScope()) | 262 functionScopes.putIfAbsent(currentElement, () => new FunctionScope()) |
| 219 .registerParameter(node); | 263 .registerParameter(node); |
| 220 } else if (Elements.isLocal(element)) { | 264 } else if (Elements.isLocal(element)) { |
| 221 makeLocalPlaceholder(node); | 265 makeLocalPlaceholder(node); |
| 222 } | 266 } |
| 223 } | 267 } |
| 224 | 268 |
| 269 void tryMakeMemberPlaceholder(Identifier node) { | |
| 270 assert(node !== null); | |
| 271 if (node.source.isPrivate()) return; | |
| 272 if (node is Operator) return; | |
| 273 final identifier = node.source.slowToString(); | |
| 274 if (fixedMemberNames.contains(identifier)) return; | |
| 275 memberPlaceholders.putIfAbsent( | |
| 276 identifier, () => new Set<Identifier>()).add(node); | |
| 277 } | |
| 278 | |
| 225 void makeTypePlaceholder(Node node, Type type) { | 279 void makeTypePlaceholder(Node node, Type type) { |
| 226 makeElementPlaceholder(node, type.element); | 280 makeElementPlaceholder(node, type.element); |
| 227 } | 281 } |
| 228 | 282 |
| 229 void makeOmitDeclarationTypePlaceholder(TypeAnnotation type) { | 283 void makeOmitDeclarationTypePlaceholder(TypeAnnotation type) { |
| 230 if (type === null) return; | 284 if (type === null) return; |
| 231 declarationTypePlaceholders.add( | 285 declarationTypePlaceholders.add( |
| 232 new DeclarationTypePlaceholder(type, false)); | 286 new DeclarationTypePlaceholder(type, false)); |
| 233 } | 287 } |
| 234 | 288 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 } | 360 } |
| 307 | 361 |
| 308 visitSendSet(SendSet send) { | 362 visitSendSet(SendSet send) { |
| 309 final element = treeElements[send]; | 363 final element = treeElements[send]; |
| 310 if (element !== null) { | 364 if (element !== null) { |
| 311 if (Elements.isStaticOrTopLevel(element)) { | 365 if (Elements.isStaticOrTopLevel(element)) { |
| 312 assert(element is VariableElement || element.isSetter()); | 366 assert(element is VariableElement || element.isSetter()); |
| 313 makeElementPlaceholder(send.selector, element); | 367 makeElementPlaceholder(send.selector, element); |
| 314 } else { | 368 } else { |
| 315 assert(send.selector is Identifier); | 369 assert(send.selector is Identifier); |
| 316 tryMakeLocalPlaceholder(element, send.selector); | 370 if (Elements.isInstanceField(element)) { |
| 371 tryMakeMemberPlaceholder(send.selector); | |
| 372 } else { | |
| 373 tryMakeLocalPlaceholder(element, send.selector); | |
| 374 } | |
| 375 } | |
| 376 } else { | |
| 377 if (send.receiver !== null) { | |
| 378 tryMakeMemberPlaceholder(send.selector); | |
| 317 } | 379 } |
| 318 } | 380 } |
| 319 send.visitChildren(this); | 381 send.visitChildren(this); |
| 320 } | 382 } |
| 321 | 383 |
| 322 visitIdentifier(Identifier identifier) { | 384 visitIdentifier(Identifier identifier) { |
| 323 if (identifier.source.isPrivate()) makePrivateIdentifier(identifier); | 385 if (identifier.source.isPrivate()) makePrivateIdentifier(identifier); |
| 324 } | 386 } |
| 325 | 387 |
| 326 static bool isPlainTypeName(TypeAnnotation typeAnnotation) { | 388 static bool isPlainTypeName(TypeAnnotation typeAnnotation) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 Element definitionElement = treeElements[definition]; | 448 Element definitionElement = treeElements[definition]; |
| 387 // definitionElement may be null if we're inside variable definitions | 449 // definitionElement may be null if we're inside variable definitions |
| 388 // of a function that is a parameter of another function. | 450 // of a function that is a parameter of another function. |
| 389 // TODO(smok): Fix this when resolver correctly deals with | 451 // TODO(smok): Fix this when resolver correctly deals with |
| 390 // such cases. | 452 // such cases. |
| 391 if (definitionElement === null) continue; | 453 if (definitionElement === null) continue; |
| 392 if (definition is Send) { | 454 if (definition is Send) { |
| 393 // May get FunctionExpression here in definition.selector | 455 // May get FunctionExpression here in definition.selector |
| 394 // in case of A(int this.f()); | 456 // in case of A(int this.f()); |
| 395 if (definition.selector is Identifier) { | 457 if (definition.selector is Identifier) { |
| 396 tryMakeLocalPlaceholder(definitionElement, definition.selector); | 458 if (definitionElement.kind === ElementKind.FIELD_PARAMETER) { |
| 459 tryMakeMemberPlaceholder(definition.selector); | |
| 460 } else { | |
| 461 tryMakeLocalPlaceholder(definitionElement, definition.selector); | |
| 462 } | |
| 397 } else { | 463 } else { |
| 398 assert(definition.selector is FunctionExpression); | 464 assert(definition.selector is FunctionExpression); |
| 465 if (definitionElement.kind === ElementKind.FIELD_PARAMETER) { | |
| 466 tryMakeMemberPlaceholder( | |
| 467 definition.selector.asFunctionExpression().name); | |
| 468 } | |
| 399 } | 469 } |
| 400 } else if (definition is Identifier) { | 470 } else if (definition is Identifier) { |
| 401 tryMakeLocalPlaceholder(definitionElement, definition); | 471 tryMakeLocalPlaceholder(definitionElement, definition); |
| 402 } else if (definition is FunctionExpression) { | 472 } else if (definition is FunctionExpression) { |
| 403 // Skip, it will be processed in visitFunctionExpression. | 473 // Skip, it will be processed in visitFunctionExpression. |
| 404 } else { | 474 } else { |
| 405 internalError('Unexpected definition structure $definition'); | 475 internalError('Unexpected definition structure $definition'); |
| 406 } | 476 } |
| 407 } | 477 } |
| 408 } | 478 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 | 562 |
| 493 visitBlock(Block node) { | 563 visitBlock(Block node) { |
| 494 for (Node statement in node.statements.nodes) { | 564 for (Node statement in node.statements.nodes) { |
| 495 if (statement is VariableDefinitions) { | 565 if (statement is VariableDefinitions) { |
| 496 makeVarDeclarationTypePlaceholder(statement); | 566 makeVarDeclarationTypePlaceholder(statement); |
| 497 } | 567 } |
| 498 } | 568 } |
| 499 node.visitChildren(this); | 569 node.visitChildren(this); |
| 500 } | 570 } |
| 501 } | 571 } |
| OLD | NEW |