use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzePropLValBwd.
private LValueResultBwd analyzePropLValBwd(Node obj, QualifiedName pname, TypeEnv outEnv, JSType type, boolean doSlicing) {
checkArgument(pname.isIdentifier());
JSType reqObjType = pickReqObjType(obj.getParent()).withProperty(pname, type);
LValueResultBwd lvalue = analyzeLValueBwd(obj, outEnv, reqObjType, false, true);
if (lvalue.ptr != null) {
lvalue.ptr = QualifiedName.join(lvalue.ptr, pname);
if (doSlicing) {
String objName = lvalue.ptr.getLeftmostName();
QualifiedName props = lvalue.ptr.getAllButLeftmost();
JSType objType = envGetType(lvalue.env, objName);
// withoutProperty only removes inferred properties
JSType slicedObjType = objType.withoutProperty(props);
lvalue.env = envPutType(lvalue.env, objName, slicedObjType);
}
}
lvalue.type = lvalue.type.mayHaveProp(pname) ? lvalue.type.getProp(pname) : UNKNOWN;
return lvalue;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeEnumObjLitFwd.
private EnvTypePair analyzeEnumObjLitFwd(Node objLit, TypeEnv inEnv, JSType requiredType) {
// so we ignore them here.
if (objLit.getFirstChild() == null) {
return new EnvTypePair(inEnv, requiredType);
}
String pname = NodeUtil.getObjectLitKeyName(objLit.getFirstChild());
JSType enumeratedType = requiredType.getProp(new QualifiedName(pname)).getEnumeratedTypeOfEnumElement();
if (enumeratedType == null) {
// enumeratedType is null only if there is some other type error
return new EnvTypePair(inEnv, requiredType);
}
TypeEnv env = inEnv;
for (Node prop : objLit.children()) {
EnvTypePair pair = analyzeExprFwd(prop, env, enumeratedType);
if (!pair.type.isSubtypeOf(enumeratedType)) {
warnings.add(JSError.make(prop, INVALID_OBJLIT_PROPERTY_TYPE, errorMsgWithTypeDiff(enumeratedType, pair.type)));
}
env = pair.env;
}
return new EnvTypePair(env, requiredType);
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method checkTaggedFunctionFirstParam.
/**
* Check that the first argument of a tagged function is a ITemplateArray.
* If the argument is missing, return Function, to avoid giving two warnings for the same issue.
*/
private FunctionType checkTaggedFunctionFirstParam(Node taggedLit, Node funcName, FunctionType funType) {
JSType firstArgType = funType.getFormalType(0);
JSType templateArray = this.commonTypes.getITemplateArrayType();
if (firstArgType == null) {
warnings.add(JSError.make(taggedLit, TEMPLATE_ARGUMENT_MISSING));
return this.commonTypes.qmarkFunction().getFunTypeIfSingletonObj();
} else if (!templateArray.isSubtypeOf(firstArgType)) {
JSError error = JSError.make(taggedLit, TEMPLATE_ARGUMENT_MISMATCH, getReadableCalleeName(funcName), errorMsgWithTypeDiff(templateArray, firstArgType));
registerMismatchAndWarn(error, firstArgType, templateArray);
}
return funType;
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeFunctionBwd.
private void analyzeFunctionBwd(NTIWorkset workset) {
for (DiGraphNode<Node, ControlFlowGraph.Branch> dn : workset.backward()) {
Node n = dn.getValue();
TypeEnv outEnv = checkNotNull(getOutEnv(dn));
TypeEnv inEnv;
println("\tBWD Statment: ", n);
println("\t\toutEnv: ", outEnv);
switch(n.getToken()) {
case EXPR_RESULT:
inEnv = analyzeExprBwd(n.getFirstChild(), outEnv, UNKNOWN).env;
break;
case RETURN:
{
Node retExp = n.getFirstChild();
if (retExp == null) {
inEnv = outEnv;
} else {
JSType declRetType = this.currentScope.getDeclaredTypeForOwnBody().getReturnType();
declRetType = firstNonNull(declRetType, UNKNOWN);
inEnv = analyzeExprBwd(retExp, outEnv, declRetType).env;
}
break;
}
case VAR:
{
if (NodeUtil.isTypedefDecl(n)) {
inEnv = outEnv;
break;
}
inEnv = outEnv;
for (Node nameNode = n.getFirstChild(); nameNode != null; nameNode = nameNode.getNext()) {
String varName = nameNode.getString();
Node rhs = nameNode.getFirstChild();
JSType declType = this.currentScope.getDeclaredTypeOf(varName);
inEnv = envPutType(inEnv, varName, UNKNOWN);
if (rhs == null || this.currentScope.isLocalFunDef(varName)) {
continue;
}
JSType inferredType = envGetType(outEnv, varName);
JSType requiredType;
if (declType == null) {
requiredType = inferredType;
} else {
// TODO(dimvar): look if the meet is needed
requiredType = JSType.meet(declType, inferredType);
requiredType = firstNonBottom(requiredType, UNKNOWN);
}
inEnv = analyzeExprBwd(rhs, inEnv, requiredType).env;
}
break;
}
case BLOCK:
case ROOT:
case BREAK:
case CATCH:
case CONTINUE:
case DEFAULT_CASE:
case DEBUGGER:
case EMPTY:
case SCRIPT:
case TRY:
case WITH:
inEnv = outEnv;
break;
case DO:
case FOR:
case FOR_IN:
case FOR_OF:
case IF:
case WHILE:
Node expr = (n.isForIn() || n.isForOf()) ? n.getFirstChild() : NodeUtil.getConditionExpression(n);
inEnv = analyzeExprBwd(expr, outEnv).env;
break;
case THROW:
case CASE:
case SWITCH:
inEnv = analyzeExprBwd(n.getFirstChild(), outEnv).env;
break;
default:
if (NodeUtil.isStatement(n)) {
throw new RuntimeException("Unhandled statement type: " + n.getToken());
} else {
inEnv = analyzeExprBwd(n, outEnv).env;
break;
}
}
println("\t\tinEnv: ", inEnv);
for (DiGraphEdge<Node, ControlFlowGraph.Branch> de : dn.getInEdges()) {
envs.put(de, inEnv);
}
}
}
use of com.google.javascript.jscomp.newtypes.JSType in project closure-compiler by google.
the class NewTypeInference method analyzeExprBwd.
/**
* For now, we won't emit any warnings bwd.
*/
private EnvTypePair analyzeExprBwd(Node expr, TypeEnv outEnv, JSType requiredType) {
Preconditions.checkArgument(requiredType != null, "Required type null at: %s", expr);
checkArgument(!requiredType.isBottom());
switch(expr.getToken()) {
case // can be created by a FOR with empty condition
EMPTY:
return new EnvTypePair(outEnv, UNKNOWN);
case FUNCTION:
{
String fnName = symbolTable.getFunInternalName(expr);
return new EnvTypePair(outEnv, envGetType(outEnv, fnName));
}
case FALSE:
case NULL:
case NUMBER:
case STRING:
case TRUE:
return new EnvTypePair(outEnv, scalarValueToType(expr.getToken()));
case OBJECTLIT:
return analyzeObjLitBwd(expr, outEnv, requiredType);
case THIS:
{
// TODO(blickly): Infer a loose type for THIS if we're in a function.
if (!this.currentScope.hasThis()) {
return new EnvTypePair(outEnv, UNKNOWN);
}
JSType thisType = this.currentScope.getDeclaredTypeOf(THIS_ID);
return new EnvTypePair(outEnv, thisType);
}
case SUPER:
// us anything useful at the moment.
return new EnvTypePair(outEnv, UNKNOWN);
case NAME:
return analyzeNameBwd(expr, outEnv, requiredType);
case INC:
case DEC:
case BITNOT:
case // Unary operations on numbers
NEG:
return analyzeExprBwd(expr.getFirstChild(), outEnv, NUMBER);
case POS:
{
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), outEnv);
pair.type = NUMBER;
return pair;
}
case TYPEOF:
{
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), outEnv);
pair.type = STRING;
return pair;
}
case INSTANCEOF:
{
TypeEnv env = analyzeExprBwd(expr.getLastChild(), outEnv, commonTypes.topFunction()).env;
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), env);
pair.type = BOOLEAN;
return pair;
}
case BITOR:
case BITAND:
case BITXOR:
case DIV:
case EXPONENT:
case LSH:
case MOD:
case MUL:
case RSH:
case SUB:
case URSH:
return analyzeBinaryNumericOpBwd(expr, outEnv);
case ADD:
return analyzeAddBwd(expr, outEnv, requiredType);
case OR:
case AND:
return analyzeLogicalOpBwd(expr, outEnv);
case SHEQ:
case SHNE:
case EQ:
case NE:
return analyzeEqNeBwd(expr, outEnv);
case LT:
case GT:
case LE:
case GE:
return analyzeLtGtBwd(expr, outEnv);
case ASSIGN:
return analyzeAssignBwd(expr, outEnv, requiredType);
case ASSIGN_ADD:
return analyzeAssignAddBwd(expr, outEnv, requiredType);
case ASSIGN_BITOR:
case ASSIGN_BITXOR:
case ASSIGN_BITAND:
case ASSIGN_LSH:
case ASSIGN_RSH:
case ASSIGN_URSH:
case ASSIGN_SUB:
case ASSIGN_MUL:
case ASSIGN_DIV:
case ASSIGN_MOD:
case ASSIGN_EXPONENT:
return analyzeAssignNumericOpBwd(expr, outEnv);
case GETPROP:
{
checkState(!NodeUtil.isAssignmentOp(expr.getParent()) || !NodeUtil.isLValue(expr));
if (expr.getBooleanProp(Node.ANALYZED_DURING_GTI)) {
return new EnvTypePair(outEnv, requiredType);
}
return analyzePropAccessBwd(expr.getFirstChild(), expr.getLastChild().getString(), outEnv, requiredType);
}
case HOOK:
return analyzeHookBwd(expr, outEnv, requiredType);
case CALL:
case NEW:
case TAGGED_TEMPLATELIT:
return analyzeInvocationBwd(expr, outEnv, requiredType);
case COMMA:
{
EnvTypePair pair = analyzeExprBwd(expr.getLastChild(), outEnv, requiredType);
pair.env = analyzeExprBwd(expr.getFirstChild(), pair.env).env;
return pair;
}
case NOT:
{
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), outEnv);
pair.type = pair.type.negate();
return pair;
}
case GETELEM:
return analyzeGetElemBwd(expr, outEnv, requiredType);
case VOID:
{
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), outEnv);
pair.type = UNDEFINED;
return pair;
}
case IN:
return analyzeInBwd(expr, outEnv);
case DELPROP:
{
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), outEnv);
pair.type = BOOLEAN;
return pair;
}
case VAR:
{
// Can happen iff its parent is a for/in or for/of.
Node vdecl = expr.getFirstChild();
String name = vdecl.getString();
// For/in and for/of can never have rhs of its VAR
checkState(!vdecl.hasChildren());
return new EnvTypePair(envPutType(outEnv, name, UNKNOWN), UNKNOWN);
}
case REGEXP:
return new EnvTypePair(outEnv, commonTypes.getRegexpType());
case ARRAYLIT:
return analyzeArrayLitBwd(expr, outEnv);
case CAST:
{
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), outEnv);
pair.type = (JSType) expr.getTypeI();
return pair;
}
case TEMPLATELIT:
return analyzeTemplateLitBwd(expr, outEnv);
case TEMPLATELIT_SUB:
return analyzeExprBwd(expr.getFirstChild(), outEnv, requiredType);
case STRING_KEY:
if (expr.hasChildren()) {
return analyzeExprBwd(expr.getFirstChild(), outEnv, requiredType);
} else {
return analyzeNameBwd(expr, outEnv, requiredType);
}
case MEMBER_FUNCTION_DEF:
return analyzeExprBwd(expr.getFirstChild(), outEnv, requiredType);
case COMPUTED_PROP:
TypeEnv env = analyzeExprBwd(expr.getSecondChild(), outEnv).env;
return analyzeExprBwd(expr.getFirstChild(), env);
case YIELD:
{
if (expr.hasChildren()) {
EnvTypePair pair = analyzeExprBwd(expr.getFirstChild(), outEnv);
pair.type = UNKNOWN;
return pair;
} else {
return new EnvTypePair(outEnv, UNKNOWN);
}
}
default:
throw new RuntimeException("BWD: Unhandled expression type: " + expr.getToken() + " with parent: " + expr.getParent());
}
}
Aggregations