| 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 ed986ed2d190767c86265e5430907b22e3824358..06029b3f1cca28c15600e1841047b1d92d8b5024 100644
|
| --- a/dart/sdk/lib/_internal/compiler/implementation/resolution/members.dart
|
| +++ b/dart/sdk/lib/_internal/compiler/implementation/resolution/members.dart
|
| @@ -5,6 +5,12 @@
|
| part of resolution;
|
|
|
| abstract class TreeElements {
|
| + Element get currentElement;
|
| + Set<Node> get superUses;
|
| +
|
| + /// A set of additional dependencies. See [registerDependency] below.
|
| + Set<Element> get otherDependencies;
|
| +
|
| Element operator[](Node node);
|
| Selector getSelector(Send send);
|
| Selector getGetterSelectorInComplexSendSet(SendSet node);
|
| @@ -14,7 +20,10 @@ abstract class TreeElements {
|
| Selector getCurrentSelector(ForIn node);
|
| DartType getType(Node node);
|
| bool isParameterChecked(Element element);
|
| - Set<Node> get superUses;
|
| +
|
| + /// Register additional dependencies required by [currentElement].
|
| + /// For example, elements that are used by a backend.
|
| + void registerDependency(Element element);
|
| }
|
|
|
| class TreeElementMapping implements TreeElements {
|
| @@ -22,8 +31,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> otherDependencies = new LinkedHashSet<Element>();
|
| + final int hashCode = ++hashCodeCounter;
|
| + static int hashCodeCounter = 0;
|
|
|
| TreeElementMapping(this.currentElement);
|
|
|
| @@ -118,6 +130,12 @@ class TreeElementMapping implements TreeElements {
|
| bool isParameterChecked(Element element) {
|
| return checkedParameters.contains(element);
|
| }
|
| +
|
| + void registerDependency(Element element) {
|
| + otherDependencies.add(element);
|
| + }
|
| +
|
| + String toString() => 'TreeElementMapping($currentElement)';
|
| }
|
|
|
| class ResolverTask extends CompilerTask {
|
| @@ -444,7 +462,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);
|
| }
|
| }
|
|
|
| @@ -1542,7 +1560,9 @@ class TypeResolver {
|
| }
|
| } else if (element.isTypeVariable()) {
|
| if (enclosingElement.isInStaticMember()) {
|
| - compiler.backend.registerThrowRuntimeError();
|
| + compiler.backend.registerThrowRuntimeError(
|
| + // TODO(ahe): Get the TreeElements for the current element.
|
| + compiler.globalDependencies);
|
| compiler.reportWarning(node,
|
| MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
|
| {'typeVariableName': node}));
|
| @@ -1733,7 +1753,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.
|
| @@ -1756,7 +1776,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;
|
| }
|
| @@ -1942,7 +1962,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
|
| scope = oldScope;
|
| enclosingElement = previousEnclosingElement;
|
|
|
| - world.registerInstantiatedClass(compiler.functionClass);
|
| + world.registerInstantiatedClass(compiler.functionClass, mapping);
|
| }
|
|
|
| visitIf(If node) {
|
| @@ -2020,7 +2040,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;
|
| @@ -2038,7 +2058,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].
|
| @@ -2057,7 +2077,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});
|
| @@ -2172,13 +2192,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);
|
| }
|
| }
|
|
|
| @@ -2190,9 +2210,9 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
|
| DartType type = resolveTypeTest(node.arguments.head);
|
| if (type != null) {
|
| if (operatorString == 'as') {
|
| - compiler.enqueuer.resolution.registerAsCheck(type);
|
| + compiler.enqueuer.resolution.registerAsCheck(type, mapping);
|
| } else {
|
| - compiler.enqueuer.resolution.registerIsCheck(type);
|
| + compiler.enqueuer.resolution.registerIsCheck(type, mapping);
|
| }
|
| }
|
| resolvedArguments = true;
|
| @@ -2246,13 +2266,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,
|
| @@ -2283,19 +2303,19 @@ 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);
|
| }
|
| }
|
|
|
| @@ -2368,27 +2388,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);
|
| }
|
|
|
| @@ -2444,14 +2464,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);
|
| }
|
|
|
| @@ -2493,7 +2513,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);
|
| @@ -2505,7 +2525,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
|
| @@ -2514,9 +2534,9 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
|
| ClassElement cls = constructor.getEnclosingClass();
|
| // [cls] might be the implementation element and only declaration elements
|
| // may be registered.
|
| - world.registerInstantiatedType(mapping.getType(node));
|
| + world.registerInstantiatedType(mapping.getType(node), mapping);
|
| if (cls.isAbstract(compiler)) {
|
| - compiler.backend.registerAbstractClassInstantiation();
|
| + compiler.backend.registerAbstractClassInstantiation(mapping);
|
| }
|
| // [cls] might be the declaration element and we want to include injected
|
| // members.
|
| @@ -2575,7 +2595,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) {
|
| @@ -2616,7 +2636,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
|
| } else {
|
| listType = compiler.listClass.rawType;
|
| }
|
| - world.registerInstantiatedType(listType);
|
| + world.registerInstantiatedType(listType, mapping);
|
| visit(node.elements);
|
| }
|
|
|
| @@ -2625,8 +2645,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);
|
| }
|
|
|
| @@ -2771,9 +2791,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);
|
| }
|
| @@ -2854,7 +2874,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) {
|
| @@ -2878,7 +2898,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) {
|
| @@ -2891,7 +2911,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
|
| @@ -3436,7 +3456,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;
|
| }
|
|
|
| @@ -3675,9 +3696,9 @@ class ConstructorResolver extends CommonResolverVisitor<Element> {
|
| SourceString targetName, MessageKind kind,
|
| Map arguments) {
|
| if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
|
| - compiler.backend.registerThrowNoSuchMethod();
|
| + compiler.backend.registerThrowNoSuchMethod(resolver.mapping);
|
| } else {
|
| - compiler.backend.registerThrowRuntimeError();
|
| + compiler.backend.registerThrowRuntimeError(resolver.mapping);
|
| }
|
| if (inConstContext) {
|
| error(diagnosticNode, kind, arguments);
|
|
|