| Index: sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (revision 21931)
|
| +++ sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (working copy)
|
| @@ -831,7 +831,7 @@
|
| assert(arguments != null);
|
| bool isUseful = addArguments(node, callee, arguments);
|
| if (hasAnalyzedAll && isUseful) {
|
| - updateArgumentsType(callee);
|
| + enqueueAgain(callee);
|
| }
|
| }
|
|
|
| @@ -846,13 +846,13 @@
|
| types.remove(send);
|
| if (hasAnalyzedAll) updateNonFinalFieldType(callee);
|
| }
|
| - } if (callee.isGetter()) {
|
| + } else if (callee.isGetter()) {
|
| return;
|
| } else {
|
| Map<Node, ArgumentsTypes> types = typeOfArguments[callee];
|
| if (types == null || !types.containsKey(send)) return;
|
| types.remove(send);
|
| - if (hasAnalyzedAll) updateArgumentsType(callee);
|
| + if (hasAnalyzedAll) enqueueAgain(callee);
|
| }
|
| }
|
|
|
| @@ -870,7 +870,7 @@
|
| if (element.name == Compiler.NO_SUCH_METHOD) return;
|
| FunctionSignature signature = element.computeSignature(compiler);
|
|
|
| - if (typeOfArguments[element].isEmpty) {
|
| + if (typeOfArguments[element] == null || typeOfArguments[element].isEmpty) {
|
| signature.forEachParameter((Element parameter) {
|
| typeOf.remove(parameter);
|
| });
|
| @@ -937,6 +937,25 @@
|
| return null;
|
| }
|
|
|
| + bool isTargetFor(TypeMask receiverType, Selector selector, Element element) {
|
| + bool isReceiverDynamic = isDynamicType(receiverType);
|
| + assert(selector.mask == receiverType
|
| + || (selector.mask == null && isReceiverDynamic));
|
| + // TODO(ngeoffray) : The following noSuchMethod handling is a bit
|
| + // convoluted, we should make it easier to know what we are sure
|
| + // we cannot hit.
|
| + if (element.name != selector.name) {
|
| + assert(element.name == Compiler.NO_SUCH_METHOD);
|
| + return isReceiverDynamic
|
| + || (!receiverType.willHit(selector, compiler)
|
| + && receiverType.canHit(
|
| + element, compiler.noSuchMethodSelector, compiler));
|
| + } else {
|
| + return isReceiverDynamic
|
| + || receiverType.canHit(element, selector, compiler);
|
| + }
|
| + }
|
| +
|
| /**
|
| * Registers that [caller] calls an element matching [selector]
|
| * with the given [arguments].
|
| @@ -949,23 +968,21 @@
|
| Selector constraint,
|
| bool inLoop) {
|
| TypeMask result;
|
| - iterateOverElements(selector, (Element element) {
|
| + iterateOverElements(selector.asUntyped, (Element element) {
|
| assert(element.isImplementation);
|
| - // TODO(ngeoffray): Enable unregistering by having a
|
| - // [: TypeMask.appliesTo(element) :] method, that will return
|
| - // whether [: element :] is a potential target for the type.
|
| - if (true) {
|
| + if (isTargetFor(receiverType, selector, element)) {
|
| registerCalledElement(
|
| node, selector, caller, element, arguments,
|
| constraint, inLoop);
|
| +
|
| + if (!selector.isSetter()) {
|
| + TypeMask type = handleIntrisifiedSelector(selector, arguments);
|
| + if (type == null) type = typeOfElementWithSelector(element, selector);
|
| + result = computeLUB(result, type);
|
| + }
|
| } else {
|
| - unregisterCalledElement(node, selector.asUntyped, caller, element);
|
| + unregisterCalledElement(node, selector, caller, element);
|
| }
|
| - if (!selector.isSetter()) {
|
| - TypeMask type = handleIntrisifiedSelector(selector, arguments);
|
| - if (type == null) type = typeOfElementWithSelector(element, selector);
|
| - result = computeLUB(result, type);
|
| - }
|
| return true;
|
| });
|
|
|
| @@ -1060,6 +1077,11 @@
|
| if (isNativeElement(element)) return;
|
| assert(hasAnalyzedAll);
|
|
|
| + if (typeOfFields[element] == null || typeOfFields[element].isEmpty) {
|
| + typeOf.remove(element);
|
| + return;
|
| + }
|
| +
|
| TypeMask fieldType = computeFieldTypeWithConstraints(
|
| element, typeOfFields[element]);
|
|
|
| @@ -1364,6 +1386,9 @@
|
| }
|
|
|
| FunctionElement function = analyzedElement;
|
| + if (inferrer.hasAnalyzedAll) {
|
| + inferrer.updateArgumentsType(function);
|
| + }
|
| FunctionSignature signature = function.computeSignature(compiler);
|
| signature.forEachOptionalParameter((element) {
|
| Node node = element.parseNode(compiler);
|
|
|