| Index: pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| index e9ceabb91234f680440a6c980d05f0c2498899f4..cf2dd76ad8e1762bd66567224352433c45fc8970 100644
|
| --- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| +++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| @@ -124,8 +124,8 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
|
| return functionType;
|
| }
|
|
|
| - TypeMask newTypedSelector(TypeMask receiver, TypeMask mask) {
|
| - return receiver;
|
| + Selector newTypedSelector(TypeMask receiver, Selector selector) {
|
| + return new TypedSelector(receiver, selector, compiler.world);
|
| }
|
|
|
| TypeMask addPhiInput(Local variable,
|
| @@ -152,16 +152,13 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
|
| return phiType;
|
| }
|
|
|
| - bool selectorNeedsUpdate(TypeMask type, TypeMask mask) {
|
| - return type != mask;
|
| + bool selectorNeedsUpdate(TypeMask type, Selector selector) {
|
| + return type != selector.mask;
|
| }
|
|
|
| - TypeMask refineReceiver(Selector selector,
|
| - TypeMask mask,
|
| - TypeMask receiverType,
|
| - bool isConditional) {
|
| - TypeMask newType =
|
| - compiler.world.allFunctions.receiverType(selector, mask);
|
| + TypeMask refineReceiver(Selector selector, TypeMask receiverType,
|
| + bool isConditional) {
|
| + TypeMask newType = compiler.world.allFunctions.receiverType(selector);
|
| return receiverType.intersection(newType, classWorld);
|
| }
|
|
|
| @@ -248,7 +245,6 @@ abstract class InferrerEngine<T, V extends TypeSystem>
|
| */
|
| T registerCalledElement(Spannable node,
|
| Selector selector,
|
| - TypeMask mask,
|
| Element caller,
|
| Element callee,
|
| ArgumentsTypes<T> arguments,
|
| @@ -266,7 +262,6 @@ abstract class InferrerEngine<T, V extends TypeSystem>
|
| */
|
| T registerCalledSelector(ast.Node node,
|
| Selector selector,
|
| - TypeMask mask,
|
| T receiverType,
|
| Element caller,
|
| ArgumentsTypes<T> arguments,
|
| @@ -283,7 +278,6 @@ abstract class InferrerEngine<T, V extends TypeSystem>
|
| */
|
| T registerCalledClosure(ast.Node node,
|
| Selector selector,
|
| - TypeMask mask,
|
| T closure,
|
| Element caller,
|
| ArgumentsTypes<T> arguments,
|
| @@ -307,13 +301,10 @@ abstract class InferrerEngine<T, V extends TypeSystem>
|
|
|
| /**
|
| * Applies [f] to all elements in the universe that match
|
| - * [selector] and [mask]. If [f] returns false, aborts the iteration.
|
| + * [selector]. If [f] returns false, aborts the iteration.
|
| */
|
| - void forEachElementMatching(Selector selector,
|
| - TypeMask mask,
|
| - bool f(Element element)) {
|
| - Iterable<Element> elements =
|
| - compiler.world.allFunctions.filter(selector, mask);
|
| + void forEachElementMatching(Selector selector, bool f(Element element)) {
|
| + Iterable<Element> elements = compiler.world.allFunctions.filter(selector);
|
| for (Element e in elements) {
|
| if (!f(e.implementation)) return;
|
| }
|
| @@ -395,7 +386,7 @@ abstract class InferrerEngine<T, V extends TypeSystem>
|
| }
|
|
|
| void updateSelectorInTree(
|
| - AstElement owner, Spannable node, Selector selector, TypeMask mask) {
|
| + AstElement owner, Spannable node, Selector selector) {
|
| if (node is cps_ir.Node) {
|
| // TODO(lry): update selector for IrInvokeDynamic.
|
| throw "updateSelector for IR node $node";
|
| @@ -404,24 +395,24 @@ abstract class InferrerEngine<T, V extends TypeSystem>
|
| TreeElements elements = owner.resolvedAst.elements;
|
| if (astNode.asSendSet() != null) {
|
| if (selector.isSetter || selector.isIndexSet) {
|
| - elements.setTypeMask(node, mask);
|
| + elements.setSelector(node, selector);
|
| } else if (selector.isGetter || selector.isIndex) {
|
| - elements.setGetterTypeMaskInComplexSendSet(node, mask);
|
| + elements.setGetterSelectorInComplexSendSet(node, selector);
|
| } else {
|
| assert(selector.isOperator);
|
| - elements.setOperatorTypeMaskInComplexSendSet(node, mask);
|
| + elements.setOperatorSelectorInComplexSendSet(node, selector);
|
| }
|
| } else if (astNode.asSend() != null) {
|
| - elements.setTypeMask(node, mask);
|
| + elements.setSelector(node, selector);
|
| } else {
|
| assert(astNode.asForIn() != null);
|
| - if (selector == compiler.iteratorSelector) {
|
| - elements.setIteratorTypeMask(node, mask);
|
| - } else if (selector == compiler.currentSelector) {
|
| - elements.setCurrentTypeMask(node, mask);
|
| + if (selector.asUntyped == compiler.iteratorSelector) {
|
| + elements.setIteratorSelector(node, selector);
|
| + } else if (selector.asUntyped == compiler.currentSelector) {
|
| + elements.setCurrentSelector(node, selector);
|
| } else {
|
| - assert(selector == compiler.moveNextSelector);
|
| - elements.setMoveNextTypeMask(node, mask);
|
| + assert(selector.asUntyped == compiler.moveNextSelector);
|
| + elements.setMoveNextSelector(node, selector);
|
| }
|
| }
|
| }
|
| @@ -581,7 +572,6 @@ class SimpleTypeInferrerVisitor<T>
|
| analyzeSuperConstructorCall(target, arguments);
|
| inferrer.registerCalledElement(node,
|
| null,
|
| - null,
|
| outermostElement,
|
| target.implementation,
|
| arguments,
|
| @@ -751,9 +741,9 @@ class SimpleTypeInferrerVisitor<T>
|
| return compiler.world.isSubclassOf(enclosing, cls);
|
| }
|
|
|
| - void checkIfExposesThis(Selector selector, TypeMask mask) {
|
| + void checkIfExposesThis(Selector selector) {
|
| if (isThisExposed) return;
|
| - inferrer.forEachElementMatching(selector, mask, (element) {
|
| + inferrer.forEachElementMatching(selector, (element) {
|
| if (element.isField) {
|
| if (!selector.isSetter
|
| && isInClassOrSubclass(element)
|
| @@ -797,14 +787,9 @@ class SimpleTypeInferrerVisitor<T>
|
|
|
| Selector getterSelector =
|
| elements.getGetterSelectorInComplexSendSet(node);
|
| - TypeMask getterMask =
|
| - elements.getGetterTypeMaskInComplexSendSet(node);
|
| Selector operatorSelector =
|
| elements.getOperatorSelectorInComplexSendSet(node);
|
| - TypeMask operatorMask =
|
| - elements.getOperatorTypeMaskInComplexSendSet(node);
|
| Selector setterSelector = elements.getSelector(node);
|
| - TypeMask setterMask = elements.getTypeMask(node);
|
|
|
| String op = node.assignmentOperator.source;
|
| bool isIncrementOrDecrement = op == '++' || op == '--';
|
| @@ -842,12 +827,10 @@ class SimpleTypeInferrerVisitor<T>
|
| }
|
| if (!isThisExposed && isCallOnThis) {
|
| checkIfExposesThis(
|
| - setterSelector,
|
| - types.newTypedSelector(receiverType, setterMask));
|
| + types.newTypedSelector(receiverType, setterSelector));
|
| if (getterSelector != null) {
|
| checkIfExposesThis(
|
| - getterSelector,
|
| - types.newTypedSelector(receiverType, getterMask));
|
| + types.newTypedSelector(receiverType, getterSelector));
|
| }
|
| }
|
| }
|
| @@ -856,7 +839,7 @@ class SimpleTypeInferrerVisitor<T>
|
| return internalError(node, "Unexpected index operation");
|
| } else if (op == '=') {
|
| return handlePlainAssignment(
|
| - node, element, setterSelector, setterMask, receiverType, rhsType,
|
| + node, element, setterSelector, receiverType, rhsType,
|
| node.arguments.head);
|
| } else {
|
| // [: foo++ :] or [: foo += 1 :].
|
| @@ -868,37 +851,33 @@ class SimpleTypeInferrerVisitor<T>
|
| newType = types.dynamicType;
|
| } else if (Elements.isStaticOrTopLevelField(element)) {
|
| Element getterElement = elements[node.selector];
|
| - getterType = handleStaticSend(
|
| - node, getterSelector, getterMask, getterElement, null);
|
| + getterType =
|
| + handleStaticSend(node, getterSelector, getterElement, null);
|
| newType = handleDynamicSend(
|
| - node, operatorSelector, operatorMask,
|
| - getterType, operatorArguments);
|
| + node, operatorSelector, getterType, operatorArguments);
|
| handleStaticSend(
|
| - node, setterSelector, setterMask, element,
|
| + node, setterSelector, element,
|
| new ArgumentsTypes<T>([newType], null));
|
| } else if (Elements.isUnresolved(element)
|
| || element.isSetter
|
| || element.isField) {
|
| getterType = handleDynamicSend(
|
| - node, getterSelector, getterMask, receiverType, null);
|
| + node, getterSelector, receiverType, null);
|
| newType = handleDynamicSend(
|
| - node, operatorSelector, operatorMask,
|
| - getterType, operatorArguments);
|
| - handleDynamicSend(node, setterSelector, setterMask, receiverType,
|
| + node, operatorSelector, getterType, operatorArguments);
|
| + handleDynamicSend(node, setterSelector, receiverType,
|
| new ArgumentsTypes<T>([newType], null));
|
| } else if (element.isLocal) {
|
| LocalElement local = element;
|
| getterType = locals.use(local);
|
| newType = handleDynamicSend(
|
| - node, operatorSelector, operatorMask,
|
| - getterType, operatorArguments);
|
| + node, operatorSelector, getterType, operatorArguments);
|
| locals.update(element, newType, node);
|
| } else {
|
| // Bogus SendSet, for example [: myMethod += 42 :].
|
| getterType = types.dynamicType;
|
| newType = handleDynamicSend(
|
| - node, operatorSelector, operatorMask,
|
| - getterType, operatorArguments);
|
| + node, operatorSelector, getterType, operatorArguments);
|
| }
|
|
|
| if (node.isPostfix) {
|
| @@ -916,32 +895,24 @@ class SimpleTypeInferrerVisitor<T>
|
| T indexType,
|
| T rhsType) {
|
| Selector getterSelector =
|
| - elements.getGetterSelectorInComplexSendSet(node);
|
| - TypeMask getterMask =
|
| - elements.getGetterTypeMaskInComplexSendSet(node);
|
| - Selector operatorSelector =
|
| - elements.getOperatorSelectorInComplexSendSet(node);
|
| - TypeMask operatorMask =
|
| - elements.getOperatorTypeMaskInComplexSendSet(node);
|
| - Selector setterSelector = elements.getSelector(node);
|
| - TypeMask setterMask = elements.getTypeMask(node);
|
| + elements.getGetterSelectorInComplexSendSet(node);
|
| + Selector operatorSelector =
|
| + elements.getOperatorSelectorInComplexSendSet(node);
|
| + Selector setterSelector = elements.getSelector(node);
|
|
|
| T getterType = handleDynamicSend(
|
| node,
|
| getterSelector,
|
| - getterMask,
|
| receiverType,
|
| new ArgumentsTypes<T>([indexType], null));
|
| T returnType = handleDynamicSend(
|
| node,
|
| operatorSelector,
|
| - operatorMask,
|
| getterType,
|
| new ArgumentsTypes<T>([rhsType], null));
|
| handleDynamicSend(
|
| node,
|
| setterSelector,
|
| - setterMask,
|
| receiverType,
|
| new ArgumentsTypes<T>([indexType, returnType], null));
|
|
|
| @@ -1154,11 +1125,9 @@ class SimpleTypeInferrerVisitor<T>
|
| /// Handle index set, like `foo[0] = 42`.
|
| T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) {
|
| Selector setterSelector = elements.getSelector(node);
|
| - TypeMask setterMask = elements.getTypeMask(node);
|
| handleDynamicSend(
|
| node,
|
| setterSelector,
|
| - setterMask,
|
| receiverType,
|
| new ArgumentsTypes<T>([indexType, rhsType], null));
|
| return rhsType;
|
| @@ -1211,7 +1180,6 @@ class SimpleTypeInferrerVisitor<T>
|
| T handlePlainAssignment(ast.Node node,
|
| Element element,
|
| Selector setterSelector,
|
| - TypeMask setterMask,
|
| T receiverType,
|
| T rhsType,
|
| ast.Node rhs) {
|
| @@ -1219,15 +1187,14 @@ class SimpleTypeInferrerVisitor<T>
|
| if (Elements.isErroneous(element)) {
|
| // Code will always throw.
|
| } else if (Elements.isStaticOrTopLevelField(element)) {
|
| - handleStaticSend(node, setterSelector, setterMask, element, arguments);
|
| + handleStaticSend(node, setterSelector, element, arguments);
|
| } else if (Elements.isUnresolved(element) || element.isSetter) {
|
| if (analyzedElement.isGenerativeConstructor
|
| && (node.asSendSet() != null)
|
| && (node.asSendSet().receiver != null)
|
| && node.asSendSet().receiver.isThis()) {
|
| Iterable<Element> targets = compiler.world.allFunctions.filter(
|
| - setterSelector,
|
| - types.newTypedSelector(thisType, setterMask));
|
| + types.newTypedSelector(thisType, setterSelector));
|
| // We just recognized a field initialization of the form:
|
| // `this.foo = 42`. If there is only one target, we can update
|
| // its type.
|
| @@ -1239,7 +1206,7 @@ class SimpleTypeInferrerVisitor<T>
|
| }
|
| }
|
| handleDynamicSend(
|
| - node, setterSelector, setterMask, receiverType, arguments);
|
| + node, setterSelector, receiverType, arguments);
|
| } else if (element.isField) {
|
| if (element.isFinal) {
|
| inferrer.recordTypeOfFinalField(
|
| @@ -1252,7 +1219,7 @@ class SimpleTypeInferrerVisitor<T>
|
| inferrer.recordTypeOfNonFinalField(node, element, rhsType);
|
| } else {
|
| handleDynamicSend(
|
| - node, setterSelector, setterMask, receiverType, arguments);
|
| + node, setterSelector, receiverType, arguments);
|
| }
|
| }
|
| } else if (element.isLocal) {
|
| @@ -1267,13 +1234,12 @@ class SimpleTypeInferrerVisitor<T>
|
| ? null
|
| : analyzeArguments(node.arguments);
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| // TODO(herhut): We could do better here if we knew what we
|
| // are calling does not expose this.
|
| isThisExposed = true;
|
| // Ensure we create a node, to make explicit the call to the
|
| // `noSuchMethod` handler.
|
| - return handleDynamicSend(node, selector, mask, superType, arguments);
|
| + return handleDynamicSend(node, selector, superType, arguments);
|
| }
|
|
|
| /// Handle a .call invocation on the values retrieved from the super
|
| @@ -1284,12 +1250,11 @@ class SimpleTypeInferrerVisitor<T>
|
| ast.NodeList arguments) {
|
| ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes);
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| // TODO(herhut): We could do better here if we knew what we
|
| // are calling does not expose this.
|
| isThisExposed = true;
|
| return inferrer.registerCalledClosure(
|
| - node, selector, mask, inferrer.typeOfElement(element),
|
| + node, selector, inferrer.typeOfElement(element),
|
| outermostElement, argumentTypes, sideEffects, inLoop);
|
| }
|
|
|
| @@ -1300,10 +1265,8 @@ class SimpleTypeInferrerVisitor<T>
|
| // TODO(herhut): We could do better here if we knew what we
|
| // are calling does not expose this.
|
| isThisExposed = true;
|
| - Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| return handleStaticSend(
|
| - node, selector, mask, method, arguments);
|
| + node, elements.getSelector(node), method, arguments);
|
| }
|
|
|
| /// Handle access to a super field or getter [element].
|
| @@ -1312,10 +1275,8 @@ class SimpleTypeInferrerVisitor<T>
|
| // TODO(herhut): We could do better here if we knew what we
|
| // are calling does not expose this.
|
| isThisExposed = true;
|
| - Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| return handleStaticSend(
|
| - node, selector, mask, element, null);
|
| + node, elements.getSelector(node), element, null);
|
| }
|
|
|
| /// Handle super constructor invocation.
|
| @@ -1326,10 +1287,8 @@ class SimpleTypeInferrerVisitor<T>
|
| assert(visitingInitializers);
|
| seenSuperConstructorCall = true;
|
| analyzeSuperConstructorCall(element, arguments);
|
| - Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| return handleStaticSend(
|
| - node, selector, mask, element, arguments);
|
| + node, elements.getSelector(node), element, arguments);
|
| }
|
|
|
| @override
|
| @@ -1537,11 +1496,7 @@ class SimpleTypeInferrerVisitor<T>
|
| ArgumentsTypes<T> arguments =
|
| new ArgumentsTypes<T>(<T>[expression.accept(this)], null);
|
| return handleStaticSend(
|
| - node,
|
| - new Selector.fromElement(element),
|
| - null,
|
| - element,
|
| - arguments);
|
| + node, new Selector.fromElement(element), element, arguments);
|
| }
|
|
|
| @override
|
| @@ -1587,16 +1542,14 @@ class SimpleTypeInferrerVisitor<T>
|
| return handleForeignSend(node, element);
|
| }
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| // In erroneous code the number of arguments in the selector might not
|
| // match the function element.
|
| // TODO(polux): return nonNullEmpty and check it doesn't break anything
|
| - if (!selector.applies(element, compiler.world) ||
|
| - (mask != null && !mask.canHit(element, selector, compiler.world))) {
|
| + if (!selector.applies(element, compiler.world)) {
|
| return types.dynamicType;
|
| }
|
|
|
| - T returnType = handleStaticSend(node, selector, mask, element, arguments);
|
| + T returnType = handleStaticSend(node, selector, element, arguments);
|
| if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
|
| return inferrer.concreteTypes.putIfAbsent(
|
| node, () => types.allocateList(
|
| @@ -1638,10 +1591,9 @@ class SimpleTypeInferrerVisitor<T>
|
| T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) {
|
| ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| - handleStaticSend(node, selector, mask, element, arguments);
|
| + handleStaticSend(node, selector, element, arguments);
|
| return inferrer.registerCalledClosure(
|
| - node, selector, mask, inferrer.typeOfElement(element),
|
| + node, selector, inferrer.typeOfElement(element),
|
| outermostElement, arguments, sideEffects, inLoop);
|
| }
|
|
|
| @@ -1652,8 +1604,7 @@ class SimpleTypeInferrerVisitor<T>
|
| }
|
| ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| - return handleStaticSend(node, selector, mask, function, arguments);
|
| + return handleStaticSend(node, selector, function, arguments);
|
| }
|
|
|
| /// Handle an static invocation of an unresolved target or with incompatible
|
| @@ -1776,9 +1727,8 @@ class SimpleTypeInferrerVisitor<T>
|
| T handleForeignSend(ast.Send node, Element element) {
|
| ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| String name = element.name;
|
| - handleStaticSend(node, selector, mask, element, arguments);
|
| + handleStaticSend(node, selector, element, arguments);
|
| if (name == 'JS' || name == 'JS_EMBEDDED_GLOBAL' || name == 'JS_BUILTIN') {
|
| native.NativeBehavior nativeBehavior =
|
| compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
|
| @@ -1828,23 +1778,17 @@ class SimpleTypeInferrerVisitor<T>
|
|
|
| /// Read a static or top level field.
|
| T handleStaticFieldGet(ast.Send node, FieldElement field) {
|
| - Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| - return handleStaticSend(node, selector, mask, field, null);
|
| + return handleStaticSend(node, elements.getSelector(node), field, null);
|
| }
|
|
|
| /// Invoke a static or top level getter.
|
| T handleStaticGetterGet(ast.Send node, MethodElement getter) {
|
| - Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| - return handleStaticSend(node, selector, mask, getter, null);
|
| + return handleStaticSend(node, elements.getSelector(node), getter, null);
|
| }
|
|
|
| /// Closurize a static or top level function.
|
| T handleStaticFunctionGet(ast.Send node, MethodElement function) {
|
| - Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| - return handleStaticSend(node, selector, mask, function, null);
|
| + return handleStaticSend(node, elements.getSelector(node), function, null);
|
| }
|
|
|
| @override
|
| @@ -1973,9 +1917,8 @@ class SimpleTypeInferrerVisitor<T>
|
| T handleCallInvoke(ast.Send node, T closure) {
|
| ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| return inferrer.registerCalledClosure(
|
| - node, selector, mask, closure, outermostElement, arguments,
|
| + node, selector, closure, outermostElement, arguments,
|
| sideEffects, inLoop);
|
| }
|
|
|
| @@ -2027,12 +1970,11 @@ class SimpleTypeInferrerVisitor<T>
|
| _) {
|
| ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| // This only works for function statements. We need a
|
| // more sophisticated type system with function types to support
|
| // more.
|
| return inferrer.registerCalledElement(
|
| - node, selector, mask, outermostElement, function, argumentTypes,
|
| + node, selector, outermostElement, function, argumentTypes,
|
| sideEffects, inLoop);
|
| }
|
|
|
| @@ -2049,7 +1991,6 @@ class SimpleTypeInferrerVisitor<T>
|
|
|
| T handleStaticSend(ast.Node node,
|
| Selector selector,
|
| - TypeMask mask,
|
| Element element,
|
| ArgumentsTypes arguments) {
|
| assert(!element.isFactoryConstructor ||
|
| @@ -2060,21 +2001,20 @@ class SimpleTypeInferrerVisitor<T>
|
| // need to pay attention if the constructor is pointing to an erroneous
|
| // element.
|
| return inferrer.registerCalledElement(
|
| - node, selector, mask, outermostElement, element, arguments,
|
| + node, selector, outermostElement, element, arguments,
|
| sideEffects, inLoop);
|
| }
|
|
|
| T handleDynamicSend(ast.Node node,
|
| Selector selector,
|
| - TypeMask mask,
|
| T receiverType,
|
| ArgumentsTypes arguments) {
|
| assert(receiverType != null);
|
| - if (types.selectorNeedsUpdate(receiverType, mask)) {
|
| - mask = receiverType == types.dynamicType
|
| - ? null
|
| - : types.newTypedSelector(receiverType, mask);
|
| - inferrer.updateSelectorInTree(analyzedElement, node, selector, mask);
|
| + if (types.selectorNeedsUpdate(receiverType, selector)) {
|
| + selector = (receiverType == types.dynamicType)
|
| + ? selector.asUntyped
|
| + : types.newTypedSelector(receiverType, selector);
|
| + inferrer.updateSelectorInTree(analyzedElement, node, selector);
|
| }
|
|
|
| // If the receiver of the call is a local, we may know more about
|
| @@ -2086,15 +2026,15 @@ class SimpleTypeInferrerVisitor<T>
|
| if (receiver != null) {
|
| Element element = elements[receiver];
|
| if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
|
| - T refinedType = types.refineReceiver(
|
| - selector, mask, receiverType, send.isConditional);
|
| + T refinedType = types.refineReceiver(selector, receiverType,
|
| + send.isConditional);
|
| locals.update(element, refinedType, node);
|
| }
|
| }
|
| }
|
|
|
| return inferrer.registerCalledSelector(
|
| - node, selector, mask, receiverType, outermostElement, arguments,
|
| + node, selector, receiverType, outermostElement, arguments,
|
| sideEffects, inLoop);
|
| }
|
|
|
| @@ -2122,16 +2062,15 @@ class SimpleTypeInferrerVisitor<T>
|
| }
|
|
|
| Selector selector = elements.getSelector(node);
|
| - TypeMask mask = elements.getTypeMask(node);
|
| if (!isThisExposed && isCallOnThis) {
|
| - checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask));
|
| + checkIfExposesThis(types.newTypedSelector(receiverType, selector));
|
| }
|
|
|
| ArgumentsTypes arguments = node.isPropertyAccess
|
| ? null
|
| : analyzeArguments(node.arguments);
|
| - if (selector.name == '==' ||
|
| - selector.name == '!=') {
|
| + if (selector.name == '=='
|
| + || selector.name == '!=') {
|
| if (types.isNull(receiverType)) {
|
| potentiallyAddNullCheck(node, node.arguments.head);
|
| return types.boolType;
|
| @@ -2140,7 +2079,7 @@ class SimpleTypeInferrerVisitor<T>
|
| return types.boolType;
|
| }
|
| }
|
| - return handleDynamicSend(node, selector, mask, receiverType, arguments);
|
| + return handleDynamicSend(node, selector, receiverType, arguments);
|
| }
|
|
|
| void recordReturnType(T type) {
|
| @@ -2177,7 +2116,6 @@ class SimpleTypeInferrerVisitor<T>
|
| ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
|
| return inferrer.registerCalledElement(node,
|
| null,
|
| - null,
|
| outermostElement,
|
| element,
|
| arguments,
|
| @@ -2210,18 +2148,12 @@ class SimpleTypeInferrerVisitor<T>
|
| return null;
|
| }
|
|
|
| - T handleForInLoop(ast.ForIn node,
|
| - T iteratorType,
|
| - Selector currentSelector,
|
| - TypeMask currentMask,
|
| - Selector moveNextSelector,
|
| - TypeMask moveNextMask) {
|
| - handleDynamicSend(
|
| - node, moveNextSelector, moveNextMask, iteratorType,
|
| - new ArgumentsTypes<T>.empty());
|
| - T currentType = handleDynamicSend(
|
| - node, currentSelector, currentMask, iteratorType,
|
| - new ArgumentsTypes<T>.empty());
|
| + T handleForInLoop(ast.ForIn node, T iteratorType, Selector currentSelector,
|
| + Selector moveNextSelector) {
|
| + handleDynamicSend(node, moveNextSelector, iteratorType,
|
| + new ArgumentsTypes<T>.empty());
|
| + T currentType = handleDynamicSend(node, currentSelector, iteratorType,
|
| + new ArgumentsTypes<T>.empty());
|
|
|
| if (node.expression.isThis()) {
|
| // Any reasonable implementation of an iterator would expose
|
| @@ -2232,7 +2164,6 @@ class SimpleTypeInferrerVisitor<T>
|
| ast.Node identifier = node.declaredIdentifier;
|
| Element element = elements.getForInVariable(node);
|
| Selector selector = elements.getSelector(identifier);
|
| - TypeMask mask = elements.getTypeMask(identifier);
|
|
|
| T receiverType;
|
| if (element != null && element.isInstanceMember) {
|
| @@ -2241,7 +2172,7 @@ class SimpleTypeInferrerVisitor<T>
|
| receiverType = types.dynamicType;
|
| }
|
|
|
| - handlePlainAssignment(identifier, element, selector, mask,
|
| + handlePlainAssignment(identifier, element, selector,
|
| receiverType, currentType,
|
| node.expression);
|
| return handleLoop(node, () {
|
| @@ -2253,36 +2184,30 @@ class SimpleTypeInferrerVisitor<T>
|
| T expressionType = visit(node.expression);
|
|
|
| Selector currentSelector = elements.getCurrentSelector(node);
|
| - TypeMask currentMask = elements.getCurrentTypeMask(node);
|
| Selector moveNextSelector = elements.getMoveNextSelector(node);
|
| - TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
|
|
|
| js.JavaScriptBackend backend = compiler.backend;
|
| Element ctor = backend.getStreamIteratorConstructor();
|
|
|
| /// Synthesize a call to the [StreamIterator] constructor.
|
| - T iteratorType = handleStaticSend(node, null, null, ctor,
|
| + T iteratorType = handleStaticSend(node, null, ctor,
|
| new ArgumentsTypes<T>([expressionType],
|
| null));
|
|
|
| - return handleForInLoop(node, iteratorType, currentSelector, currentMask,
|
| - moveNextSelector, moveNextMask);
|
| + return handleForInLoop(node, iteratorType, currentSelector,
|
| + moveNextSelector);
|
| }
|
|
|
| T visitSyncForIn(ast.SyncForIn node) {
|
| T expressionType = visit(node.expression);
|
| Selector iteratorSelector = elements.getIteratorSelector(node);
|
| - TypeMask iteratorMask = elements.getIteratorTypeMask(node);
|
| Selector currentSelector = elements.getCurrentSelector(node);
|
| - TypeMask currentMask = elements.getCurrentTypeMask(node);
|
| Selector moveNextSelector = elements.getMoveNextSelector(node);
|
| - TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
|
|
|
| - T iteratorType = handleDynamicSend(
|
| - node, iteratorSelector, iteratorMask, expressionType,
|
| - new ArgumentsTypes<T>.empty());
|
| + T iteratorType = handleDynamicSend(node, iteratorSelector, expressionType,
|
| + new ArgumentsTypes<T>.empty());
|
|
|
| - return handleForInLoop(node, iteratorType, currentSelector, currentMask,
|
| - moveNextSelector, moveNextMask);
|
| + return handleForInLoop(node, iteratorType, currentSelector,
|
| + moveNextSelector);
|
| }
|
| }
|
|
|