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

Unified Diff: lib/compiler/implementation/dart_backend/placeholder_collector.dart

Issue 11267046: [dart2dart] fix after https://codereview.chromium.org/11227007 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 2 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 side-by-side diff with in-line comments
Download patch
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 b1b363908c7a6230cc07bb48da17b4fd90536ce9..e4ffc3ac78590da519de58362eebe06949dbe8f0 100644
--- a/lib/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/lib/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -24,6 +24,12 @@ class FunctionScope {
}
}
+class ConstructorPlaceholder {
+ final Node node;
+ final DartType type;
+ ConstructorPlaceholder(this.node, this.type);
+}
+
class DeclarationTypePlaceholder {
final TypeAnnotation typeNode;
final bool requiresVar;
@@ -92,37 +98,16 @@ class SendVisitor extends ResolvedVisitor {
|| identical(element, compiler.assertMethod)) {
return;
}
+ // TODO(smok): We should never go inside this IF, check?
if (element.isConstructor() || element.isFactoryConstructor()) {
// Rename named constructor in redirection position:
// class C { C.named(); C.redirecting() : this.named(); }
+ // TODO(smok): Fix redirecting constructors.
if (node.receiver is Identifier
&& node.receiver.asIdentifier().isThis()) {
assert(node.selector is Identifier);
collector.tryMakeMemberPlaceholder(node.selector);
}
- // Field names can be exposed as names of optional arguments, e.g.
- // class C {
- // final field;
- // C([this.field]);
- // }
- // Do not forget to rename them as well.
- FunctionElement functionElement = element;
- 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 (identical(parameter.kind, ElementKind.FIELD_PARAMETER)) {
- if (parameter.name.slowToString() == nameAsString) {
- collector.tryMakeMemberPlaceholder(name);
- break;
- }
- }
- }
- }
return;
}
collector.makeElementPlaceholder(node.selector, element);
@@ -146,11 +131,12 @@ class PlaceholderCollector extends Visitor {
final Map<Element, ElementAst> elementAsts;
final Set<Node> nullNodes; // Nodes that should not be in output.
final Set<Identifier> unresolvedNodes;
- final Map<Element, Set<Identifier>> elementNodes;
+ 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;
+ final Map<Element, List<ConstructorPlaceholder>> constructorPlaceholders;
Map<String, LocalPlaceholder> currentLocalPlaceholders;
Element currentElement;
FunctionElement topmostEnclosingFunction;
@@ -165,20 +151,18 @@ class PlaceholderCollector extends Visitor {
PlaceholderCollector(this.compiler, this.fixedMemberNames, this.elementAsts) :
nullNodes = new Set<Node>(),
unresolvedNodes = new Set<Identifier>(),
- elementNodes = new Map<Element, Set<Identifier>>(),
+ elementNodes = new Map<Element, Set<Node>>(),
functionScopes = new Map<FunctionElement, FunctionScope>(),
privateNodes = new Map<LibraryElement, Set<Identifier>>(),
declarationTypePlaceholders = new List<DeclarationTypePlaceholder>(),
- memberPlaceholders = new Map<String, Set<Identifier>>();
-
- void tryMakeConstructorNamePlaceholder(
- FunctionExpression constructor, ClassElement element) {
- Node nameNode = constructor.name;
- if (nameNode is Send) nameNode = nameNode.receiver;
- if (nameNode.asIdentifier().token.slowToString()
- == element.name.slowToString()) {
- makeElementPlaceholder(nameNode, element);
- }
+ memberPlaceholders = new Map<String, Set<Identifier>>(),
+ constructorPlaceholders =
+ new Map<Element, List<ConstructorPlaceholder>>();
+
+ void tryMakeConstructorPlaceholder(
+ FunctionExpression constructor, FunctionElement constructorElement) {
+ DartType type = constructorElement.getEnclosingClass().type.asRaw();
+ makeConstructorPlaceholder(constructor.name, constructorElement, type);
}
void collectFunctionDeclarationPlaceholders(
@@ -195,29 +179,7 @@ class PlaceholderCollector extends Visitor {
// 0.dart: class C { C(); }
// 1.dart: interface C default p0.C { C(); }
// the second case is just a bug now.
- tryMakeConstructorNamePlaceholder(node, element.getEnclosingClass());
-
- // If we have interface constructor, make sure that we put placeholder
- // for its default factory implementation.
- // Example:
- // interface I default C { I();}
- // class C { factory I() {} }
- // 2 cases:
- // Plain interface name. Rename it unless it is the default
- // constructor for enclosing class.
- // Example:
- // interface I { I(); }
- // class C implements I { C(); } don't rename this case.
- // OR I.named() inside C, rename first part.
- if (element.defaultImplementation != null
- && !identical(element.defaultImplementation, element)) {
- FunctionElement implementingFactory = element.defaultImplementation;
- if (implementingFactory is !SynthesizedConstructorElement) {
- tryMakeConstructorNamePlaceholder(
- elementAsts[implementingFactory].ast,
- element.getEnclosingClass());
- }
- }
+ tryMakeConstructorPlaceholder(node, element);
} else if (Elements.isStaticOrTopLevel(element)) {
// Note: this code should only rename private identifiers for class'
// fields/getters/setters/methods. Top-level identifiers are renamed
@@ -331,7 +293,7 @@ class PlaceholderCollector extends Visitor {
nullNodes.add(node);
}
- void makeElementPlaceholder(Identifier node, Element element) {
+ void makeElementPlaceholder(Node node, Element element) {
assert(element != null);
if (identical(element, entryFunction)) return;
if (identical(element.getLibrary(), coreLibrary)) return;
@@ -343,7 +305,7 @@ class PlaceholderCollector extends Visitor {
'Should never make element placeholder for dynamic type element',
node: node);
}
- elementNodes.putIfAbsent(element, () => new Set<Identifier>()).add(node);
+ elementNodes.putIfAbsent(element, () => new Set<Node>()).add(node);
}
void makePrivateIdentifier(Identifier node) {
@@ -369,6 +331,12 @@ class PlaceholderCollector extends Visitor {
getLocalPlaceholder().nodes.add(identifier);
}
+ void makeConstructorPlaceholder(Node node, Element element, DartType type) {
+ constructorPlaceholders
+ .putIfAbsent(element, () => <ConstructorPlaceholder>[])
+ .add(new ConstructorPlaceholder(node, type));
+ }
+
void internalError(String reason, {Node node}) {
compiler.cancel(reason, node: node);
}
@@ -379,6 +347,45 @@ class PlaceholderCollector extends Visitor {
visitNode(Node node) { node.visitChildren(this); } // We must go deeper.
+ visitNewExpression(NewExpression node) {
+ Send send = node.send;
+ InterfaceType type = treeElements.getType(node);
+ assert(type != null);
+ Element constructor = treeElements[send];
+ assert(constructor != null);
+ assert(send.receiver == null);
+ if (constructor is !ErroneousElement) {
+ makeConstructorPlaceholder(node.send.selector, constructor, type);
+ // TODO(smok): Should this be in visitNamedArgument?
+ // Field names can be exposed as names of optional arguments, e.g.
+ // class C {
+ // final field;
+ // C([this.field]);
+ // }
+ // Do not forget to rename them as well.
+ Link<Element> optionalParameters =
+ constructor.functionSignature.optionalParameters;
+ print(send.argumentsNode);
+ for (final argument in send.argumentsNode) {
+ NamedArgument named = argument.asNamedArgument();
+ if (named == null) continue;
+ Identifier name = named.name;
+ String nameAsString = name.source.slowToString();
+ for (final parameter in optionalParameters) {
+ if (identical(parameter.kind, ElementKind.FIELD_PARAMETER)) {
+ if (parameter.name.slowToString() == nameAsString) {
+ tryMakeMemberPlaceholder(name);
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ makeUnresolvedPlaceholder(node.send.selector);
+ }
+ visit(node.send.argumentsNode);
+ }
+
visitSend(Send send) {
new SendVisitor(this, treeElements).visitSend(send);
send.visitChildren(this);
@@ -448,62 +455,21 @@ class PlaceholderCollector extends Visitor {
}
// We call [resolveReturnType] to allow having 'void'.
final type = compiler.resolveReturnType(currentElement, node);
- bool hasPrefix = false;
if (type is InterfaceType || type is TypedefType) {
- Node target = node.typeName;
- if (node.typeName is Send) {
- final send = node.typeName.asSend();
- Identifier receiver = send.receiver;
- Identifier selector = send.selector;
- Element potentialPrefix =
- currentElement.getLibrary().findLocal(receiver.source);
- if (potentialPrefix != null && potentialPrefix.isPrefix()) {
- // prefix.Class case.
- hasPrefix = true;
- } else {
- // Class.namedContructor case.
- target = receiver;
- // If element is unresolved, mark namedConstructor as unresolved.
- if (treeElements[node] == null) {
- makeUnresolvedPlaceholder(selector);
- }
- }
- }
// TODO(antonm): is there a better way to detect unresolved types?
// Corner case: dart:core type with a prefix.
// Most probably there are some additional problems with
// coreLibPrefix.topLevels.
- Element typeElement = type.element;
- Element dynamicTypeElement = compiler.types.dynamicType.element;
- if (hasPrefix &&
- (identical(typeElement.getLibrary(), coreLibrary) ||
- identical(typeElement, dynamicTypeElement))) {
- makeNullPlaceholder(node.typeName.asSend().receiver);
+ if (!identical(type.element, compiler.types.dynamicType.element)) {
+ makeTypePlaceholder(node.typeName, type);
} else {
- if (hasPrefix) {
- assert(node.typeName is Send);
- Send typeName = node.typeName;
- assert(typeName.receiver is Identifier);
- assert(typeName.selector is Identifier);
- makeNullPlaceholder(typeName.receiver);
- }
- if (!identical(typeElement, dynamicTypeElement)) {
- makeTypePlaceholder(target, type);
- } else {
- if (!isDynamicType(node)) makeUnresolvedPlaceholder(target);
- }
+ if (!isDynamicType(node)) makeUnresolvedPlaceholder(node.typeName);
}
}
- // Trying to differentiate new A.foo() and lib.A cases. In the latter case
- // we don't want to go deeper into typeName.
- if (hasPrefix) {
- // Visit only type arguments, otherwise in case of lib.Class type
- // annotation typeName is Send and we go to visitGetterSend, as a result
- // "Class" is added to member placeholders.
- visit(node.typeArguments);
- } else {
- node.visitChildren(this);
- }
+ // Visit only type arguments, otherwise in case of lib.Class type
+ // annotation typeName is Send and we go to visitGetterSend, as a result
+ // "Class" is added to member placeholders.
+ visit(node.typeArguments);
}
visitVariableDefinitions(VariableDefinitions node) {
« no previous file with comments | « lib/compiler/implementation/dart_backend/backend.dart ('k') | lib/compiler/implementation/dart_backend/renamer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698