| 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 ebda6b57b47e04bca3d9e24dc76adb16b3f89d51..2de3174c7a14e9d67c40ca8c37a0aaa860f63d7c 100644
|
| --- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| +++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
|
| @@ -1230,8 +1230,13 @@ class SimpleTypeInferrerVisitor<T>
|
| }
|
|
|
| T visitStaticSend(ast.Send node) {
|
| - Element element = elements[node];
|
| assert(!elements.isAssert(node));
|
| + Element element = elements[node];
|
| + return handleConstructorSend(node, element);
|
| + }
|
| +
|
| + /// Handle constructor invocation of [element].
|
| + T handleConstructorSend(ast.Send node, ConstructorElement element) {
|
| ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| if (visitingInitializers) {
|
| if (ast.Initializers.isConstructorRedirect(node)) {
|
| @@ -1254,13 +1259,15 @@ class SimpleTypeInferrerVisitor<T>
|
| }
|
| }
|
| if (element.isForeign(compiler.backend)) {
|
| - return handleForeignSend(node);
|
| + return handleForeignSend(node, element);
|
| }
|
| Selector selector = elements.getSelector(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)) return types.dynamicType;
|
| + if (!selector.applies(element, compiler.world)) {
|
| + return types.dynamicType;
|
| + }
|
|
|
| T returnType = handleStaticSend(node, selector, element, arguments);
|
| if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
|
| @@ -1291,21 +1298,137 @@ class SimpleTypeInferrerVisitor<T>
|
| node, () => types.allocateList(
|
| types.nonNullExact(constructor.enclosingClass), node,
|
| outermostElement, elementType, length));
|
| - } else if (element.isFunction || element.isConstructor) {
|
| - return returnType;
|
| } else {
|
| - assert(element.isField || element.isGetter);
|
| - return inferrer.registerCalledClosure(
|
| - node, selector, inferrer.typeOfElement(element),
|
| - outermostElement, arguments, sideEffects, inLoop);
|
| + return returnType;
|
| }
|
| }
|
|
|
| - T handleForeignSend(ast.Send node) {
|
| + T handleNewExpression(ast.NewExpression node) {
|
| + return visitStaticSend(node.send);
|
| + }
|
| +
|
| + /// Handle invocation of a top level or static field or getter [element].
|
| + T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) {
|
| ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| Selector selector = elements.getSelector(node);
|
| - String name = selector.name;
|
| - handleStaticSend(node, selector, elements[node], arguments);
|
| + handleStaticSend(node, selector, element, arguments);
|
| + return inferrer.registerCalledClosure(
|
| + node, selector, inferrer.typeOfElement(element),
|
| + outermostElement, arguments, sideEffects, inLoop);
|
| + }
|
| +
|
| + /// Handle invocation of a top level or static [function].
|
| + T handleStaticFunctionInvoke(ast.Send node, MethodElement function) {
|
| + if (function.isForeign(compiler.backend)) {
|
| + return handleForeignSend(node, function);
|
| + }
|
| + ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| + Selector selector = elements.getSelector(node);
|
| + return handleStaticSend(node, selector, function, arguments);
|
| + }
|
| +
|
| + /// Handle an static invocation of an unresolved target or with incompatible
|
| + /// arguments to a resolved target.
|
| + T handleInvalidStaticInvoke(ast.Send node) {
|
| + analyzeArguments(node.arguments);
|
| + return types.dynamicType;
|
| + }
|
| +
|
| + @override
|
| + T visitStaticFieldInvoke(
|
| + ast.Send node,
|
| + FieldElement field,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleStaticFieldOrGetterInvoke(node, field);
|
| + }
|
| +
|
| + @override
|
| + T visitStaticFunctionInvoke(
|
| + ast.Send node,
|
| + MethodElement function,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleStaticFunctionInvoke(node, function);
|
| + }
|
| +
|
| + @override
|
| + T visitStaticFunctionIncompatibleInvoke(
|
| + ast.Send node,
|
| + MethodElement function,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleInvalidStaticInvoke(node);
|
| + }
|
| +
|
| + @override
|
| + T visitStaticGetterInvoke(
|
| + ast.Send node,
|
| + FunctionElement getter,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleStaticFieldOrGetterInvoke(node, getter);
|
| + }
|
| +
|
| + @override
|
| + T visitTopLevelFieldInvoke(
|
| + ast.Send node,
|
| + FieldElement field,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleStaticFieldOrGetterInvoke(node, field);
|
| + }
|
| +
|
| + @override
|
| + T visitTopLevelFunctionInvoke(
|
| + ast.Send node,
|
| + MethodElement function,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleStaticFunctionInvoke(node, function);
|
| + }
|
| +
|
| + @override
|
| + T visitTopLevelFunctionIncompatibleInvoke(
|
| + ast.Send node,
|
| + MethodElement function,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleInvalidStaticInvoke(node);
|
| + }
|
| +
|
| + @override
|
| + T visitTopLevelGetterInvoke(
|
| + ast.Send node,
|
| + FunctionElement getter,
|
| + ast.NodeList arguments,
|
| + CallStructure callStructure,
|
| + _) {
|
| + return handleStaticFieldOrGetterInvoke(node, getter);
|
| + }
|
| +
|
| + @override
|
| + T visitUnresolvedInvoke(
|
| + ast.Send node,
|
| + Element element,
|
| + ast.NodeList arguments,
|
| + Selector selector,
|
| + _) {
|
| + return handleInvalidStaticInvoke(node);
|
| + }
|
| +
|
| + T handleForeignSend(ast.Send node, Element element) {
|
| + ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
| + Selector selector = elements.getSelector(node);
|
| + String name = element.name;
|
| + handleStaticSend(node, selector, element, arguments);
|
| if (name == 'JS' || name == 'JS_EMBEDDED_GLOBAL' || name == 'JS_BUILTIN') {
|
| native.NativeBehavior nativeBehavior =
|
| compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
|
| @@ -1343,23 +1466,12 @@ class SimpleTypeInferrerVisitor<T>
|
| }
|
|
|
| T visitGetterSend(ast.Send node) {
|
| - Element element = elements[node];
|
| - Selector selector = elements.getSelector(node);
|
| - if (Elements.isStaticOrTopLevelField(element)) {
|
| - return handleStaticSend(node, selector, element, null);
|
| - } else if (Elements.isInstanceSend(node, elements)) {
|
| - return visitDynamicSend(node);
|
| - } else if (Elements.isStaticOrTopLevelFunction(element)) {
|
| - return handleStaticSend(node, selector, element, null);
|
| - } else if (Elements.isErroneous(element)) {
|
| - return types.dynamicType;
|
| - } else if (element.isLocal) {
|
| - internalError(node, "Unhandled local: $element");
|
| - return null;
|
| - } else {
|
| - assert(element is PrefixElement);
|
| - return null;
|
| + if (elements[node] is! PrefixElement) {
|
| + // TODO(johnniwinther): Remove this when no longer called from
|
| + // [handleSendSet].
|
| + internalError(node, "Unexpected visitGetterSend");
|
| }
|
| + return null;
|
| }
|
|
|
| /// Read a local variable, function or parameter.
|
| @@ -1368,21 +1480,118 @@ class SimpleTypeInferrerVisitor<T>
|
| return locals.use(local);
|
| }
|
|
|
| + /// Read a static or top level field.
|
| + T handleStaticFieldGet(ast.Send node, FieldElement field) {
|
| + return handleStaticSend(node, elements.getSelector(node), field, null);
|
| + }
|
| +
|
| + /// Invoke a static or top level getter.
|
| + T handleStaticGetterGet(ast.Send node, MethodElement getter) {
|
| + return handleStaticSend(node, elements.getSelector(node), getter, null);
|
| + }
|
| +
|
| + /// Closurize a static or top level function.
|
| + T handleStaticFunctionGet(ast.Send node, MethodElement function) {
|
| + return handleStaticSend(node, elements.getSelector(node), function, null);
|
| + }
|
| +
|
| @override
|
| - T visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
|
| + T visitDynamicPropertyGet(
|
| + ast.Send node,
|
| + ast.Node receiver,
|
| + Selector selector,
|
| + _) {
|
| + return visitDynamicSend(node);
|
| + }
|
| +
|
| + @override
|
| + T visitLocalVariableGet(
|
| + ast.Send node,
|
| + LocalVariableElement variable,
|
| + _) {
|
| return handleLocalGet(node, variable);
|
| }
|
|
|
| @override
|
| - T visitParameterGet(ast.Send node, ParameterElement parameter, _) {
|
| + T visitParameterGet(
|
| + ast.Send node,
|
| + ParameterElement parameter,
|
| + _) {
|
| return handleLocalGet(node, parameter);
|
| }
|
|
|
| @override
|
| - T visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
|
| + T visitLocalFunctionGet(
|
| + ast.Send node,
|
| + LocalFunctionElement function,
|
| + _) {
|
| return handleLocalGet(node, function);
|
| }
|
|
|
| + @override
|
| + T visitStaticFieldGet(
|
| + ast.Send node,
|
| + FieldElement field,
|
| + _) {
|
| + return handleStaticFieldGet(node, field);
|
| + }
|
| +
|
| + @override
|
| + T visitStaticFunctionGet(
|
| + ast.Send node,
|
| + MethodElement function,
|
| + _) {
|
| + return handleStaticFunctionGet(node, function);
|
| + }
|
| +
|
| + @override
|
| + T visitStaticGetterGet(
|
| + ast.Send node,
|
| + FunctionElement getter,
|
| + _) {
|
| + return handleStaticGetterGet(node, getter);
|
| + }
|
| +
|
| + @override
|
| + T visitThisPropertyGet(
|
| + ast.Send node,
|
| + Selector selector,
|
| + _) {
|
| + return visitDynamicSend(node);
|
| + }
|
| +
|
| + @override
|
| + T visitTopLevelFieldGet(
|
| + ast.Send node,
|
| + FieldElement field,
|
| + _) {
|
| + return handleStaticFieldGet(node, field);
|
| + }
|
| +
|
| + @override
|
| + T visitTopLevelFunctionGet(
|
| + ast.Send node,
|
| + MethodElement function,
|
| + _) {
|
| + return handleStaticFunctionGet(node, function);
|
| + }
|
| +
|
| + @override
|
| + T visitTopLevelGetterGet(
|
| + ast.Send node,
|
| + FunctionElement getter,
|
| + _) {
|
| + return handleStaticGetterGet(node, getter);
|
| + }
|
| +
|
| + @override
|
| + T visitUnresolvedGet(
|
| + ast.Send node,
|
| + Element element,
|
| + _) {
|
| + return types.dynamicType;
|
| + }
|
| +
|
| /// Handle .call invocation on [closure].
|
| T handleCallInvoke(ast.Send node, T closure) {
|
| ArgumentsTypes arguments = analyzeArguments(node.arguments);
|
|
|