Search in sources :

Example 11 with JSType

use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.

the class TypeInference method traverseName.

private FlowScope traverseName(Node n, FlowScope scope) {
    String varName = n.getString();
    Node value = n.getFirstChild();
    JSType type = n.getJSType();
    if (value != null) {
        scope = traverse(value, scope);
        updateScopeForTypeChange(scope, n, n.getJSType(), /* could be null */
        getJSType(value));
        return scope;
    } else {
        StaticTypedSlot<JSType> var = scope.getSlot(varName);
        if (var != null) {
            // There are two situations where we don't want to use type information
            // from the scope, even if we have it.
            // 1) The var is escaped and assigned in an inner scope, e.g.,
            // function f() { var x = 3; function g() { x = null } (x); }
            boolean isInferred = var.isTypeInferred();
            boolean unflowable = isInferred && isUnflowable(currentScope.getVar(varName));
            // 2) We're reading type information from another scope for an
            // inferred variable. That variable is assigned more than once,
            // and we can't know which type we're getting.
            // 
            // var t = null; function f() { (t); } doStuff(); t = {};
            // 
            // Notice that this heuristic isn't perfect. For example, you might
            // have:
            // 
            // function f() { (t); } f(); var t = 3;
            // 
            // In this case, we would infer the first reference to t as
            // type {number}, even though it's undefined.
            TypedVar maybeOuterVar = isInferred && cfgRootScope.isLocal() ? cfgRootScope.getParent().getVar(varName) : null;
            boolean nonLocalInferredSlot = var.equals(maybeOuterVar) && !maybeOuterVar.isMarkedAssignedExactlyOnce();
            if (!unflowable && !nonLocalInferredSlot) {
                type = var.getType();
                if (type == null) {
                    type = unknownType;
                }
            }
        }
    }
    n.setJSType(type);
    return scope;
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) Node(com.google.javascript.rhino.Node)

Example 12 with JSType

use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.

the class TypeInference method traverseAdd.

private FlowScope traverseAdd(Node n, FlowScope scope) {
    Node left = n.getFirstChild();
    Node right = left.getNext();
    scope = traverseChildren(n, scope);
    JSType leftType = left.getJSType();
    JSType rightType = right.getJSType();
    JSType type = unknownType;
    if (leftType != null && rightType != null) {
        boolean leftIsUnknown = leftType.isUnknownType();
        boolean rightIsUnknown = rightType.isUnknownType();
        if (leftIsUnknown && rightIsUnknown) {
            type = unknownType;
        } else if ((!leftIsUnknown && leftType.isString()) || (!rightIsUnknown && rightType.isString())) {
            type = getNativeType(STRING_TYPE);
        } else if (leftIsUnknown || rightIsUnknown) {
            type = unknownType;
        } else if (isAddedAsNumber(leftType) && isAddedAsNumber(rightType)) {
            type = getNativeType(NUMBER_TYPE);
        } else {
            type = registry.createUnionType(STRING_TYPE, NUMBER_TYPE);
        }
    }
    n.setJSType(type);
    if (n.isAssignAdd()) {
        updateScopeForTypeChange(scope, left, leftType, type);
    }
    return scope;
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) Node(com.google.javascript.rhino.Node)

Example 13 with JSType

use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.

the class TypeInference method inferArguments.

/**
 * Infers all of a function's arguments if their types aren't declared.
 */
