Index: dart/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
diff --git a/dart/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/dart/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
index 1ff6f484cba8314292db2f3b4251514eb9d722a9..db43fd22fa851283074e9fd74653798a0609ccc6 100644 |
--- a/dart/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
+++ b/dart/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
@@ -5,6 +5,10 @@ |
part of resolution; |
abstract class TreeElements { |
+ Element get currentElement; |
+ Set<Node> get superUses; |
+ Set<Element> get backendDependencies; |
+ |
Element operator[](Node node); |
Selector getSelector(Send send); |
Selector getGetterSelectorInComplexSendSet(SendSet node); |
@@ -14,7 +18,7 @@ abstract class TreeElements { |
Selector getCurrentSelector(ForIn node); |
DartType getType(Node node); |
bool isParameterChecked(Element element); |
- Set<Node> get superUses; |
+ void registerBackendDependency(Element element); |
} |
class TreeElementMapping implements TreeElements { |
@@ -22,8 +26,11 @@ class TreeElementMapping implements TreeElements { |
final Map<Spannable, Selector> selectors = |
new LinkedHashMap<Spannable, Selector>(); |
final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>(); |
- final Set<Element> checkedParameters = new Set<Element>(); |
- final Set<Node> superUses = new Set<Node>(); |
+ final Set<Element> checkedParameters = new LinkedHashSet<Element>(); |
+ final Set<Node> superUses = new LinkedHashSet<Node>(); |
+ final Set<Element> backendDependencies = new LinkedHashSet<Element>(); |
+ final int hashCode = ++hashCodeCounter; |
+ static int hashCodeCounter = 0; |
TreeElementMapping(this.currentElement); |
@@ -118,6 +125,12 @@ class TreeElementMapping implements TreeElements { |
bool isParameterChecked(Element element) { |
return checkedParameters.contains(element); |
} |
+ |
+ void registerBackendDependency(Element element) { |
+ backendDependencies.add(element); |
+ } |
+ |
+ String toString() => 'TreeElementMapping($currentElement)'; |
} |
class ResolverTask extends CompilerTask { |
@@ -440,7 +453,7 @@ class ResolverTask extends CompilerTask { |
if (tree.asSendSet() != null) { |
// TODO(ngeoffray): We could do better here by using the |
// constant handler to figure out if it's a lazy field or not. |
- compiler.backend.registerLazyField(); |
+ compiler.backend.registerLazyField(visitor.mapping); |
} |
} |
@@ -1538,7 +1551,7 @@ class TypeResolver { |
} |
} else if (element.isTypeVariable()) { |
if (enclosingElement.isInStaticMember()) { |
- compiler.backend.registerThrowRuntimeError(); |
+ compiler.backend.registerThrowRuntimeError(mapping); |
compiler.reportWarning(node, |
MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( |
{'typeVariableName': node})); |
@@ -1729,7 +1742,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
element = warnAndCreateErroneousElement(node, node.source, |
MessageKind.CANNOT_RESOLVE, |
{'name': node}); |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} |
} else if (element.isErroneous()) { |
// Use the erroneous element. |
@@ -1752,7 +1765,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
DartType type = resolveTypeAnnotation(node); |
if (type != null) { |
if (inCheckContext) { |
- compiler.enqueuer.resolution.registerIsCheck(type); |
+ compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
} |
return type.element; |
} |
@@ -1938,7 +1951,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
scope = oldScope; |
enclosingElement = previousEnclosingElement; |
- world.registerInstantiatedClass(compiler.functionClass); |
+ world.registerInstantiatedClass(compiler.functionClass, mapping); |
} |
visitIf(If node) { |
@@ -2016,7 +2029,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
// call [:super.noSuchMethod:] that does a |
// [:InvocationMirror.invokeOn:]. |
world.registerDynamicInvocation(selector.name, selector); |
- compiler.backend.registerSuperNoSuchMethod(); |
+ compiler.backend.registerSuperNoSuchMethod(mapping); |
} |
} else if (Elements.isUnresolved(resolvedReceiver)) { |
return null; |
@@ -2034,7 +2047,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
target = receiverClass.lookupLocalMember(name); |
if (target == null || target.isInstanceMember()) { |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
// TODO(johnniwinther): With the simplified [TreeElements] invariant, |
// try to resolve injected elements if [currentClass] is in the patch |
// library of [receiverClass]. |
@@ -2053,7 +2066,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
PrefixElement prefix = resolvedReceiver; |
target = prefix.lookupLocalMember(name); |
if (Elements.isUnresolved(target)) { |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
return warnAndCreateErroneousElement( |
node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
{'libraryName': prefix.name, 'memberName': name}); |
@@ -2168,13 +2181,13 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
AbstractFieldElement field = target; |
target = field.getter; |
if (target == null && !inInstanceContext) { |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
target = |
warnAndCreateErroneousElement(node.selector, field.name, |
MessageKind.CANNOT_RESOLVE_GETTER); |
} |
} else if (target.impliesType() && !sendIsMemberAccess) { |
- compiler.backend.registerTypeLiteral(); |
+ compiler.backend.registerTypeLiteral(mapping); |
} |
} |
@@ -2188,7 +2201,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
if (operatorString == 'as') { |
compiler.enqueuer.resolution.registerAsCheck(type); |
} else { |
- compiler.enqueuer.resolution.registerIsCheck(type); |
+ compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
} |
} |
resolvedArguments = true; |
@@ -2242,13 +2255,13 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
registerSend(selector, target); |
if (node.isPropertyAccess) { |
// It might be the closurization of a method. |
- world.registerInstantiatedClass(compiler.functionClass); |
+ world.registerInstantiatedClass(compiler.functionClass, mapping); |
} |
return node.isPropertyAccess ? target : null; |
} |
void warnArgumentMismatch(Send node, Element target) { |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
// TODO(karlklose): we can be more precise about the reason of the |
// mismatch. |
warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, |
@@ -2279,26 +2292,26 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
if (setter == null && !inInstanceContext) { |
setter = warnAndCreateErroneousElement( |
node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER); |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} |
if (isComplex && getter == null && !inInstanceContext) { |
getter = warnAndCreateErroneousElement( |
node.selector, field.name, MessageKind.CANNOT_RESOLVE_GETTER); |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} |
} else if (target.impliesType()) { |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} else if (target.modifiers.isFinal() || target.modifiers.isConst()) { |
setter = warnAndCreateErroneousElement( |
node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER); |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} else if (isComplex && target.name == const SourceString('[]=')) { |
getter = target.getEnclosingClass().lookupMember( |
const SourceString('[]')); |
if (getter == null) { |
getter = warnAndCreateErroneousElement( |
node, setter.name, MessageKind.CANNOT_RESOLVE_INDEX); |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} |
} |
} |
@@ -2363,27 +2376,27 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
visitLiteralInt(LiteralInt node) { |
- world.registerInstantiatedClass(compiler.intClass); |
+ world.registerInstantiatedClass(compiler.intClass, mapping); |
} |
visitLiteralDouble(LiteralDouble node) { |
- world.registerInstantiatedClass(compiler.doubleClass); |
+ world.registerInstantiatedClass(compiler.doubleClass, mapping); |
} |
visitLiteralBool(LiteralBool node) { |
- world.registerInstantiatedClass(compiler.boolClass); |
+ world.registerInstantiatedClass(compiler.boolClass, mapping); |
} |
visitLiteralString(LiteralString node) { |
- world.registerInstantiatedClass(compiler.stringClass); |
+ world.registerInstantiatedClass(compiler.stringClass, mapping); |
} |
visitLiteralNull(LiteralNull node) { |
- world.registerInstantiatedClass(compiler.nullClass); |
+ world.registerInstantiatedClass(compiler.nullClass, mapping); |
} |
visitStringJuxtaposition(StringJuxtaposition node) { |
- world.registerInstantiatedClass(compiler.stringClass); |
+ world.registerInstantiatedClass(compiler.stringClass, mapping); |
node.visitChildren(this); |
} |
@@ -2439,14 +2452,14 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
world.registerStaticUse(redirectionTarget); |
world.registerInstantiatedClass( |
- redirectionTarget.enclosingElement.declaration); |
+ redirectionTarget.enclosingElement.declaration, mapping); |
} |
visitThrow(Throw node) { |
if (!inCatchBlock && node.expression == null) { |
error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
} |
- compiler.backend.registerThrow(); |
+ compiler.backend.registerThrow(mapping); |
visit(node.expression); |
} |
@@ -2488,7 +2501,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
Selector callSelector = mapping.getSelector(node.send); |
if (!callSelector.applies(constructor, compiler)) { |
warnArgumentMismatch(node.send, constructor); |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} |
compiler.withCurrentElement(constructor, () { |
FunctionExpression tree = constructor.parseNode(compiler); |
@@ -2500,7 +2513,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
// TODO(ngeoffray): Remove once we remove such support. |
world.registerStaticUse(constructor.declaration); |
world.registerInstantiatedClass( |
- constructor.getEnclosingClass().declaration); |
+ constructor.getEnclosingClass().declaration, mapping); |
constructor = constructor.defaultImplementation; |
} |
// [constructor.defaultImplementation] might be the implementation element |
@@ -2511,7 +2524,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
// may be registered. |
world.registerInstantiatedType(mapping.getType(node)); |
if (cls.isAbstract(compiler)) { |
- compiler.backend.registerAbstractClassInstantiation(); |
+ compiler.backend.registerAbstractClassInstantiation(mapping); |
} |
// [cls] might be the declaration element and we want to include injected |
// members. |
@@ -2570,7 +2583,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
onFailure: report, whenResolved: useType); |
if (type == null) return null; |
if (inCheckContext) { |
- compiler.enqueuer.resolution.registerIsCheck(type); |
+ compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
} |
if (typeRequired || inCheckContext) { |
if (type is InterfaceType) { |
@@ -2590,7 +2603,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
visitLiteralList(LiteralList node) { |
- world.registerInstantiatedClass(compiler.listClass); |
+ world.registerInstantiatedClass(compiler.listClass, mapping); |
NodeList arguments = node.typeArguments; |
if (arguments != null) { |
Link<Node> nodes = arguments.nodes; |
@@ -2612,8 +2625,8 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
visitStringInterpolation(StringInterpolation node) { |
- world.registerInstantiatedClass(compiler.stringClass); |
- compiler.backend.registerStringInterpolation(); |
+ world.registerInstantiatedClass(compiler.stringClass, mapping); |
+ compiler.backend.registerStringInterpolation(mapping); |
node.visitChildren(this); |
} |
@@ -2758,9 +2771,9 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
visitLiteralMap(LiteralMap node) { |
- world.registerInstantiatedClass(compiler.mapClass); |
+ world.registerInstantiatedClass(compiler.mapClass, mapping); |
if (node.isConst()) { |
- compiler.backend.registerConstantMap(); |
+ compiler.backend.registerConstantMap(mapping); |
} |
node.visitChildren(this); |
} |
@@ -2841,7 +2854,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
}); |
// TODO(ngeoffray): We should check here instead of the SSA backend if |
// there might be an error. |
- compiler.backend.registerFallThroughError(); |
+ compiler.backend.registerFallThroughError(mapping); |
} |
visitSwitchCase(SwitchCase node) { |
@@ -2865,7 +2878,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
} |
visitCatchBlock(CatchBlock node) { |
- compiler.backend.registerCatchStatement(); |
+ compiler.backend.registerCatchStatement(mapping); |
// Check that if catch part is present, then |
// it has one or two formal parameters. |
if (node.formals != null) { |
@@ -2878,7 +2891,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
} |
} |
- compiler.backend.registerStackTraceInCatch(); |
+ compiler.backend.registerStackTraceInCatch(mapping); |
} |
// Check that the formals aren't optional and that they have no |
@@ -3423,7 +3436,8 @@ class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { |
SourceString visitIdentifier(Identifier node) { |
// The variable is initialized to null. |
- resolver.world.registerInstantiatedClass(compiler.nullClass); |
+ resolver.world.registerInstantiatedClass(compiler.nullClass, |
+ resolver.mapping); |
return node.source; |
} |
@@ -3662,9 +3676,9 @@ class ConstructorResolver extends CommonResolverVisitor<Element> { |
SourceString targetName, MessageKind kind, |
Map arguments) { |
if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
- compiler.backend.registerThrowNoSuchMethod(); |
+ compiler.backend.registerThrowNoSuchMethod(mapping); |
} else { |
- compiler.backend.registerThrowRuntimeError(); |
+ compiler.backend.registerThrowRuntimeError(mapping); |
} |
if (inConstContext) { |
error(diagnosticNode, kind, arguments); |