Chromium Code Reviews| Index: lib/compiler/implementation/dart_backend/placeholder_collector.dart |
| diff --git a/lib/compiler/implementation/dart_backend/placeholder_collector.dart b/lib/compiler/implementation/dart_backend/placeholder_collector.dart |
| index 8f9c29b76e2266345c4650058b8e84dee00e932d..573d13df8cc8b6b52e9fb6fc70b1ccf0ecaf3e15 100644 |
| --- a/lib/compiler/implementation/dart_backend/placeholder_collector.dart |
| +++ b/lib/compiler/implementation/dart_backend/placeholder_collector.dart |
| @@ -33,11 +33,20 @@ class SendVisitor extends ResolvedVisitor { |
| SendVisitor(this.collector, TreeElements elements) : super(elements); |
| - visitDynamicSend(Send node) {} |
| - visitSuperSend(Send node) {} |
| visitOperatorSend(Send node) {} |
| visitForeignSend(Send node) {} |
| + visitSuperSend(Send node) { |
| + 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
|
| + } |
| + |
| + visitDynamicSend(Send node) { |
| + final element = elements[node]; |
| + if (element === null || !element.isErroneous()) { |
| + collector.tryMakeMemberPlaceholder(node.selector); |
| + } |
| + } |
| + |
| visitClosureSend(Send node) { |
| final element = elements[node]; |
| if (element !== null) { |
| @@ -48,27 +57,55 @@ class SendVisitor extends ResolvedVisitor { |
| visitGetterSend(Send node) { |
| final element = elements[node]; |
| // element === null means dynamic property access. |
| - if (element === null) return; |
| - if (element.isPrefix()) { |
| + if (element === null) { |
| + collector.tryMakeMemberPlaceholder(node.selector); |
| + } else if (element.isPrefix()) { |
| // Node is prefix part in case of source 'lib.somesetter = 5;' |
| collector.makeNullPlaceholder(node); |
| } else if (Elements.isStaticOrTopLevel(element)) { |
| // Unqualified or prefixed top level or static. |
| collector.makeElementPlaceholder(node.selector, element); |
| } else if (!element.isTopLevel()) { |
| - // May get FunctionExpression here in selector |
| - // in case of A(int this.f()); |
| - if (node.selector is Identifier) { |
| - collector.tryMakeLocalPlaceholder(element, node.selector); |
| + if (element.isInstanceMember()) { |
| + collector.tryMakeMemberPlaceholder(node.selector); |
| } else { |
| - assert(node.selector is FunctionExpression); |
| + // May get FunctionExpression here in selector |
| + // in case of A(int this.f()); |
| + if (node.selector is Identifier) { |
| + collector.tryMakeLocalPlaceholder(element, node.selector); |
| + } else { |
| + assert(node.selector is FunctionExpression); |
| + } |
| } |
| } |
| } |
| visitStaticSend(Send node) { |
| final element = elements[node]; |
| - if (element.isConstructor() || element.isFactoryConstructor()) return; |
| + if (element.isConstructor() || element.isFactoryConstructor()) { |
| + 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.
|
| + assert(node.selector is Identifier); |
| + collector.tryMakeMemberPlaceholder(node.selector); |
| + } |
| + 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.
|
| + Link<Element> optionalParameters = |
| + functionElement.functionSignature.optionalParameters; |
| + for (final argument in node.argumentsNode) { |
| + NamedArgument named = argument.asNamedArgument(); |
| + if (named === null) continue; |
| + Identifier name = named.name; |
| + String nameAsString = name.source.slowToString(); |
| + for (final parameter in optionalParameters) { |
| + if (parameter.kind === ElementKind.FIELD_PARAMETER) { |
| + if (parameter.name.slowToString() == nameAsString) { |
| + collector.tryMakeMemberPlaceholder(name); |
| + break; |
| + } |
| + } |
| + } |
| + } |
| + return; |
| + } |
| collector.makeElementPlaceholder(node.selector, element); |
| // Another ugly case: <lib prefix>.<top level> is represented as |
| // receiver: lib prefix, selector: top level. |
| @@ -86,12 +123,14 @@ class SendVisitor extends ResolvedVisitor { |
| class PlaceholderCollector extends AbstractVisitor { |
| final Compiler compiler; |
| + final Set<String> fixedMemberNames; // member names which cannot be renamed. |
| final Set<Node> nullNodes; // Nodes that should not be in output. |
| final Set<Identifier> unresolvedNodes; |
| final Map<Element, Set<Node>> elementNodes; |
| final Map<FunctionElement, FunctionScope> functionScopes; |
| final Map<LibraryElement, Set<Identifier>> privateNodes; |
| final List<DeclarationTypePlaceholder> declarationTypePlaceholders; |
| + final Map<String, Set<Identifier>> memberPlaceholders; |
| Map<String, LocalPlaceholder> currentLocalPlaceholders; |
| Element currentElement; |
| TreeElements treeElements; |
| @@ -99,13 +138,14 @@ class PlaceholderCollector extends AbstractVisitor { |
| LibraryElement get coreLibrary => compiler.coreLibrary; |
| FunctionElement get entryFunction => compiler.mainApp.find(Compiler.MAIN); |
| - PlaceholderCollector(this.compiler) : |
| + PlaceholderCollector(this.compiler, this.fixedMemberNames) : |
| nullNodes = new Set<Node>(), |
| unresolvedNodes = new Set<Identifier>(), |
| elementNodes = new Map<Element, Set<Node>>(), |
| functionScopes = new Map<FunctionElement, FunctionScope>(), |
| privateNodes = new Map<LibraryElement, Set<Identifier>>(), |
| - declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(); |
| + declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(), |
| + memberPlaceholders = new Map<String, Set<Identifier>>(); |
| void tryMakeConstructorNamePlaceholder( |
| FunctionExpression constructor, ClassElement element) { |
| @@ -157,20 +197,24 @@ class PlaceholderCollector extends AbstractVisitor { |
| // just to escape conflicts and that should be enough as we shouldn't |
| // be able to resolve private identifiers for other libraries. |
| makeElementPlaceholder(node.name, element); |
| + } else if (element.isMember()) { |
| + if (node.name is Identifier) { |
| + tryMakeMemberPlaceholder(node.name); |
| + } else { |
| + assert(node.name.asSend().isOperator); |
| + } |
| } |
| } |
| void collectFieldDeclarationPlaceholders( |
| Element element, VariableDefinitions node) { |
| + Node fieldNode = element.parseNode(compiler); |
| + Identifier name = |
| + fieldNode is Identifier ? fieldNode : fieldNode.asSend().selector; |
| if (Elements.isStaticOrTopLevel(element)) { |
| - Node fieldNode = element.parseNode(compiler); |
| - if (fieldNode is Identifier) { |
| - makeElementPlaceholder(fieldNode, element); |
| - } else if (fieldNode is SendSet) { |
| - makeElementPlaceholder(fieldNode.selector, element); |
| - } else { |
| - unreachable(); |
| - } |
| + makeElementPlaceholder(name, element); |
| + } else if (Elements.isInstanceField(element)) { |
| + tryMakeMemberPlaceholder(name); |
| } |
| makeVarDeclarationTypePlaceholder(node); |
| } |
| @@ -222,6 +266,16 @@ class PlaceholderCollector extends AbstractVisitor { |
| } |
| } |
| + void tryMakeMemberPlaceholder(Identifier node) { |
| + assert(node !== null); |
| + if (node.source.isPrivate()) return; |
| + if (node is Operator) return; |
| + final identifier = node.source.slowToString(); |
| + if (fixedMemberNames.contains(identifier)) return; |
| + memberPlaceholders.putIfAbsent( |
| + identifier, () => new Set<Identifier>()).add(node); |
| + } |
| + |
| void makeTypePlaceholder(Node node, Type type) { |
| makeElementPlaceholder(node, type.element); |
| } |
| @@ -313,7 +367,15 @@ class PlaceholderCollector extends AbstractVisitor { |
| makeElementPlaceholder(send.selector, element); |
| } else { |
| assert(send.selector is Identifier); |
| - tryMakeLocalPlaceholder(element, send.selector); |
| + if (Elements.isInstanceField(element)) { |
| + tryMakeMemberPlaceholder(send.selector); |
| + } else { |
| + tryMakeLocalPlaceholder(element, send.selector); |
| + } |
| + } |
| + } else { |
| + if (send.receiver !== null) { |
| + tryMakeMemberPlaceholder(send.selector); |
| } |
| } |
| send.visitChildren(this); |
| @@ -393,9 +455,17 @@ class PlaceholderCollector extends AbstractVisitor { |
| // May get FunctionExpression here in definition.selector |
| // in case of A(int this.f()); |
| if (definition.selector is Identifier) { |
| - tryMakeLocalPlaceholder(definitionElement, definition.selector); |
| + if (definitionElement.kind === ElementKind.FIELD_PARAMETER) { |
| + tryMakeMemberPlaceholder(definition.selector); |
| + } else { |
| + tryMakeLocalPlaceholder(definitionElement, definition.selector); |
| + } |
| } else { |
| assert(definition.selector is FunctionExpression); |
| + if (definitionElement.kind === ElementKind.FIELD_PARAMETER) { |
| + tryMakeMemberPlaceholder( |
| + definition.selector.asFunctionExpression().name); |
| + } |
| } |
| } else if (definition is Identifier) { |
| tryMakeLocalPlaceholder(definitionElement, definition); |