Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: lib/compiler/implementation/dart_backend/placeholder_collector.dart

Issue 10913250: Properly collect placeholders for function expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 final Map<Element, ElementAst> elementAsts; 143 final Map<Element, ElementAst> elementAsts;
144 final Set<Node> nullNodes; // Nodes that should not be in output. 144 final Set<Node> nullNodes; // Nodes that should not be in output.
145 final Set<Identifier> unresolvedNodes; 145 final Set<Identifier> unresolvedNodes;
146 final Map<Element, Set<Node>> elementNodes; 146 final Map<Element, Set<Node>> elementNodes;
147 final Map<FunctionElement, FunctionScope> functionScopes; 147 final Map<FunctionElement, FunctionScope> functionScopes;
148 final Map<LibraryElement, Set<Identifier>> privateNodes; 148 final Map<LibraryElement, Set<Identifier>> privateNodes;
149 final List<DeclarationTypePlaceholder> declarationTypePlaceholders; 149 final List<DeclarationTypePlaceholder> declarationTypePlaceholders;
150 final Map<String, Set<Identifier>> memberPlaceholders; 150 final Map<String, Set<Identifier>> memberPlaceholders;
151 Map<String, LocalPlaceholder> currentLocalPlaceholders; 151 Map<String, LocalPlaceholder> currentLocalPlaceholders;
152 Element currentElement; 152 Element currentElement;
153 FunctionElement topmostEnclosingFunction;
153 TreeElements treeElements; 154 TreeElements treeElements;
154 155
155 LibraryElement get coreLibrary => compiler.coreLibrary; 156 LibraryElement get coreLibrary => compiler.coreLibrary;
156 FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN); 157 FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN);
157 158
159 get currentFunctionScope => functionScopes.putIfAbsent(
160 topmostEnclosingFunction, () => new FunctionScope());
161
158 PlaceholderCollector(this.compiler, this.fixedMemberNames, this.elementAsts) : 162 PlaceholderCollector(this.compiler, this.fixedMemberNames, this.elementAsts) :
159 nullNodes = new Set<Node>(), 163 nullNodes = new Set<Node>(),
160 unresolvedNodes = new Set<Identifier>(), 164 unresolvedNodes = new Set<Identifier>(),
161 elementNodes = new Map<Element, Set<Node>>(), 165 elementNodes = new Map<Element, Set<Node>>(),
162 functionScopes = new Map<FunctionElement, FunctionScope>(), 166 functionScopes = new Map<FunctionElement, FunctionScope>(),
163 privateNodes = new Map<LibraryElement, Set<Identifier>>(), 167 privateNodes = new Map<LibraryElement, Set<Identifier>>(),
164 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), 168 declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(),
165 memberPlaceholders = new Map<String, Set<Identifier>>(); 169 memberPlaceholders = new Map<String, Set<Identifier>>();
166 170
167 void tryMakeConstructorNamePlaceholder( 171 void tryMakeConstructorNamePlaceholder(
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 Identifier name = node is Identifier ? node : node.asSend().selector; 234 Identifier name = node is Identifier ? node : node.asSend().selector;
231 if (Elements.isStaticOrTopLevel(element)) { 235 if (Elements.isStaticOrTopLevel(element)) {
232 makeElementPlaceholder(name, element); 236 makeElementPlaceholder(name, element);
233 } else if (Elements.isInstanceField(element)) { 237 } else if (Elements.isInstanceField(element)) {
234 tryMakeMemberPlaceholder(name); 238 tryMakeMemberPlaceholder(name);
235 } 239 }
236 } 240 }
237 241
238 void collect(Element element) { 242 void collect(Element element) {
239 this.currentElement = element; 243 this.currentElement = element;
244 this.topmostEnclosingFunction = null;
240 final ElementAst elementAst = elementAsts[element]; 245 final ElementAst elementAst = elementAsts[element];
241 this.treeElements = elementAst.treeElements; 246 this.treeElements = elementAst.treeElements;
242 Node elementNode = elementAst.ast; 247 Node elementNode = elementAst.ast;
243 if (element is FunctionElement) { 248 if (element is FunctionElement) {
244 collectFunctionDeclarationPlaceholders(element, elementNode); 249 collectFunctionDeclarationPlaceholders(element, elementNode);
245 } else if (element is VariableListElement) { 250 } else if (element is VariableListElement) {
246 VariableDefinitions definitions = elementNode; 251 VariableDefinitions definitions = elementNode;
247 for (Node definition in definitions.definitions) { 252 for (Node definition in definitions.definitions) {
248 final definitionElement = treeElements[definition]; 253 final definitionElement = treeElements[definition];
249 // definitionElement === null if variable is actually unused. 254 // definitionElement === null if variable is actually unused.
(...skipping 16 matching lines...) Expand all
266 for (Element parameter in function.functionSignature.optionalParameters) { 271 for (Element parameter in function.functionSignature.optionalParameters) {
267 if (parameter === element) return true; 272 if (parameter === element) return true;
268 } 273 }
269 return false; 274 return false;
270 } 275 }
271 276
272 // TODO(smok): Maybe we should rename privates as well, their privacy 277 // TODO(smok): Maybe we should rename privates as well, their privacy
273 // should not matter if they are local vars. 278 // should not matter if they are local vars.
274 if (node.source.isPrivate()) return; 279 if (node.source.isPrivate()) return;
275 if (element.isParameter() && isOptionalParameter()) { 280 if (element.isParameter() && isOptionalParameter()) {
276 functionScopes.putIfAbsent(currentElement, () => new FunctionScope()) 281 currentFunctionScope.registerParameter(node);
277 .registerParameter(node);
278 } else if (Elements.isLocal(element)) { 282 } else if (Elements.isLocal(element)) {
279 makeLocalPlaceholder(node); 283 makeLocalPlaceholder(node);
280 } 284 }
281 } 285 }
282 286
283 void tryMakeMemberPlaceholder(Identifier node) { 287 void tryMakeMemberPlaceholder(Identifier node) {
284 assert(node !== null); 288 assert(node !== null);
285 if (node.source.isPrivate()) return; 289 if (node.source.isPrivate()) return;
286 if (node is Operator) return; 290 if (node is Operator) return;
287 final identifier = node.source.slowToString(); 291 final identifier = node.source.slowToString();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 344
341 void makeUnresolvedPlaceholder(Node node) { 345 void makeUnresolvedPlaceholder(Node node) {
342 unresolvedNodes.add(node); 346 unresolvedNodes.add(node);
343 } 347 }
344 348
345 void makeLocalPlaceholder(Identifier identifier) { 349 void makeLocalPlaceholder(Identifier identifier) {
346 LocalPlaceholder getLocalPlaceholder() { 350 LocalPlaceholder getLocalPlaceholder() {
347 String name = identifier.source.slowToString(); 351 String name = identifier.source.slowToString();
348 return currentLocalPlaceholders.putIfAbsent(name, () { 352 return currentLocalPlaceholders.putIfAbsent(name, () {
349 LocalPlaceholder localPlaceholder = new LocalPlaceholder(name); 353 LocalPlaceholder localPlaceholder = new LocalPlaceholder(name);
350 functionScopes.putIfAbsent(currentElement, () => new FunctionScope()) 354 currentFunctionScope.localPlaceholders.add(localPlaceholder);
351 .localPlaceholders.add(localPlaceholder);
352 return localPlaceholder; 355 return localPlaceholder;
353 }); 356 });
354 } 357 }
355 358
356 assert(currentElement is FunctionElement);
357 getLocalPlaceholder().nodes.add(identifier); 359 getLocalPlaceholder().nodes.add(identifier);
358 } 360 }
359 361
360 void internalError(String reason, [Node node]) { 362 void internalError(String reason, [Node node]) {
361 compiler.cancel(reason: reason, node: node); 363 compiler.cancel(reason: reason, node: node);
362 } 364 }
363 365
364 void unreachable() { internalError('Unreachable case'); } 366 void unreachable() { internalError('Unreachable case'); }
365 367
366 visit(Node node) => (node === null) ? null : node.accept(this); 368 visit(Node node) => (node === null) ? null : node.accept(this);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 makeTypePlaceholder(target, type); 452 makeTypePlaceholder(target, type);
451 } else { 453 } else {
452 if (!isDynamicType(node)) makeUnresolvedPlaceholder(target); 454 if (!isDynamicType(node)) makeUnresolvedPlaceholder(target);
453 } 455 }
454 } 456 }
455 node.visitChildren(this); 457 node.visitChildren(this);
456 } 458 }
457 459
458 visitVariableDefinitions(VariableDefinitions node) { 460 visitVariableDefinitions(VariableDefinitions node) {
459 // Collect only local placeholders. 461 // Collect only local placeholders.
460 if (currentElement is FunctionElement) { 462 for (Node definition in node.definitions.nodes) {
461 for (Node definition in node.definitions.nodes) { 463 Element definitionElement = treeElements[definition];
462 Element definitionElement = treeElements[definition]; 464 // definitionElement may be null if we're inside variable definitions
463 // definitionElement may be null if we're inside variable definitions 465 // of a function that is a parameter of another function.
464 // of a function that is a parameter of another function. 466 // TODO(smok): Fix this when resolver correctly deals with
465 // TODO(smok): Fix this when resolver correctly deals with 467 // such cases.
466 // such cases. 468 if (definitionElement === null) continue;
467 if (definitionElement === null) continue; 469 if (definition is Send) {
468 if (definition is Send) { 470 // May get FunctionExpression here in definition.selector
469 // May get FunctionExpression here in definition.selector 471 // in case of A(int this.f());
470 // in case of A(int this.f()); 472 if (definition.selector is Identifier) {
471 if (definition.selector is Identifier) { 473 if (definitionElement.kind === ElementKind.FIELD_PARAMETER) {
472 if (definitionElement.kind === ElementKind.FIELD_PARAMETER) { 474 tryMakeMemberPlaceholder(definition.selector);
473 tryMakeMemberPlaceholder(definition.selector);
474 } else {
475 tryMakeLocalPlaceholder(definitionElement, definition.selector);
476 }
477 } else { 475 } else {
478 assert(definition.selector is FunctionExpression); 476 tryMakeLocalPlaceholder(definitionElement, definition.selector);
479 if (definitionElement.kind === ElementKind.FIELD_PARAMETER) {
480 tryMakeMemberPlaceholder(
481 definition.selector.asFunctionExpression().name);
482 }
483 } 477 }
484 } else if (definition is Identifier) {
485 tryMakeLocalPlaceholder(definitionElement, definition);
486 } else if (definition is FunctionExpression) {
487 // Skip, it will be processed in visitFunctionExpression.
488 } else { 478 } else {
489 internalError('Unexpected definition structure $definition'); 479 assert(definition.selector is FunctionExpression);
480 if (definitionElement.kind === ElementKind.FIELD_PARAMETER) {
481 tryMakeMemberPlaceholder(
482 definition.selector.asFunctionExpression().name);
483 }
490 } 484 }
485 } else if (definition is Identifier) {
486 tryMakeLocalPlaceholder(definitionElement, definition);
487 } else if (definition is FunctionExpression) {
488 // Skip, it will be processed in visitFunctionExpression.
489 } else {
490 internalError('Unexpected definition structure $definition');
491 } 491 }
492 } 492 }
493 node.visitChildren(this); 493 node.visitChildren(this);
494 } 494 }
495 495
496 visitFunctionExpression(FunctionExpression node) { 496 visitFunctionExpression(FunctionExpression node) {
497 Element element = treeElements[node]; 497 Element element = treeElements[node];
498 // May get null here in case of A(int this.f()); 498 // May get null here in case of A(int this.f());
499 if (element !== null) { 499 if (element !== null) {
500 // Rename only local functions. 500 // Rename only local functions.
501 if (topmostEnclosingFunction === null) {
502 topmostEnclosingFunction = element;
503 }
501 if (element !== currentElement) { 504 if (element !== currentElement) {
502 if (node.name !== null) { 505 if (node.name !== null) {
503 assert(node.name is Identifier); 506 assert(node.name is Identifier);
504 tryMakeLocalPlaceholder(element, node.name); 507 tryMakeLocalPlaceholder(element, node.name);
505 } 508 }
506 } 509 }
507 } 510 }
508 node.visitChildren(this); 511 node.visitChildren(this);
509 makeOmitDeclarationTypePlaceholder(node.returnType); 512 makeOmitDeclarationTypePlaceholder(node.returnType);
510 collectFunctionParameters(node.parameters); 513 collectFunctionParameters(node.parameters);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 579
577 visitBlock(Block node) { 580 visitBlock(Block node) {
578 for (Node statement in node.statements.nodes) { 581 for (Node statement in node.statements.nodes) {
579 if (statement is VariableDefinitions) { 582 if (statement is VariableDefinitions) {
580 makeVarDeclarationTypePlaceholder(statement); 583 makeVarDeclarationTypePlaceholder(statement);
581 } 584 }
582 } 585 }
583 node.visitChildren(this); 586 node.visitChildren(this);
584 } 587 }
585 } 588 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698