use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method collectTypesForEscapedVarsFwd.
/**
* Used when analyzing a scope that defines variables used in inner scopes.
* Returns a type environment that combines the types from all uses of a variable.
*/
private TypeEnv collectTypesForEscapedVarsFwd(Node n, TypeEnv env) {
checkArgument(n.isFunction() || (n.isName() && NodeUtil.isInvocationTarget(n)), "Expected invovation target, found %s", n);
String fnName = n.isFunction() ? symbolTable.getFunInternalName(n) : n.getString();
NTIScope innerScope = this.currentScope.getScope(fnName);
JSType summaryAsJstype = summaries.get(innerScope);
if (summaryAsJstype == null) {
// NOTE(dimvar): The n.isFromExterns part is here because the polymer pass does some weird
// rewriting which AFAIU can copy some @polymerBehavior code from the externs to the source,
// but the AST function nodes are still marked as externs, and don't have summaries.
// We don't have a unit test for it.
checkState(NodeUtil.isUnannotatedCallback(n) || n.isFromExterns());
return env;
}
FunctionType summary = summaryAsJstype.getFunType();
for (String freeVar : innerScope.getOuterVars()) {
if (innerScope.getDeclaredTypeOf(freeVar) == null) {
JSType outerType = envGetType(env, freeVar);
if (outerType == null) {
outerType = UNKNOWN;
}
JSType innerType = summary.getOuterVarPrecondition(freeVar);
if (// haven't found an easy way to avoid false positives.
!innerType.isLoose() && // so we don't warn for uninitialized variables.
(n.isName() || (n.isFunction() && !outerType.isUndefined())) && !JSType.haveCommonSubtype(outerType, innerType)) {
warnings.add(JSError.make(n, CROSS_SCOPE_GOTCHA, freeVar, outerType.toString(), innerType.toString()));
}
// If n is a callee node, we only want to keep the type in the callee.
// If n is a function expression, we don't know if it will get called, so we take the
// types from both scopes into account.
JSType freeVarType;
if (n.isFunction()) {
// defined in this scope, and it's more likely that this type is correct.
if (// only keep outerType for initialized variables
!outerType.isNullOrUndef() && !outerType.isUnknown() && !innerType.isUnknown() && outerType.isSubtypeOf(innerType)) {
freeVarType = outerType;
} else {
freeVarType = JSType.join(innerType, outerType);
}
} else {
freeVarType = innerType;
}
env = envPutType(env, freeVar, freeVarType);
}
}
return env;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method maybeSetTypeI.
private void maybeSetTypeI(Node n, JSType t) {
TypeI oldType = n.getTypeI();
checkState(oldType == null || oldType instanceof JSType);
// outer scope; we've already computed a good type for it, don't lose it.
if (oldType == null) {
n.setTypeI(t);
}
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeStrictComparisonFwd.
private EnvTypePair analyzeStrictComparisonFwd(Token comparisonOp, Node lhs, Node rhs, TypeEnv inEnv, JSType specializedType) {
if (specializedType.isTrueOrTruthy() || specializedType.isFalseOrFalsy()) {
if (lhs.isTypeOf()) {
return analyzeSpecializedTypeof(lhs, rhs, comparisonOp, inEnv, specializedType);
} else if (rhs.isTypeOf()) {
return analyzeSpecializedTypeof(rhs, lhs, comparisonOp, inEnv, specializedType);
} else if (isGoogTypeof(lhs)) {
return analyzeGoogTypeof(lhs, rhs, inEnv, specializedType);
} else if (isGoogTypeof(rhs)) {
return analyzeGoogTypeof(rhs, lhs, inEnv, specializedType);
}
}
EnvTypePair lhsPair = analyzeExprFwd(lhs, inEnv);
EnvTypePair rhsPair = analyzeExprFwd(rhs, lhsPair.env);
JSType rhstype = rhsPair.type;
JSType lhstype = lhsPair.type;
if (!rhstype.isNullOrUndef()) {
if (JSType.haveCommonSubtype(lhstype, rhstype)) {
registerImplicitUses(lhs, lhstype, rhstype);
} else {
JSError error = JSError.make(lhs, INCOMPATIBLE_STRICT_COMPARISON, lhstype.toString(), rhstype.toString());
registerMismatchAndWarn(error, lhstype, rhstype);
}
}
// This env may contain types that have been tightened after nullable deref.
TypeEnv preciseEnv = rhsPair.env;
if ((comparisonOp == Token.SHEQ && specializedType.isTrueOrTruthy()) || (comparisonOp == Token.SHNE && specializedType.isFalseOrFalsy())) {
lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsPair.type.specialize(rhsPair.type));
rhsPair = analyzeExprFwd(rhs, lhsPair.env, UNKNOWN, rhsPair.type.specialize(lhsPair.type));
} else if ((comparisonOp == Token.SHEQ && specializedType.isFalseOrFalsy()) || (comparisonOp == Token.SHNE && specializedType.isTrueOrTruthy())) {
JSType lhsType = lhsPair.type;
JSType rhsType = rhsPair.type;
if (lhsType.isNullOrUndef()) {
rhsType = rhsType.removeType(lhsType);
} else if (rhsType.isNullOrUndef()) {
lhsType = lhsType.removeType(rhsType);
}
lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsType);
rhsPair = analyzeExprFwd(rhs, lhsPair.env, UNKNOWN, rhsType);
}
rhsPair.type = BOOLEAN;
return rhsPair;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeArrayLitBwd.
private EnvTypePair analyzeArrayLitBwd(Node expr, TypeEnv outEnv) {
TypeEnv env = outEnv;
JSType elementType = BOTTOM;
for (Node elm = expr.getLastChild(); elm != null; elm = elm.getPrevious()) {
EnvTypePair pair = analyzeExprBwd(elm, env);
env = pair.env;
elementType = JSType.join(elementType, pair.type);
}
elementType = firstNonBottom(elementType, UNKNOWN);
return new EnvTypePair(env, commonTypes.getArrayInstance(elementType));
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeReceiverLvalFwd.
private LValueResultFwd analyzeReceiverLvalFwd(Node obj, QualifiedName pname, TypeEnv inEnv, JSType propType) {
// pname is null when the property name is not known.
checkArgument(pname == null || pname.isIdentifier());
JSType reqObjType = pickReqObjType(obj.getParent());
if (pname != null) {
reqObjType = reqObjType.withProperty(pname, propType);
}
LValueResultFwd lvalue = analyzeLValueFwd(obj, inEnv, reqObjType, true);
EnvTypePair pair = mayWarnAboutNullableReferenceAndTighten(obj, lvalue.type, null, lvalue.env);
JSType lvalueType = pair.type;
if (lvalueType.isEnumElement()) {
lvalueType = lvalueType.getEnumeratedTypeOfEnumElement();
}
if (!lvalueType.isSubtypeOf(TOP_OBJECT)) {
warnings.add(JSError.make(obj, ADDING_PROPERTY_TO_NON_OBJECT, getPropNameForErrorMsg(obj.getParent()), lvalueType.toString()));
}
lvalue.type = lvalueType;
lvalue.env = pair.env;
return lvalue;
}
Aggregations