// unknownType is a singleton
@SuppressWarnings("ReferenceEquality")
private void inferArguments(TypedScope functionScope) {
    Node functionNode = functionScope.getRootNode();
    Node astParameters = functionNode.getSecondChild();
    Node iifeArgumentNode = null;
    if (NodeUtil.isInvocationTarget(functionNode)) {
        iifeArgumentNode = functionNode.getNext();
    }
    FunctionType functionType = JSType.toMaybeFunctionType(functionNode.getJSType());
    if (functionType != null) {
        Node parameterTypes = functionType.getParametersNode();
        if (parameterTypes != null) {
            Node parameterTypeNode = parameterTypes.getFirstChild();
            for (Node astParameter : astParameters.children()) {
                TypedVar var = functionScope.getVar(astParameter.getString());
                checkNotNull(var);
                if (var.isTypeInferred() && var.getType() == unknownType) {
                    JSType newType = null;
                    if (iifeArgumentNode != null) {
                        newType = iifeArgumentNode.getJSType();
                    } else if (parameterTypeNode != null) {
                        newType = parameterTypeNode.getJSType();
                    }
                    if (newType != null) {
                        var.setType(newType);
                        astParameter.setJSType(newType);
                    }
                }
                if (parameterTypeNode != null) {
                    parameterTypeNode = parameterTypeNode.getNext();
                }
                if (iifeArgumentNode != null) {
                    iifeArgumentNode = iifeArgumentNode.getNext();
                }
            }
        }
    }
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) Node(com.google.javascript.rhino.Node) FunctionType(com.google.javascript.rhino.jstype.FunctionType)

Example 14 with JSType

use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.

the class TypeInference method traverseCall.

private FlowScope traverseCall(Node n, FlowScope scope) {
    scope = traverseChildren(n, scope);
    Node left = n.getFirstChild();
    JSType functionType = getJSType(left).restrictByNotNullOrUndefined();
    if (functionType.isFunctionType()) {
        FunctionType fnType = functionType.toMaybeFunctionType();
        n.setJSType(fnType.getReturnType());
        backwardsInferenceFromCallSite(n, fnType);
    } else if (functionType.isEquivalentTo(getNativeType(CHECKED_UNKNOWN_TYPE))) {
        n.setJSType(getNativeType(CHECKED_UNKNOWN_TYPE));
    }
    scope = tightenTypesAfterAssertions(scope, n);
    return scope;
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) Node(com.google.javascript.rhino.Node) FunctionType(com.google.javascript.rhino.jstype.FunctionType)

Example 15 with JSType

use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.

the class TypeInference method resolvedTemplateType.

private static void resolvedTemplateType(Map<TemplateType, JSType> map, TemplateType template, JSType resolved) {
    JSType previous = map.get(template);
    if (!resolved.isUnknownType()) {
        if (previous == null) {
            map.put(template, resolved);
        } else {
            JSType join = previous.getLeastSupertype(resolved);
            map.put(template, join);
        }
    }
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType)

Aggregations

JSType (com.google.javascript.rhino.jstype.JSType)189 Node (com.google.javascript.rhino.Node)60 FunctionType (com.google.javascript.rhino.jstype.FunctionType)38 ObjectType (com.google.javascript.rhino.jstype.ObjectType)37 JSDocInfo (com.google.javascript.rhino.JSDocInfo)9 FlowScope (com.google.javascript.jscomp.type.FlowScope)7 TemplateType (com.google.javascript.rhino.jstype.TemplateType)6 TemplateTypeMap (com.google.javascript.rhino.jstype.TemplateTypeMap)5 UnionType (com.google.javascript.rhino.jstype.UnionType)4 ArrayList (java.util.ArrayList)4 EnumType (com.google.javascript.rhino.jstype.EnumType)3 JSTypeRegistry (com.google.javascript.rhino.jstype.JSTypeRegistry)3 TemplateTypeMapReplacer (com.google.javascript.rhino.jstype.TemplateTypeMapReplacer)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 Branch (com.google.javascript.jscomp.ControlFlowGraph.Branch)2 Scope (com.google.javascript.jscomp.Scope)2 Token (com.google.javascript.rhino.Token)2 FunctionBuilder (com.google.javascript.rhino.jstype.FunctionBuilder)2 TemplatizedType (com.google.javascript.rhino.jstype.TemplatizedType)2 HashMap (java.util.HashMap)2