use of com.google.javascript.rhino.Token in project closure-compiler by google.
the class AstValidator method validateCompoundAssignmentExpression.
private void validateCompoundAssignmentExpression(Node n) {
validateProperties(n);
validateChildCount(n);
Token contextType = n.getToken();
Node lhs = n.getFirstChild();
validateAssignmentOpTarget(lhs, contextType);
validateExpression(n.getLastChild());
}
use of com.google.javascript.rhino.Token in project closure-compiler by google.
the class SemanticReverseAbstractInterpreterTest method testInequalitiesCondition2.
/**
* Tests reverse interpretation of a COMPARE(NAME, NAME) expression, where COMPARE can be LE, LT,
* GE or GT.
*/
@Test
public void testInequalitiesCondition2() {
for (Token op : Arrays.asList(Token.LT, Token.GT, Token.LE, Token.GE)) {
FlowScope[] blind = newScope();
testBinop(blind, op, createVar(blind, "a", createUnionType(getNativeStringType(), getNativeNumberType(), getNativeVoidType())), createVar(blind, "b", createUnionType(getNativeNumberType(), getNativeNullType())), ImmutableSet.of(new TypedName("a", createUnionType(getNativeStringType(), getNativeNumberType())), new TypedName("b", createUnionType(getNativeNumberType(), getNativeNullType()))), ImmutableSet.of(new TypedName("a", createUnionType(getNativeStringType(), getNativeNumberType(), getNativeVoidType())), new TypedName("b", createUnionType(getNativeNumberType(), getNativeNullType()))));
}
}
use of com.google.javascript.rhino.Token in project closure-compiler by google.
the class SemanticReverseAbstractInterpreterTest method testInequalitiesCondition3.
/**
* Tests reverse interpretation of a COMPARE(NUMBER-untyped, NAME) expression, where COMPARE can
* be LE, LT, GE or GT.
*/
@Test
public void testInequalitiesCondition3() {
for (Token op : Arrays.asList(Token.LT, Token.GT, Token.LE, Token.GE)) {
FlowScope[] blind = newScope();
testBinop(blind, op, createUntypedNumber(8), createVar(blind, "a", createUnionType(getNativeStringType(), getNativeVoidType())), ImmutableSet.of(new TypedName("a", getNativeStringType())), ImmutableSet.of(new TypedName("a", createUnionType(getNativeStringType(), getNativeVoidType()))));
}
}
use of com.google.javascript.rhino.Token in project closure-compiler by google.
the class TypeCheck method visitName.
/**
* Visits a NAME node.
*
* @param t The node traversal object that supplies context, such as the scope chain to use in
* name lookups as well as error reporting.
* @param n The node being visited.
* @return whether the node is typeable or not
*/
boolean visitName(NodeTraversal t, Node n, Node parent) {
// Skip empty function expression names. They don't need a type.
boolean isFunctionName = n.getParent().isFunction() && n.isFirstChildOf(parent);
if (isFunctionName && n.getString().isEmpty()) {
return false;
}
// the compiler's unknown type reporting allows certain names to be untyped if declared but
// never used in an expression. The associated AST nodes still need to be typed to prevent
// future passes from crashing, though.
boolean reportIfMissingType = true;
// At this stage, we need to determine whether this is a leaf
// node in an expression (which therefore needs to have a type
// assigned for it) versus some other decorative node that we
// can safely ignore.
Token parentNodeType = parent.getToken();
if (isFunctionName || parentNodeType == Token.CATCH || parentNodeType == Token.PARAM_LIST || NodeUtil.isNameDeclaration(parent)) {
reportIfMissingType = false;
}
// Not need to type first key in for-in or for-of.
if (NodeUtil.isEnhancedFor(parent) && parent.getFirstChild() == n) {
reportIfMissingType = false;
}
JSType type = n.getJSType();
if (type == null) {
type = getNativeType(UNKNOWN_TYPE);
// TODO(b/149843534): crash instead of defaulting to '?' when the var is null.
TypedVar var = t.getTypedScope().getVar(n.getString());
if (var != null) {
type = checkNotNull(var.getType());
}
}
ensureTyped(n, type);
return reportIfMissingType;
}
use of com.google.javascript.rhino.Token in project closure-compiler by google.
the class SemanticReverseAbstractInterpreter method getPreciserScopeKnowingConditionOutcome.
@Override
@CheckReturnValue
public FlowScope getPreciserScopeKnowingConditionOutcome(Node condition, FlowScope blindScope, Outcome outcome) {
// Check for the typeof operator.
Token operatorToken = condition.getToken();
switch(operatorToken) {
case EQ:
case NE:
case SHEQ:
case SHNE:
case CASE:
Node left;
Node right;
if (operatorToken == Token.CASE) {
// the switch condition
left = condition.getParent().getFirstChild();
right = condition.getFirstChild();
} else {
left = condition.getFirstChild();
right = condition.getLastChild();
}
Node typeOfNode = null;
Node stringNode = null;
if (left.isTypeOf() && right.isStringLit()) {
typeOfNode = left;
stringNode = right;
} else if (right.isTypeOf() && left.isStringLit()) {
typeOfNode = right;
stringNode = left;
}
if (typeOfNode != null && stringNode != null) {
Node operandNode = typeOfNode.getFirstChild();
JSType operandType = getTypeIfRefinable(operandNode, blindScope);
if (operandType != null) {
boolean resultEqualsValue = operatorToken == Token.EQ || operatorToken == Token.SHEQ || operatorToken == Token.CASE;
if (!outcome.isTruthy()) {
resultEqualsValue = !resultEqualsValue;
}
return caseTypeOf(operandNode, operandType, stringNode.getString(), resultEqualsValue, blindScope);
}
}
break;
default:
break;
}
switch(operatorToken) {
case AND:
if (outcome.isTruthy()) {
return caseAndOrNotShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.TRUE);
} else {
return caseAndOrMaybeShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.TRUE);
}
case OR:
if (!outcome.isTruthy()) {
return caseAndOrNotShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.FALSE);
} else {
return caseAndOrMaybeShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, Outcome.FALSE);
}
case EQ:
if (outcome.isTruthy()) {
return caseEquality(condition, blindScope, EQ);
} else {
return caseEquality(condition, blindScope, NE);
}
case NE:
if (outcome.isTruthy()) {
return caseEquality(condition, blindScope, NE);
} else {
return caseEquality(condition, blindScope, EQ);
}
case SHEQ:
if (outcome.isTruthy()) {
return caseEquality(condition, blindScope, SHEQ);
} else {
return caseEquality(condition, blindScope, SHNE);
}
case SHNE:
if (outcome.isTruthy()) {
return caseEquality(condition, blindScope, SHNE);
} else {
return caseEquality(condition, blindScope, SHEQ);
}
case NAME:
case GETPROP:
return caseNameOrGetProp(condition, blindScope, outcome);
case ASSIGN:
return firstPreciserScopeKnowingConditionOutcome(condition.getFirstChild(), firstPreciserScopeKnowingConditionOutcome(condition.getSecondChild(), blindScope, outcome), outcome);
case NOT:
return firstPreciserScopeKnowingConditionOutcome(condition.getFirstChild(), blindScope, outcome.not());
case LE:
case LT:
case GE:
case GT:
if (outcome.isTruthy()) {
return caseEquality(condition, blindScope, ineq);
}
break;
case INSTANCEOF:
return caseInstanceOf(condition.getFirstChild(), condition.getLastChild(), blindScope, outcome);
case IN:
if (outcome.isTruthy() && condition.getFirstChild().isStringLit()) {
return caseIn(condition.getLastChild(), condition.getFirstChild().getString(), blindScope);
}
break;
case CASE:
{
Node left = // the switch condition
condition.getParent().getFirstChild();
Node right = condition.getFirstChild();
if (outcome.isTruthy()) {
return caseEquality(left, right, blindScope, SHEQ);
} else {
return caseEquality(left, right, blindScope, SHNE);
}
}
case CALL:
{
Node left = condition.getFirstChild();
String leftName = left.getQualifiedName();
if ("Array.isArray".equals(leftName) && left.getNext() != null) {
return caseIsArray(left.getNext(), blindScope, outcome);
}
break;
}
default:
break;
}
return nextPreciserScopeKnowingConditionOutcome(condition, blindScope, outcome);
}
Aggregations