use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NTIScope method isNamespace.
boolean isNamespace(String name) {
checkArgument(!name.contains("."));
Declaration decl = getDeclaration(name, false);
if (decl == null) {
return false;
}
JSType simpleType = decl.getTypeOfSimpleDecl();
return decl.getNamespace() != null || (simpleType != null && simpleType.isNamespace());
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeReturnFwd.
private TypeEnv analyzeReturnFwd(Node n, TypeEnv inEnv) {
if (this.currentScope.getRoot().isGeneratorFunction()) {
JSType declRetType = getDeclaredReturnTypeOfCurrentScope(this.commonTypes.getGeneratorInstance(UNKNOWN));
if (n.hasChildren()) {
EnvTypePair retPair = analyzeExprFwd(n.getFirstChild(), inEnv, UNKNOWN);
return envPutType(retPair.env, RETVAL_ID, declRetType);
}
return envPutType(inEnv, RETVAL_ID, declRetType);
}
TypeEnv outEnv;
JSType declRetType = getDeclaredReturnTypeOfCurrentScope(UNKNOWN);
JSType actualRetType;
Node retExp = n.getFirstChild();
if (retExp == null) {
actualRetType = UNDEFINED;
outEnv = envPutType(inEnv, RETVAL_ID, actualRetType);
} else {
EnvTypePair retPair = analyzeExprFwd(retExp, inEnv, declRetType);
actualRetType = retPair.type;
outEnv = envPutType(retPair.env, RETVAL_ID, actualRetType);
}
if (!actualRetType.isSubtypeOf(declRetType)) {
registerMismatchAndWarn(JSError.make(n, RETURN_NONDECLARED_TYPE, errorMsgWithTypeDiff(declRetType, actualRetType)), actualRetType, declRetType);
}
return outEnv;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeLValueFwd.
private LValueResultFwd analyzeLValueFwd(Node expr, TypeEnv inEnv, JSType requiredType, boolean insideQualifiedName) {
LValueResultFwd lvalResult = null;
switch(expr.getToken()) {
case THIS:
{
mayWarnAboutGlobalThis(expr);
if (this.currentScope.hasThis()) {
lvalResult = new LValueResultFwd(inEnv, envGetType(inEnv, THIS_ID), this.currentScope.getDeclaredTypeOf(THIS_ID), new QualifiedName(THIS_ID));
} else {
lvalResult = new LValueResultFwd(inEnv, UNKNOWN, null, null);
}
break;
}
case NAME:
{
String varName = expr.getString();
JSType varType = analyzeExprFwd(expr, inEnv).type;
lvalResult = new LValueResultFwd(inEnv, varType, this.currentScope.getDeclaredTypeOf(varName), varType.hasNonScalar() ? new QualifiedName(varName) : null);
break;
}
case GETPROP:
case GETELEM:
{
Node obj = expr.getFirstChild();
Node prop = expr.getLastChild();
QualifiedName pname = expr.isGetProp() || prop.isString() ? new QualifiedName(prop.getString()) : null;
LValueResultFwd recvLvalue = analyzeReceiverLvalFwd(obj, pname, inEnv, requiredType);
if (!recvLvalue.type.isSubtypeOf(TOP_OBJECT)) {
EnvTypePair pair = analyzeExprFwd(prop, recvLvalue.env, requiredType);
lvalResult = new LValueResultFwd(pair.env, requiredType, null, null);
break;
}
JSType indexType = recvLvalue.type.getIndexType();
// (1) A getelem where the receiver is an IObject
if (expr.isGetElem() && indexType != null) {
lvalResult = analyzeIObjectElmLvalFwd(prop, recvLvalue, indexType);
break;
}
// (2) A getelem where the prop is a string literal is like a getprop
if (expr.isGetProp() || prop.isString()) {
lvalResult = analyzePropLValFwd(obj, pname, recvLvalue, requiredType, insideQualifiedName);
break;
}
// (3) All other getelems
// TODO(dimvar): there is some recomputation here; the receiver will be
// analyzed again. Some more refactoring can fix this.
EnvTypePair pair = analyzeExprFwd(expr, recvLvalue.env, requiredType);
lvalResult = new LValueResultFwd(pair.env, pair.type, null, null);
break;
}
case VAR:
{
// Can happen iff its parent is a for/in or for/of.
checkState(expr.getParent().isForIn() || expr.getParent().isForOf());
Node nameNode = expr.getFirstChild();
String name = nameNode.getString();
// For/in and for/of can never have rhs of its VAR
checkState(!nameNode.hasChildren());
maybeSetTypeI(nameNode, requiredType);
if (expr.getParent().isForIn()) {
return new LValueResultFwd(inEnv, STRING, null, new QualifiedName(name));
} else {
JSType declType = this.currentScope.getDeclaredTypeOf(name);
return new LValueResultFwd(inEnv, requiredType, declType, new QualifiedName(name));
}
}
default:
{
// Expressions that aren't lvalues should be handled because they may
// be, e.g., the left child of a getprop.
// We must check that they are not the direct lvalues.
checkState(insideQualifiedName);
EnvTypePair pair = analyzeExprFwd(expr, inEnv, requiredType);
return new LValueResultFwd(pair.env, pair.type, null, null);
}
}
maybeSetTypeI(expr, lvalResult.type);
mayWarnAboutUnknownType(expr, lvalResult.type);
return lvalResult;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeNameBwd.
private EnvTypePair analyzeNameBwd(Node expr, TypeEnv outEnv, JSType requiredType) {
String varName = expr.getString();
if (varName.equals("undefined")) {
return new EnvTypePair(outEnv, UNDEFINED);
}
JSType inferredType = envGetType(outEnv, varName);
println(varName, "'s inferredType: ", inferredType, " requiredType: ", requiredType);
if (inferredType == null) {
return new EnvTypePair(outEnv, UNKNOWN);
}
JSType preciseType = inferredType.specialize(requiredType);
if ((this.currentScope.isUndeclaredFormal(varName) || this.currentScope.isUndeclaredOuterVar(varName)) && preciseType.hasNonScalar()) {
preciseType = preciseType.withLoose();
}
println(varName, "'s preciseType: ", preciseType);
if (preciseType.isBottom()) {
// If there is a type mismatch, we can propagate the previously
// inferred type or the required type.
// Propagating the already inferred type means that the type of the
// variable is stable throughout the function body.
// Propagating the required type means that the type chosen for a
// formal is the one closest to the function header, which helps
// generate more intuitive warnings in the fwd direction.
// But there is a small chance that the different types of the same
// variable flow to other variables and this can also be a source of
// unintuitive warnings.
// It's a trade-off.
JSType declType = this.currentScope.getDeclaredTypeOf(varName);
preciseType = firstNonNull(declType, requiredType);
}
return EnvTypePair.addBinding(outEnv, varName, preciseType);
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method isFunctionBind.
private boolean isFunctionBind(Node callee, TypeEnv env, boolean isFwd) {
if (NodeUtil.isFunctionBind(callee)) {
if (isFwd) {
analyzeExprFwdIgnoreResult(callee, env);
}
return true;
}
if (!callee.isGetProp() || !callee.isQualifiedName() || !callee.getLastChild().getString().equals("bind")) {
return false;
}
Node recv = callee.getFirstChild();
JSType recvType;
if (isFwd) {
recvType = analyzeExprFwd(recv, env).type;
maybeSetTypeI(callee, recvType.getProp(new QualifiedName("bind")));
} else {
recvType = analyzeExprBwd(recv, env).type;
}
return !recvType.isUnknown() && recvType.isSubtypeOf(commonTypes.topFunction());
}
Aggregations