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 { | |
| 28 final Node node; | |
| 29 final DartType type; | |
| 30 ConstructorPlaceholder(this.node, this.type); | |
| 31 } | |
| 32 | |
| 27 class DeclarationTypePlaceholder { | 33 class DeclarationTypePlaceholder { |
| 28 final TypeAnnotation typeNode; | 34 final TypeAnnotation typeNode; |
| 29 final bool requiresVar; | 35 final bool requiresVar; |
| 30 DeclarationTypePlaceholder(this.typeNode, this.requiresVar); | 36 DeclarationTypePlaceholder(this.typeNode, this.requiresVar); |
| 31 } | 37 } |
| 32 | 38 |
| 33 class SendVisitor extends ResolvedVisitor { | 39 class SendVisitor extends ResolvedVisitor { |
| 34 final PlaceholderCollector collector; | 40 final PlaceholderCollector collector; |
| 35 | 41 |
| 36 get compiler => collector.compiler; | 42 get compiler => collector.compiler; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 } | 91 } |
| 86 } | 92 } |
| 87 } | 93 } |
| 88 | 94 |
| 89 visitStaticSend(Send node) { | 95 visitStaticSend(Send node) { |
| 90 final element = elements[node]; | 96 final element = elements[node]; |
| 91 if (Elements.isUnresolved(element) | 97 if (Elements.isUnresolved(element) |
| 92 || identical(element, compiler.assertMethod)) { | 98 || identical(element, compiler.assertMethod)) { |
| 93 return; | 99 return; |
| 94 } | 100 } |
| 101 // TODO(smok): We should never go inside this IF, check? | |
| 95 if (element.isConstructor() || element.isFactoryConstructor()) { | 102 if (element.isConstructor() || element.isFactoryConstructor()) { |
| 96 // Rename named constructor in redirection position: | 103 // Rename named constructor in redirection position: |
| 97 // class C { C.named(); C.redirecting() : this.named(); } | 104 // class C { C.named(); C.redirecting() : this.named(); } |
| 105 // TODO(smok): Fix redirecting constructors. | |
| 98 if (node.receiver is Identifier | 106 if (node.receiver is Identifier |
| 99 && node.receiver.asIdentifier().isThis()) { | 107 && node.receiver.asIdentifier().isThis()) { |
| 100 assert(node.selector is Identifier); | 108 assert(node.selector is Identifier); |
| 101 collector.tryMakeMemberPlaceholder(node.selector); | 109 collector.tryMakeMemberPlaceholder(node.selector); |
| 102 } | 110 } |
| 103 // Field names can be exposed as names of optional arguments, e.g. | |
| 104 // class C { | |
| 105 // final field; | |
| 106 // C([this.field]); | |
| 107 // } | |
| 108 // Do not forget to rename them as well. | |
| 109 FunctionElement functionElement = element; | |
| 110 Link<Element> optionalParameters = | |
| 111 functionElement.functionSignature.optionalParameters; | |
| 112 for (final argument in node.argumentsNode) { | |
| 113 NamedArgument named = argument.asNamedArgument(); | |
| 114 if (named == null) continue; | |
| 115 Identifier name = named.name; | |
| 116 String nameAsString = name.source.slowToString(); | |
| 117 for (final parameter in optionalParameters) { | |
| 118 if (identical(parameter.kind, ElementKind.FIELD_PARAMETER)) { | |
| 119 if (parameter.name.slowToString() == nameAsString) { | |
| 120 collector.tryMakeMemberPlaceholder(name); | |
| 121 break; | |
| 122 } | |
| 123 } | |
| 124 } | |
| 125 } | |
| 126 return; | 111 return; |
| 127 } | 112 } |
| 128 collector.makeElementPlaceholder(node.selector, element); | 113 collector.makeElementPlaceholder(node.selector, element); |
| 129 // Another ugly case: <lib prefix>.<top level> is represented as | 114 // Another ugly case: <lib prefix>.<top level> is represented as |
| 130 // receiver: lib prefix, selector: top level. | 115 // receiver: lib prefix, selector: top level. |
| 131 if (element.isTopLevel() && node.receiver != null) { | 116 if (element.isTopLevel() && node.receiver != null) { |
| 132 assert(elements[node.receiver].isPrefix()); | 117 assert(elements[node.receiver].isPrefix()); |
| 133 // Hack: putting null into map overrides receiver of original node. | 118 // Hack: putting null into map overrides receiver of original node. |
| 134 collector.makeNullPlaceholder(node.receiver); | 119 collector.makeNullPlaceholder(node.receiver); |
| 135 } | 120 } |
| 136 } | 121 } |
| 137 | 122 |
| 138 internalError(String reason, {Node node}) { | 123 internalError(String reason, {Node node}) { |
| 139 collector.internalError(reason, node); | 124 collector.internalError(reason, node); |
| 140 } | 125 } |
| 141 } | 126 } |
| 142 | 127 |
| 143 class PlaceholderCollector extends Visitor { | 128 class PlaceholderCollector extends Visitor { |
| 144 final Compiler compiler; | 129 final Compiler compiler; |
| 145 final Set<String> fixedMemberNames; // member names which cannot be renamed. | 130 final Set<String> fixedMemberNames; // member names which cannot be renamed. |
| 146 final Map<Element, ElementAst> elementAsts; | 131 final Map<Element, ElementAst> elementAsts; |
| 147 final Set<Node> nullNodes; // Nodes that should not be in output. | 132 final Set<Node> nullNodes; // Nodes that should not be in output. |
| 148 final Set<Identifier> unresolvedNodes; | 133 final Set<Identifier> unresolvedNodes; |
| 149 final Map<Element, Set<Identifier>> elementNodes; | 134 final Map<Element, Set<Node>> elementNodes; |
| 150 final Map<FunctionElement, FunctionScope> functionScopes; | 135 final Map<FunctionElement, FunctionScope> functionScopes; |
| 151 final Map<LibraryElement, Set<Identifier>> privateNodes; | 136 final Map<LibraryElement, Set<Identifier>> privateNodes; |
| 152 final List<DeclarationTypePlaceholder> declarationTypePlaceholders; | 137 final List<DeclarationTypePlaceholder> declarationTypePlaceholders; |
| 153 final Map<String, Set<Identifier>> memberPlaceholders; | 138 final Map<String, Set<Identifier>> memberPlaceholders; |
| 139 final Map<Element, List<ConstructorPlaceholder>> constructorPlaceholders; | |
| 154 Map<String, LocalPlaceholder> currentLocalPlaceholders; | 140 Map<String, LocalPlaceholder> currentLocalPlaceholders; |
| 155 Element currentElement; | 141 Element currentElement; |
| 156 FunctionElement topmostEnclosingFunction; | 142 FunctionElement topmostEnclosingFunction; |
| 157 TreeElements treeElements; | 143 TreeElements treeElements; |
| 158 | 144 |
| 159 LibraryElement get coreLibrary => compiler.coreLibrary; | 145 LibraryElement get coreLibrary => compiler.coreLibrary; |
| 160 FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN); | 146 FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN); |
| 161 | 147 |
| 162 get currentFunctionScope => functionScopes.putIfAbsent( | 148 get currentFunctionScope => functionScopes.putIfAbsent( |
| 163 topmostEnclosingFunction, () => new FunctionScope()); | 149 topmostEnclosingFunction, () => new FunctionScope()); |
| 164 | 150 |
| 165 PlaceholderCollector(this.compiler, this.fixedMemberNames, this.elementAsts) : | 151 PlaceholderCollector(this.compiler, this.fixedMemberNames, this.elementAsts) : |
| 166 nullNodes = new Set<Node>(), | 152 nullNodes = new Set<Node>(), |
| 167 unresolvedNodes = new Set<Identifier>(), | 153 unresolvedNodes = new Set<Identifier>(), |
| 168 elementNodes = new Map<Element, Set<Identifier>>(), | 154 elementNodes = new Map<Element, Set<Node>>(), |
| 169 functionScopes = new Map<FunctionElement, FunctionScope>(), | 155 functionScopes = new Map<FunctionElement, FunctionScope>(), |
| 170 privateNodes = new Map<LibraryElement, Set<Identifier>>(), | 156 privateNodes = new Map<LibraryElement, Set<Identifier>>(), |
| 171 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), | 157 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), |
| 172 memberPlaceholders = new Map<String, Set<Identifier>>(); | 158 memberPlaceholders = new Map<String, Set<Identifier>>(), |
| 159 constructorPlaceholders = | |
| 160 new Map<Element, List<ConstructorPlaceholder>>(); | |
| 173 | 161 |
| 174 void tryMakeConstructorNamePlaceholder( | 162 void tryMakeConstructorPlaceholder( |
| 175 FunctionExpression constructor, ClassElement element) { | 163 FunctionExpression constructor, FunctionElement constructorElement) { |
| 176 Node nameNode = constructor.name; | 164 DartType type = constructorElement.getEnclosingClass().type.asRaw(); |
| 177 if (nameNode is Send) nameNode = nameNode.receiver; | 165 makeConstructorPlaceholder(constructor.name, constructorElement, type); |
| 178 if (nameNode.asIdentifier().token.slowToString() | |
| 179 == element.name.slowToString()) { | |
| 180 makeElementPlaceholder(nameNode, element); | |
| 181 } | |
| 182 } | 166 } |
| 183 | 167 |
| 184 void collectFunctionDeclarationPlaceholders( | 168 void collectFunctionDeclarationPlaceholders( |
| 185 FunctionElement element, FunctionExpression node) { | 169 FunctionElement element, FunctionExpression node) { |
| 186 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { | 170 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { |
| 187 // Two complicated cases for class/interface renaming: | 171 // Two complicated cases for class/interface renaming: |
| 188 // 1) class which implements constructors of other interfaces, but not | 172 // 1) class which implements constructors of other interfaces, but not |
| 189 // implements interfaces themselves: | 173 // implements interfaces themselves: |
| 190 // 0.dart: class C { I(); } | 174 // 0.dart: class C { I(); } |
| 191 // 1.dart and 2.dart: interface I default C { I(); } | 175 // 1.dart and 2.dart: interface I default C { I(); } |
| 192 // now we have to duplicate our I() constructor in C class with | 176 // now we have to duplicate our I() constructor in C class with |
| 193 // proper names. | 177 // proper names. |
| 194 // 2) (even worse for us): | 178 // 2) (even worse for us): |
| 195 // 0.dart: class C { C(); } | 179 // 0.dart: class C { C(); } |
| 196 // 1.dart: interface C default p0.C { C(); } | 180 // 1.dart: interface C default p0.C { C(); } |
| 197 // the second case is just a bug now. | 181 // the second case is just a bug now. |
| 198 tryMakeConstructorNamePlaceholder(node, element.getEnclosingClass()); | 182 tryMakeConstructorPlaceholder(node, element); |
| 199 | |
| 200 // If we have interface constructor, make sure that we put placeholder | |
| 201 // for its default factory implementation. | |
| 202 // Example: | |
| 203 // interface I default C { I();} | |
| 204 // class C { factory I() {} } | |
| 205 // 2 cases: | |
| 206 // Plain interface name. Rename it unless it is the default | |
| 207 // constructor for enclosing class. | |
| 208 // Example: | |
| 209 // interface I { I(); } | |
| 210 // class C implements I { C(); } don't rename this case. | |
| 211 // OR I.named() inside C, rename first part. | |
| 212 if (element.defaultImplementation != null | |
| 213 && !identical(element.defaultImplementation, element)) { | |
| 214 FunctionElement implementingFactory = element.defaultImplementation; | |
| 215 if (implementingFactory is !SynthesizedConstructorElement) { | |
| 216 tryMakeConstructorNamePlaceholder( | |
| 217 elementAsts[implementingFactory].ast, | |
| 218 element.getEnclosingClass()); | |
| 219 } | |
| 220 } | |
| 221 } else if (Elements.isStaticOrTopLevel(element)) { | 183 } else if (Elements.isStaticOrTopLevel(element)) { |
| 222 // Note: this code should only rename private identifiers for class' | 184 // Note: this code should only rename private identifiers for class' |
| 223 // fields/getters/setters/methods. Top-level identifiers are renamed | 185 // fields/getters/setters/methods. Top-level identifiers are renamed |
| 224 // just to escape conflicts and that should be enough as we shouldn't | 186 // just to escape conflicts and that should be enough as we shouldn't |
| 225 // be able to resolve private identifiers for other libraries. | 187 // be able to resolve private identifiers for other libraries. |
| 226 makeElementPlaceholder(node.name, element); | 188 makeElementPlaceholder(node.name, element); |
| 227 } else if (element.isMember()) { | 189 } else if (element.isMember()) { |
| 228 if (node.name is Identifier) { | 190 if (node.name is Identifier) { |
| 229 tryMakeMemberPlaceholder(node.name); | 191 tryMakeMemberPlaceholder(node.name); |
| 230 } else { | 192 } else { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 bool requiresVar = !node.modifiers.isFinalOrConst(); | 286 bool requiresVar = !node.modifiers.isFinalOrConst(); |
| 325 declarationTypePlaceholders.add( | 287 declarationTypePlaceholders.add( |
| 326 new DeclarationTypePlaceholder(node.type, requiresVar)); | 288 new DeclarationTypePlaceholder(node.type, requiresVar)); |
| 327 } | 289 } |
| 328 | 290 |
| 329 void makeNullPlaceholder(Node node) { | 291 void makeNullPlaceholder(Node node) { |
| 330 assert(node is Identifier || node is Send); | 292 assert(node is Identifier || node is Send); |
| 331 nullNodes.add(node); | 293 nullNodes.add(node); |
| 332 } | 294 } |
| 333 | 295 |
| 334 void makeElementPlaceholder(Identifier node, Element element) { | 296 void makeElementPlaceholder(Node node, Element element) { |
| 335 assert(element != null); | 297 assert(element != null); |
| 336 if (identical(element, entryFunction)) return; | 298 if (identical(element, entryFunction)) return; |
| 337 if (identical(element.getLibrary(), coreLibrary)) return; | 299 if (identical(element.getLibrary(), coreLibrary)) return; |
| 338 if (element.getLibrary().isPlatformLibrary && !element.isTopLevel()) { | 300 if (element.getLibrary().isPlatformLibrary && !element.isTopLevel()) { |
| 339 return; | 301 return; |
| 340 } | 302 } |
| 341 if (element == compiler.types.dynamicType.element) { | 303 if (element == compiler.types.dynamicType.element) { |
| 342 internalError( | 304 internalError( |
| 343 'Should never make element placeholder for dynamic type element', | 305 'Should never make element placeholder for dynamic type element', |
| 344 node: node); | 306 node: node); |
| 345 } | 307 } |
| 346 elementNodes.putIfAbsent(element, () => new Set<Identifier>()).add(node); | 308 elementNodes.putIfAbsent(element, () => new Set<Node>()).add(node); |
| 347 } | 309 } |
| 348 | 310 |
| 349 void makePrivateIdentifier(Identifier node) { | 311 void makePrivateIdentifier(Identifier node) { |
| 350 assert(node != null); | 312 assert(node != null); |
| 351 privateNodes.putIfAbsent( | 313 privateNodes.putIfAbsent( |
| 352 currentElement.getLibrary(), () => new Set<Identifier>()).add(node); | 314 currentElement.getLibrary(), () => new Set<Identifier>()).add(node); |
| 353 } | 315 } |
| 354 | 316 |
| 355 void makeUnresolvedPlaceholder(Node node) { | 317 void makeUnresolvedPlaceholder(Node node) { |
| 356 unresolvedNodes.add(node); | 318 unresolvedNodes.add(node); |
| 357 } | 319 } |
| 358 | 320 |
| 359 void makeLocalPlaceholder(Identifier identifier) { | 321 void makeLocalPlaceholder(Identifier identifier) { |
| 360 LocalPlaceholder getLocalPlaceholder() { | 322 LocalPlaceholder getLocalPlaceholder() { |
| 361 String name = identifier.source.slowToString(); | 323 String name = identifier.source.slowToString(); |
| 362 return currentLocalPlaceholders.putIfAbsent(name, () { | 324 return currentLocalPlaceholders.putIfAbsent(name, () { |
| 363 LocalPlaceholder localPlaceholder = new LocalPlaceholder(name); | 325 LocalPlaceholder localPlaceholder = new LocalPlaceholder(name); |
| 364 currentFunctionScope.localPlaceholders.add(localPlaceholder); | 326 currentFunctionScope.localPlaceholders.add(localPlaceholder); |
| 365 return localPlaceholder; | 327 return localPlaceholder; |
| 366 }); | 328 }); |
| 367 } | 329 } |
| 368 | 330 |
| 369 getLocalPlaceholder().nodes.add(identifier); | 331 getLocalPlaceholder().nodes.add(identifier); |
| 370 } | 332 } |
| 371 | 333 |
| 334 void makeConstructorPlaceholder(Node node, Element element, DartType type) { | |
| 335 constructorPlaceholders | |
| 336 .putIfAbsent(element, () => <ConstructorPlaceholder>[]) | |
| 337 .add(new ConstructorPlaceholder(node, type)); | |
| 338 } | |
| 339 | |
| 372 void internalError(String reason, {Node node}) { | 340 void internalError(String reason, {Node node}) { |
| 373 compiler.cancel(reason, node: node); | 341 compiler.cancel(reason, node: node); |
| 374 } | 342 } |
| 375 | 343 |
| 376 void unreachable() { internalError('Unreachable case'); } | 344 void unreachable() { internalError('Unreachable case'); } |
| 377 | 345 |
| 378 visit(Node node) => (node == null) ? null : node.accept(this); | 346 visit(Node node) => (node == null) ? null : node.accept(this); |
| 379 | 347 |
| 380 visitNode(Node node) { node.visitChildren(this); } // We must go deeper. | 348 visitNode(Node node) { node.visitChildren(this); } // We must go deeper. |
| 381 | 349 |
| 350 visitNewExpression(NewExpression node) { | |
| 351 Send send = node.send; | |
| 352 InterfaceType type = treeElements.getType(node); | |
| 353 assert(type !== null); | |
|
Anton Muhin
2012/10/29 18:19:22
nit: != here and everywhere
Roman
2012/10/29 18:40:28
Done.
| |
| 354 Element constructor = treeElements[send]; | |
| 355 assert(constructor !== null); | |
| 356 assert(send.receiver == null); | |
| 357 if (constructor is !ErroneousElement) { | |
| 358 makeConstructorPlaceholder(node.send.selector, constructor, type); | |
| 359 // TODO(smok): Should this be in visitNamedArgument? | |
| 360 // Field names can be exposed as names of optional arguments, e.g. | |
| 361 // class C { | |
| 362 // final field; | |
| 363 // C([this.field]); | |
| 364 // } | |
| 365 // Do not forget to rename them as well. | |
| 366 Link<Element> optionalParameters = | |
| 367 constructor.functionSignature.optionalParameters; | |
| 368 print(send.argumentsNode); | |
| 369 for (final argument in send.argumentsNode) { | |
| 370 NamedArgument named = argument.asNamedArgument(); | |
| 371 if (named == null) continue; | |
| 372 Identifier name = named.name; | |
| 373 String nameAsString = name.source.slowToString(); | |
| 374 for (final parameter in optionalParameters) { | |
| 375 if (identical(parameter.kind, ElementKind.FIELD_PARAMETER)) { | |
| 376 if (parameter.name.slowToString() == nameAsString) { | |
| 377 tryMakeMemberPlaceholder(name); | |
| 378 break; | |
| 379 } | |
| 380 } | |
| 381 } | |
| 382 } | |
| 383 } else { | |
| 384 makeUnresolvedPlaceholder(node.send.selector); | |
| 385 } | |
| 386 visit(node.send.argumentsNode); | |
| 387 } | |
| 388 | |
| 382 visitSend(Send send) { | 389 visitSend(Send send) { |
| 383 new SendVisitor(this, treeElements).visitSend(send); | 390 new SendVisitor(this, treeElements).visitSend(send); |
| 384 send.visitChildren(this); | 391 send.visitChildren(this); |
| 385 } | 392 } |
| 386 | 393 |
| 387 visitSendSet(SendSet send) { | 394 visitSendSet(SendSet send) { |
| 388 Element element = treeElements[send]; | 395 Element element = treeElements[send]; |
| 389 if (Elements.isErroneousElement(element)) { | 396 if (Elements.isErroneousElement(element)) { |
| 390 // Complicated case: constructs like receiver.selector++ can resolve | 397 // Complicated case: constructs like receiver.selector++ can resolve |
| 391 // to ErroneousElement. Fortunately, receiver.selector still | 398 // to ErroneousElement. Fortunately, receiver.selector still |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 441 } else { | 448 } else { |
| 442 typeDeclarationElement = currentElement.getEnclosingClass(); | 449 typeDeclarationElement = currentElement.getEnclosingClass(); |
| 443 } | 450 } |
| 444 if (typeDeclarationElement != null && isPlainTypeName(node) | 451 if (typeDeclarationElement != null && isPlainTypeName(node) |
| 445 && tryResolveAndCollectTypeVariable( | 452 && tryResolveAndCollectTypeVariable( |
| 446 typeDeclarationElement, node.typeName)) { | 453 typeDeclarationElement, node.typeName)) { |
| 447 return; | 454 return; |
| 448 } | 455 } |
| 449 // We call [resolveReturnType] to allow having 'void'. | 456 // We call [resolveReturnType] to allow having 'void'. |
| 450 final type = compiler.resolveReturnType(currentElement, node); | 457 final type = compiler.resolveReturnType(currentElement, node); |
| 451 bool hasPrefix = false; | |
| 452 if (type is InterfaceType || type is TypedefType) { | 458 if (type is InterfaceType || type is TypedefType) { |
| 453 Node target = node.typeName; | |
| 454 if (node.typeName is Send) { | |
| 455 final send = node.typeName.asSend(); | |
| 456 Identifier receiver = send.receiver; | |
| 457 Identifier selector = send.selector; | |
| 458 Element potentialPrefix = | |
| 459 currentElement.getLibrary().findLocal(receiver.source); | |
| 460 if (potentialPrefix != null && potentialPrefix.isPrefix()) { | |
| 461 // prefix.Class case. | |
| 462 hasPrefix = true; | |
| 463 } else { | |
| 464 // Class.namedContructor case. | |
| 465 target = receiver; | |
| 466 // If element is unresolved, mark namedConstructor as unresolved. | |
| 467 if (treeElements[node] == null) { | |
| 468 makeUnresolvedPlaceholder(selector); | |
| 469 } | |
| 470 } | |
| 471 } | |
| 472 // TODO(antonm): is there a better way to detect unresolved types? | 459 // TODO(antonm): is there a better way to detect unresolved types? |
| 473 // Corner case: dart:core type with a prefix. | 460 // Corner case: dart:core type with a prefix. |
| 474 // Most probably there are some additional problems with | 461 // Most probably there are some additional problems with |
| 475 // coreLibPrefix.topLevels. | 462 // coreLibPrefix.topLevels. |
| 476 Element typeElement = type.element; | 463 if (!identical(type.element, compiler.types.dynamicType.element)) { |
| 477 Element dynamicTypeElement = compiler.types.dynamicType.element; | 464 makeTypePlaceholder(node.typeName, type); |
| 478 if (hasPrefix && | |
| 479 (identical(typeElement.getLibrary(), coreLibrary) || | |
| 480 identical(typeElement, dynamicTypeElement))) { | |
| 481 makeNullPlaceholder(node.typeName.asSend().receiver); | |
| 482 } else { | 465 } else { |
| 483 if (hasPrefix) { | 466 if (!isDynamicType(node)) makeUnresolvedPlaceholder(node.typeName); |
| 484 assert(node.typeName is Send); | |
| 485 Send typeName = node.typeName; | |
| 486 assert(typeName.receiver is Identifier); | |
| 487 assert(typeName.selector is Identifier); | |
| 488 makeNullPlaceholder(typeName.receiver); | |
| 489 } | |
| 490 if (!identical(typeElement, dynamicTypeElement)) { | |
| 491 makeTypePlaceholder(target, type); | |
| 492 } else { | |
| 493 if (!isDynamicType(node)) makeUnresolvedPlaceholder(target); | |
| 494 } | |
| 495 } | 467 } |
| 496 } | 468 } |
| 497 // Trying to differentiate new A.foo() and lib.A cases. In the latter case | 469 // Visit only type arguments, otherwise in case of lib.Class type |
| 498 // we don't want to go deeper into typeName. | 470 // annotation typeName is Send and we go to visitGetterSend, as a result |
| 499 if (hasPrefix) { | 471 // "Class" is added to member placeholders. |
| 500 // Visit only type arguments, otherwise in case of lib.Class type | 472 visit(node.typeArguments); |
| 501 // annotation typeName is Send and we go to visitGetterSend, as a result | |
| 502 // "Class" is added to member placeholders. | |
| 503 visit(node.typeArguments); | |
| 504 } else { | |
| 505 node.visitChildren(this); | |
| 506 } | |
| 507 } | 473 } |
| 508 | 474 |
| 509 visitVariableDefinitions(VariableDefinitions node) { | 475 visitVariableDefinitions(VariableDefinitions node) { |
| 510 // Collect only local placeholders. | 476 // Collect only local placeholders. |
| 511 for (Node definition in node.definitions.nodes) { | 477 for (Node definition in node.definitions.nodes) { |
| 512 Element definitionElement = treeElements[definition]; | 478 Element definitionElement = treeElements[definition]; |
| 513 // definitionElement may be null if we're inside variable definitions | 479 // definitionElement may be null if we're inside variable definitions |
| 514 // of a function that is a parameter of another function. | 480 // of a function that is a parameter of another function. |
| 515 // TODO(smok): Fix this when resolver correctly deals with | 481 // TODO(smok): Fix this when resolver correctly deals with |
| 516 // such cases. | 482 // such cases. |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 | 604 |
| 639 visitBlock(Block node) { | 605 visitBlock(Block node) { |
| 640 for (Node statement in node.statements.nodes) { | 606 for (Node statement in node.statements.nodes) { |
| 641 if (statement is VariableDefinitions) { | 607 if (statement is VariableDefinitions) { |
| 642 makeVarDeclarationTypePlaceholder(statement); | 608 makeVarDeclarationTypePlaceholder(statement); |
| 643 } | 609 } |
| 644 } | 610 } |
| 645 node.visitChildren(this); | 611 node.visitChildren(this); |
| 646 } | 612 } |
| 647 } | 613 } |
| OLD | NEW |