use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeYieldFwd.
private EnvTypePair analyzeYieldFwd(Node expr, TypeEnv inEnv) {
if (!expr.hasChildren()) {
return new EnvTypePair(envPutType(inEnv, YIELDVAL_ID, UNDEFINED), UNKNOWN);
}
EnvTypePair resultPair = analyzeExprFwd(expr.getFirstChild(), inEnv);
// Getting the instantiated declared return type
JSType iterable = this.commonTypes.getIterableInstance(UNKNOWN);
JSType iterator = this.commonTypes.getIteratorInstance(UNKNOWN);
JSType generator = this.commonTypes.getGeneratorInstance(UNKNOWN);
JSType declRetType = getDeclaredReturnTypeOfCurrentScope(generator);
JSType yieldType;
if (!generator.isSubtypeOf(declRetType)) {
// Return early due to unexpected declared return type, but do not warn
// Warning will be generated in createSummary of the function
resultPair.type = UNKNOWN;
return resultPair;
} else if (declRetType.isSubtypeOf(iterable)) {
// This check and implementation is in lieu of calling a hypothetical unifyWithSupertype()
// method on generator.
yieldType = declRetType.getInstantiatedTypeArgument(iterable);
} else if (declRetType.isSubtypeOf(iterator)) {
yieldType = declRetType.getInstantiatedTypeArgument(iterator);
} else {
// declRetType is neither subtype of iterable nor iterator. This means we do not know
// anything about the yield type.
yieldType = UNKNOWN;
}
// Getting the actual ret type
JSType actualRetType;
if (expr.isYieldAll()) {
JSType boxedType = resultPair.type.autobox();
if (boxedType.isSubtypeOf(iterable)) {
actualRetType = boxedType.getInstantiatedTypeArgument(iterable);
} else {
warnings.add(JSError.make(expr, YIELD_ALL_EXPECTS_ITERABLE, resultPair.type.toString()));
resultPair.type = UNKNOWN;
return resultPair;
}
} else {
actualRetType = resultPair.type;
}
if (!yieldType.isBottom() && !actualRetType.isSubtypeOf(yieldType)) {
// Do not warn if yieldType is bottom because this only happens when unification returns
// an empty list, which means the declRetType is Generator<?>
registerMismatchAndWarn(JSError.make(expr, YIELD_NONDECLARED_TYPE, errorMsgWithTypeDiff(yieldType, actualRetType)), actualRetType, yieldType);
resultPair.type = UNKNOWN;
return resultPair;
}
if (yieldType.isBottom() || yieldType.isUnknown()) {
// Infer the instantiated yield type of the function if there is no declared type.
JSType oldType = envGetType(resultPair.env, YIELDVAL_ID);
if (oldType == null) {
resultPair.env = envPutType(resultPair.env, YIELDVAL_ID, actualRetType);
} else {
resultPair.env = envPutType(resultPair.env, YIELDVAL_ID, JSType.join(oldType, actualRetType));
}
}
resultPair.type = UNKNOWN;
return resultPair;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NTIScope method getLocalDeclaration.
private Declaration getLocalDeclaration(String name, boolean includeTypes) {
checkArgument(!name.contains("."));
if (!isDefinedLocally(name, includeTypes)) {
return null;
}
DeclaredFunctionType declaredType = getDeclaredTypeForOwnBody();
JSType type = null;
boolean isTypeVar = false;
if ("this".equals(name)) {
type = getDeclaredTypeOf("this");
} else if (locals.containsKey(name)) {
type = locals.get(name).getDeclaredType();
} else if (formals.contains(name)) {
int formalIndex = formals.indexOf(name);
if (declaredType != null && formalIndex != -1) {
JSType formalType = declaredType.getFormalType(formalIndex);
if (formalType != null && !formalType.isBottom()) {
type = formalType;
}
}
} else if (localFunDefs.containsKey(name)) {
// external function namespaces, don't rely on localFunDefs
if (isFrozen && externs.containsKey(name)) {
type = externs.get(name);
}
} else if (localTypedefs.containsKey(name) || localNamespaces.containsKey(name)) {
// Any further declarations are shadowed
} else if (declaredType != null && declaredType.isTypeVariableDefinedLocally(name)) {
isTypeVar = true;
type = JSType.fromTypeVar(this.commonTypes, declaredType.getTypeVariableDefinedLocally(name));
} else if (externs.containsKey(name)) {
type = externs.get(name);
}
Namespace ns = null;
if (localNamespaces.containsKey(name)) {
ns = localNamespaces.get(name);
} else if (preservedNamespaces != null) {
ns = preservedNamespaces.get(name);
}
return new Declaration(type, localTypedefs.get(name), ns, localFunDefs.get(name), isTypeVar, constVars.contains(name));
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeNonStrictComparisonFwd.
private EnvTypePair analyzeNonStrictComparisonFwd(Node expr, TypeEnv inEnv, JSType specializedType) {
Token tokenType = expr.getToken();
Node lhs = expr.getFirstChild();
Node rhs = expr.getLastChild();
if (specializedType.isTrueOrTruthy() || specializedType.isFalseOrFalsy()) {
if (lhs.isTypeOf()) {
return analyzeSpecializedTypeof(lhs, rhs, tokenType, inEnv, specializedType);
} else if (rhs.isTypeOf()) {
return analyzeSpecializedTypeof(rhs, lhs, tokenType, 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);
// This env may contain types that have been tightened after nullable deref.
TypeEnv preciseEnv = rhsPair.env;
JSType lhsType = lhsPair.type;
JSType rhsType = rhsPair.type;
if ((tokenType == Token.EQ && specializedType.isTrueOrTruthy()) || (tokenType == Token.NE && specializedType.isFalseOrFalsy())) {
if (lhsType.isNullOrUndef()) {
rhsPair = analyzeExprFwd(rhs, preciseEnv, UNKNOWN, NULL_OR_UNDEFINED);
} else if (rhsType.isNullOrUndef()) {
lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, NULL_OR_UNDEFINED);
rhsPair = analyzeExprFwd(rhs, lhsPair.env);
} else if (!NULL.isSubtypeOf(lhsType) && !UNDEFINED.isSubtypeOf(lhsType)) {
rhsType = rhsType.removeType(NULL_OR_UNDEFINED);
rhsPair = analyzeExprFwd(rhs, preciseEnv, UNKNOWN, rhsType);
} else if (!NULL.isSubtypeOf(rhsType) && !UNDEFINED.isSubtypeOf(rhsType)) {
lhsType = lhsType.removeType(NULL_OR_UNDEFINED);
lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsType);
rhsPair = analyzeExprFwd(rhs, lhsPair.env);
}
} else if ((tokenType == Token.EQ && specializedType.isFalseOrFalsy()) || (tokenType == Token.NE && specializedType.isTrueOrTruthy())) {
if (lhsType.isNullOrUndef()) {
rhsType = rhsType.removeType(NULL_OR_UNDEFINED);
rhsPair = analyzeExprFwd(rhs, preciseEnv, UNKNOWN, rhsType);
} else if (rhsType.isNullOrUndef()) {
lhsType = lhsType.removeType(NULL_OR_UNDEFINED);
lhsPair = analyzeExprFwd(lhs, preciseEnv, UNKNOWN, lhsType);
rhsPair = analyzeExprFwd(rhs, lhsPair.env);
}
}
rhsPair.type = BOOLEAN;
return rhsPair;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeAssignBwd.
private EnvTypePair analyzeAssignBwd(Node expr, TypeEnv outEnv, JSType requiredType) {
if (expr.getBooleanProp(Node.ANALYZED_DURING_GTI)) {
return new EnvTypePair(outEnv, requiredType);
}
Node lhs = expr.getFirstChild();
Node rhs = expr.getLastChild();
if (lhs.getBooleanProp(Node.ANALYZED_DURING_GTI)) {
return analyzeExprBwd(rhs, outEnv, markAndGetTypeOfPreanalyzedNode(lhs, outEnv, false));
}
// Here we analyze the LHS twice:
// Once to find out what should be removed for the slicedEnv,
// and again to take into account the side effects of the LHS itself.
LValueResultBwd lvalue = analyzeLValueBwd(lhs, outEnv, requiredType, true);
TypeEnv slicedEnv = lvalue.env;
JSType rhsReqType = specializeKeep2ndWhenBottom(lvalue.type, requiredType);
EnvTypePair pair = analyzeExprBwd(rhs, slicedEnv, rhsReqType);
pair.env = analyzeLValueBwd(lhs, pair.env, requiredType, true).env;
return pair;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class SimpleInference method inferCallNew.
private JSType inferCallNew(Node n, NTIScope scope) {
Node callee = n.getFirstChild();
// compiler for i18n.
if (callee.matchesQualifiedName("goog.getMsg")) {
return this.commonTypes.STRING;
}
FunctionType funType = inferFunction(callee, scope);
if (funType == null) {
return null;
}
if (funType.isGeneric()) {
funType = inferInstantiatedCallee(n, funType, true, scope);
if (funType == null) {
return null;
}
}
JSType retType = n.isNew() ? funType.getThisType() : funType.getReturnType();
return retType;
}
Aggregations