in rhino/src/main/java/org/mozilla/javascript/optimizer/Block.java [457:570]
private static int findExpressionType(OptFunctionNode fn, Node n, int[] varTypes) {
switch (n.getType()) {
case Token.NUMBER:
return Optimizer.NumberType;
case Token.CALL:
case Token.NEW:
case Token.REF_CALL:
return Optimizer.AnyType;
case Token.GETELEM:
case Token.GETPROP:
case Token.NAME:
case Token.THIS:
return Optimizer.AnyType;
case Token.GETVAR:
return varTypes[fn.getVarIndex(n)];
case Token.INC:
case Token.DEC:
case Token.MUL:
case Token.DIV:
case Token.MOD:
case Token.EXP:
case Token.BITOR:
case Token.BITXOR:
case Token.BITAND:
case Token.BITNOT:
case Token.LSH:
case Token.RSH:
case Token.URSH:
case Token.SUB:
case Token.POS:
case Token.NEG:
return Optimizer.NumberType;
case Token.VOID:
// NYI: undefined type
return Optimizer.AnyType;
case Token.FALSE:
case Token.TRUE:
case Token.EQ:
case Token.NE:
case Token.LT:
case Token.LE:
case Token.GT:
case Token.GE:
case Token.SHEQ:
case Token.SHNE:
case Token.NOT:
case Token.INSTANCEOF:
case Token.IN:
case Token.DEL_REF:
case Token.DELPROP:
// NYI: boolean type
return Optimizer.AnyType;
case Token.STRING:
case Token.TYPEOF:
case Token.TYPEOFNAME:
// NYI: string type
return Optimizer.AnyType;
case Token.NULL:
case Token.REGEXP:
case Token.ARRAYCOMP:
case Token.ARRAYLIT:
case Token.OBJECTLIT:
case Token.TEMPLATE_LITERAL:
case Token.BIGINT:
return Optimizer.AnyType; // XXX: actually, we know it's not
// number, but no type yet for that
case Token.ADD:
{
// if the lhs & rhs are known to be numbers, we can be sure that's
// the result, otherwise it could be a string.
Node child = n.getFirstChild();
int lType = findExpressionType(fn, child, varTypes);
int rType = findExpressionType(fn, child.getNext(), varTypes);
return lType | rType; // we're not distinguishing strings yet
}
case Token.HOOK:
{
Node ifTrue = n.getFirstChild().getNext();
Node ifFalse = ifTrue.getNext();
int ifTrueType = findExpressionType(fn, ifTrue, varTypes);
int ifFalseType = findExpressionType(fn, ifFalse, varTypes);
return ifTrueType | ifFalseType;
}
case Token.COMMA:
case Token.SETVAR:
case Token.SETCONSTVAR:
case Token.SETNAME:
case Token.SETPROP:
case Token.SETELEM:
return findExpressionType(fn, n.getLastChild(), varTypes);
case Token.AND:
case Token.OR:
{
Node child = n.getFirstChild();
int lType = findExpressionType(fn, child, varTypes);
int rType = findExpressionType(fn, child.getNext(), varTypes);
return lType | rType;
}
}
return Optimizer.AnyType;
}