Package com.google.javascript.jscomp.newtypes

Examples of com.google.javascript.jscomp.newtypes.JSType


      return analyzeClosureCallFwd(expr, inEnv, specializedType);
    }
    Node callee = expr.getFirstChild();
    EnvTypePair calleePair =
        analyzeExprFwd(callee, inEnv, JSType.topFunction());
    JSType calleeType = calleePair.type;
    if (!calleeType.isSubtypeOf(JSType.topFunction())) {
      warnings.add(JSError.make(
          expr, TypeCheck.NOT_CALLABLE, calleeType.toString()));
    }
    FunctionType funType = calleeType.getFunType();
    if (funType == null
        || funType.isTopFunction() || funType.isQmarkFunction()) {
      return analyzeCallNodeArgumentsFwd(expr, inEnv);
    } else if (funType.isLoose()) {
      return analyzeLooseCallNodeFwd(expr, inEnv, requiredType);
    } else if (expr.isCall() && funType.isConstructor()) {
      // TODO(dimvar): handle constructors with @return; they can be called
      // without new, eg, Number in es3.js
      warnings.add(JSError.make(
          expr, TypeCheck.CONSTRUCTOR_NOT_CALLABLE, funType.toString()));
      return analyzeCallNodeArgumentsFwd(expr, inEnv);
    } else if (expr.isNew() && !funType.isConstructor()) {
      warnings.add(JSError.make(
          expr, NOT_A_CONSTRUCTOR, funType.toString()));
      return analyzeCallNodeArgumentsFwd(expr, inEnv);
    }
    int maxArity = funType.getMaxArity();
    int minArity = funType.getMinArity();
    int numArgs = expr.getChildCount() - 1;
    if (numArgs < minArity || numArgs > maxArity) {
      warnings.add(JSError.make(
          expr, TypeCheck.WRONG_ARGUMENT_COUNT, "",
          Integer.toString(numArgs), Integer.toString(minArity),
          " and at most " + maxArity));
      return analyzeCallNodeArgumentsFwd(expr, inEnv);
    }
    FunctionType origFunType = funType; // save for later
    if (funType.isGeneric()) {
      Map<String, JSType> typeMap =
          calcTypeInstantiationFwd(expr, funType, inEnv);
      funType = funType.instantiateGenerics(typeMap);
      println("Instantiated function type: " + funType);
    }
    // argTypes collects types of actuals for deferred checks.
    List<JSType> argTypes = new ArrayList<>();
    TypeEnv tmpEnv = inEnv;
    Node arg = expr.getChildAtIndex(1);
    for (int i = 0; i < numArgs; i++) {
      JSType formalType = funType.getFormalType(i);
      if (formalType.isBottom()) {
        warnings.add(JSError.make(expr, CALL_FUNCTION_WITH_BOTTOM_FORMAL,
                Integer.toString(i)));
        formalType = JSType.UNKNOWN;
      }
      EnvTypePair pair = analyzeExprFwd(arg, tmpEnv, formalType);
      JSType argTypeForDeferredCheck = pair.type;
      // Allow passing undefined for an optional argument.
      if (i >= minArity && pair.type.equals(JSType.UNDEFINED)) {
        argTypeForDeferredCheck = null; // No deferred check needed.
      } else if (!pair.type.isSubtypeOf(formalType)) {
        warnings.add(JSError.make(arg, INVALID_ARGUMENT_TYPE,
                Integer.toString(i + 1), "",
                formalType.toString(), pair.type.toString()));
        argTypeForDeferredCheck = null; // No deferred check needed.
      }
      argTypes.add(argTypeForDeferredCheck);
      tmpEnv = pair.env;
      arg = arg.getNext();
    }
    JSType retType = funType.getReturnType();
    if (callee.isName()) {
      String calleeName = callee.getQualifiedName();
      if (currentScope.isKnownFunction(calleeName)
          && !currentScope.isExternalFunction(calleeName)) {
        // Local function definitions will be type-checked more
        // exactly using their summaries, and don't need deferred checks
        if (currentScope.isLocalFunDef(calleeName)) {
          collectTypesForFreeVarsFwd(callee, tmpEnv);
        } else if (!origFunType.isGeneric()) {
          JSType expectedRetType = requiredType;
          println("Updating deferred check with ret: ", expectedRetType,
              " and args: ", argTypes);
          DeferredCheck dc;
          if (expr.isCall()) {
            dc = deferredChecks.get(expr);
View Full Code Here


  private EnvTypePair analyzeGetElemFwd(
      Node expr, TypeEnv inEnv, JSType requiredType, JSType specializedType) {
    Node receiver = expr.getFirstChild();
    Node index = expr.getLastChild();
    JSType reqObjType = pickReqObjType(expr);
    EnvTypePair pair = analyzeExprFwd(receiver, inEnv, reqObjType);
    JSType recvType = pair.type;
    // TODO(dimvar): we don't know the prop name here so we're passing the
    // empty string. Consider improving the error msg.
    if (!mayWarnAboutNonObject(receiver, "", recvType, specializedType) &&
        !mayWarnAboutStructPropAccess(receiver, recvType)) {
      if (isArrayType(recvType)) {
View Full Code Here

  private EnvTypePair analyzeInFwd(
      Node expr, TypeEnv inEnv, JSType specializedType) {
    Node lhs = expr.getFirstChild();
    Node rhs = expr.getLastChild();
    JSType reqObjType = pickReqObjType(expr);
    EnvTypePair pair;

    pair = analyzeExprFwd(lhs, inEnv, JSType.NUM_OR_STR);
    if (!pair.type.isSubtypeOf(JSType.NUM_OR_STR)) {
      warnInvalidOperand(lhs, Token.IN, JSType.NUM_OR_STR, pair.type);
    }
    pair = analyzeExprFwd(rhs, pair.env, reqObjType);
    if (!pair.type.isSubtypeOf(JSType.TOP_OBJECT)) {
      warnInvalidOperand(rhs, Token.IN, "Object", pair.type);
      pair.type = JSType.BOOLEAN;
      return pair;
    }
    if (pair.type.isStruct()) {
      warnings.add(JSError.make(rhs, TypeCheck.IN_USED_WITH_STRUCT));
      pair.type = JSType.BOOLEAN;
      return pair;
    }

    JSType resultType = JSType.BOOLEAN;
    if (lhs.isString()) {
      QualifiedName pname = new QualifiedName(lhs.getString());
      if (specializedType.isTruthy()) {
        pair = analyzeExprFwd(rhs, inEnv, reqObjType,
            reqObjType.withPropertyRequired(pname.getLeftmostName()));
View Full Code Here

    return pair;
  }

  private EnvTypePair analyzeArrayLitFwd(Node expr, TypeEnv inEnv) {
    TypeEnv env = inEnv;
    JSType elementType = JSType.BOTTOM;
    for (Node arrayElm = expr.getFirstChild(); arrayElm != null;
         arrayElm = arrayElm.getNext()) {
      EnvTypePair pair = analyzeExprFwd(arrayElm, env);
      env = pair.env;
      elementType = JSType.join(elementType, pair.type);
    }
    if (elementType.isBottom()) {
      elementType = JSType.UNKNOWN;
    }
    return new EnvTypePair(env, symbolTable.getArrayType(elementType));
  }
View Full Code Here

    return new EnvTypePair(env, symbolTable.getArrayType(elementType));
  }

  private EnvTypePair analyzeCastFwd(Node expr, TypeEnv inEnv) {
    EnvTypePair pair = analyzeExprFwd(expr.getFirstChild(), inEnv);
    JSType fromType = pair.type;
    JSType toType = symbolTable.getCastType(expr);
    if (!toType.isSubtypeOf(fromType) && !fromType.isSubtypeOf(toType)) {
      warnings.add(JSError.make(expr, TypeValidator.INVALID_CAST,
              fromType.toString(), toType.toString()));
    }
    pair.type = toType;
    return pair;
  }
View Full Code Here

    EnvTypePair lhsPair = analyzeExprFwd(lhs, inEnv);
    EnvTypePair rhsPair = analyzeExprFwd(rhs, lhsPair.env);

    if ((comparisonOp == Token.SHEQ && specializedType.isTruthy()) ||
        (comparisonOp == Token.SHNE && specializedType.isFalsy())) {
      JSType meetType = JSType.meet(lhsPair.type, rhsPair.type);
      lhsPair = analyzeExprFwd(lhs, inEnv, JSType.UNKNOWN, meetType);
      rhsPair = analyzeExprFwd(rhs, lhsPair.env, JSType.UNKNOWN, meetType);
    } else if ((comparisonOp == Token.SHEQ && specializedType.isFalsy()) ||
        (comparisonOp == Token.SHNE && specializedType.isTruthy())) {
      JSType lhsType = lhsPair.type;
      JSType rhsType = rhsPair.type;
      if (lhsType.equals(JSType.NULL) ||
          lhsType.equals(JSType.UNDEFINED)) {
        rhsType = rhsType.removeType(lhsType);
      } else if (rhsType.equals(JSType.NULL) ||
          rhsType.equals(JSType.UNDEFINED)) {
        lhsType = lhsType.removeType(rhsType);
      }
      lhsPair = analyzeExprFwd(lhs, inEnv, JSType.UNKNOWN, lhsType);
      rhsPair = analyzeExprFwd(rhs, lhsPair.env, JSType.UNKNOWN, rhsType);
    }
View Full Code Here

  private EnvTypePair analyzeSpecializedTypeof(Node typeof, Node typeString,
      int comparisonOp, TypeEnv inEnv, JSType specializedType) {
    EnvTypePair pair;
    Node typeofRand = typeof.getFirstChild();
    JSType comparedType = getTypeFromString(typeString);
    checkInvalidTypename(typeString);
    if (comparedType.isUnknown()) {
      pair = analyzeExprFwd(typeofRand, inEnv);
      pair = analyzeExprFwd(typeString, pair.env);
    } else if ((specializedType.isTruthy() &&
         (comparisonOp == Token.SHEQ || comparisonOp == Token.EQ)) ||
        (specializedType.isFalsy() &&
View Full Code Here

    Node arg = callNode.getChildAtIndex(1);
    int i = 0;
    while (arg != null) {
      EnvTypePair pair = isFwd ?
          analyzeExprFwd(arg, typeEnv) : analyzeExprBwd(arg, typeEnv);
      JSType unifTarget = funType.getFormalType(i);
      JSType unifSource = pair.type;
      if (!unifTarget.unifyWith(unifSource, typeParameters, typeMultimap)) {
        // Unification may fail b/c of types irrelevant to generics, eg,
        // number vs string.
        // In this case, don't warn here; we'll show invalid-arg-type later.
        HashMap<String, JSType> tmpTypeMap = new HashMap<>();
        for (String typeParam : typeParameters) {
          tmpTypeMap.put(typeParam, JSType.UNKNOWN);
        }
        if (unifSource.isSubtypeOf(unifTarget.substituteGenerics(tmpTypeMap))) {
          warnings.add(JSError.make(arg, FAILED_TO_UNIFY,
                  unifTarget.toString(), unifSource.toString()));
        }
      }
      arg = arg.getNext();
      typeEnv = pair.env;
      i++;
View Full Code Here

      }
    }

    EnvTypePair lhsPair = analyzeExprFwd(lhs, inEnv);
    EnvTypePair rhsPair = analyzeExprFwd(rhs, lhsPair.env);
    JSType lhsType = lhsPair.type;
    JSType rhsType = rhsPair.type;

    if (tokenType == Token.EQ && specializedType.isTruthy() ||
        tokenType == Token.NE && specializedType.isFalsy()) {
      if (lhsType.isNullOrUndef()) {
        rhsPair = analyzeExprFwd(
            rhs, lhsPair.env, JSType.UNKNOWN, JSType.NULL_OR_UNDEF);
      } else if (rhsType.isNullOrUndef()) {
        lhsPair = analyzeExprFwd(
            lhs, inEnv, JSType.UNKNOWN, JSType.NULL_OR_UNDEF);
        rhsPair = analyzeExprFwd(rhs, lhsPair.env);
      } else if (!JSType.NULL_OR_UNDEF.isSubtypeOf(lhsType)) {
        rhsType = rhsType.removeType(JSType.NULL_OR_UNDEF);
        rhsPair = analyzeExprFwd(rhs, lhsPair.env, JSType.UNKNOWN, rhsType);
      } else if (!JSType.NULL_OR_UNDEF.isSubtypeOf(rhsType)) {
        lhsType = lhsType.removeType(JSType.NULL_OR_UNDEF);
        lhsPair = analyzeExprFwd(lhs, inEnv, JSType.UNKNOWN, lhsType);
        rhsPair = analyzeExprFwd(rhs, lhsPair.env);
      }
    } else if (tokenType == Token.EQ && specializedType.isFalsy() ||
        tokenType == Token.NE && specializedType.isTruthy()) {
      if (lhsType.isNullOrUndef()) {
        rhsType = rhsType.removeType(JSType.NULL_OR_UNDEF);
        rhsPair = analyzeExprFwd(rhs, lhsPair.env, JSType.UNKNOWN, rhsType);
      } else if (rhsType.isNullOrUndef()) {
        lhsType = lhsType.removeType(JSType.NULL_OR_UNDEF);
        lhsPair = analyzeExprFwd(lhs, inEnv, JSType.UNKNOWN, lhsType);
        rhsPair = analyzeExprFwd(rhs, lhsPair.env);
      }
    }
View Full Code Here

    }
    JSDocInfo jsdoc = objLit.getJSDocInfo();
    boolean isStruct = jsdoc != null && jsdoc.makesStructs();
    boolean isDict = jsdoc != null && jsdoc.makesDicts();
    TypeEnv env = inEnv;
    JSType result = pickReqObjType(objLit);
    for (Node prop : objLit.children()) {
      if (isStruct && prop.isQuotedString()) {
        warnings.add(
            JSError.make(prop, TypeCheck.ILLEGAL_OBJLIT_KEY, "struct"));
      } else if (isDict && !prop.isQuotedString()) {
        warnings.add(JSError.make(prop, TypeCheck.ILLEGAL_OBJLIT_KEY, "dict"));
      }
      String pname = NodeUtil.getObjectLitKeyName(prop);
      // We can't assign to a getter to change its value.
      // We can't do a prop access on a setter.
      // So, we don't associate pname with a getter/setter.
      // We add a property with a name that's weird enough to hopefully avoid
      // an accidental clash.
      if (prop.isGetterDef() || prop.isSetterDef()) {
        EnvTypePair pair = analyzeExprFwd(prop.getFirstChild(), env);
        FunctionType funType = pair.type.getFunType();
        Preconditions.checkNotNull(funType);
        String specialPropName;
        JSType propType;
        if (prop.isGetterDef()) {
          specialPropName = GETTER_PREFIX + pname;
          propType = funType.getReturnType();
        } else {
          specialPropName = SETTER_PREFIX + pname;
          propType = pair.type;
        }
        result = result.withProperty(
            new QualifiedName(specialPropName), propType);
        env = pair.env;
      } else {
        QualifiedName qname = new QualifiedName(pname);
        JSType jsdocType = symbolTable.getPropDeclaredType(prop);
        JSType reqPtype, specPtype;
        if (jsdocType != null) {
          reqPtype = specPtype = jsdocType;
        } else if (requiredType.mayHaveProp(qname)) {
          reqPtype = specPtype = requiredType.getProp(qname);
          if (specializedType.mayHaveProp(qname)) {
View Full Code Here

TOP

Related Classes of com.google.javascript.jscomp.newtypes.JSType

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.