use of com.google.javascript.rhino.Token in project closure-compiler by google.
the class SemanticReverseAbstractInterpreterTest method testInequalitiesCondition1.
/**
* Tests reverse interpretation of a COMPARE(NAME, NUMBER) expression, where COMPARE can be LE,
* LT, GE or GT.
*/
@Test
public void testInequalitiesCondition1() {
for (Token op : Arrays.asList(Token.LT, Token.GT, Token.LE, Token.GE)) {
FlowScope[] blind = newScope();
testBinop(blind, op, createVar(blind, "a", createUnionType(getNativeStringType(), getNativeVoidType())), createNumber(8), 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 TypeInferencePass method inferAllScopes.
/**
* Execute type inference running over part of the scope tree.
*
* @return the top scope, either newly created, or patched by this inference.
*/
TypedScope inferAllScopes(Node inferenceRoot) {
// order to propagate the type of ns.method in the outer scope.
try (JSTypeResolver.Closer closer = this.registry.getResolver().openForDefinition()) {
checkState(inferenceRoot.isRoot());
checkState(inferenceRoot.getParent() == null);
checkState(this.topScope == null);
this.topScope = scopeCreator.createScope(inferenceRoot, null);
NodeTraversal.builder().setCompiler(compiler).setCallback(new FirstScopeBuildingCallback()).setScopeCreator(scopeCreator).traverseWithScope(inferenceRoot, this.topScope);
scopeCreator.resolveWeakImportsPreResolution();
}
scopeCreator.finishAndFreeze();
NodeTraversal.builder().setCompiler(compiler).setCallback(new SecondScopeBuildingCallback()).setScopeCreator(scopeCreator).traverseWithScope(inferenceRoot, this.topScope);
// Normalize TypedVars to have the '?' type instead of null after inference is complete. This
// currently cannot be done any earlier because it breaks inference of variables assigned in
// local scopes.
// TODO(b/149843534): this should be a crash instead.
final JSType unknownType = this.registry.getNativeType(UNKNOWN_TYPE);
for (TypedVar var : this.scopeCreator.getAllSymbols()) {
if (var.getType() == null) {
var.setType(unknownType);
}
}
if (this.stepCountHistogram != null) {
try (LogFile histogram = this.compiler.createOrReopenLog(this.getClass(), "step_histogram.log")) {
histogram.log("step_count token population");
int[] totals = new int[] { 0, 0 };
this.stepCountHistogram.keySet().stream().sorted(Comparator.<Integer>naturalOrder().reversed()).forEach((stepCount) -> this.stepCountHistogram.get(stepCount).entrySet().stream().sorted(comparingInt(Multiset.Entry::getCount)).forEach((e) -> {
totals[0] += stepCount * e.getCount();
totals[1] += e.getCount();
histogram.log("%s %s %s", stepCount, e.getElement(), e.getCount());
}));
histogram.log("%s TOTAL %s", totals[0], totals[1]);
}
}
return this.topScope;
}
use of com.google.javascript.rhino.Token in project closure-compiler by google.
the class CollectFunctionNames method collectObjectLiteralMethodsNames.
/**
* Sets names in the functionNames map for unnamed functions inside object literals,
* and recursively visits nested object literals.
* @param objectLiteral The object literal node to visit.
* @param context Represents the qualified name "so far"
*/
private void collectObjectLiteralMethodsNames(Node objectLiteral, String context) {
for (Node keyNode = objectLiteral.getFirstChild(); keyNode != null; keyNode = keyNode.getNext()) {
Node valueNode = keyNode.getFirstChild();
// TODO(lharker): Find a way to name Get, Set, and CompProp keys.
if (keyNode.isStringKey() || keyNode.isMemberFunctionDef()) {
// concatenate the context and key name to get a new qualified name.
String name = combineNames(context, extractor.getName(keyNode));
Token type = valueNode.getToken();
if (type == Token.FUNCTION) {
Node functionNameNode = valueNode.getFirstChild();
String functionName = functionNameNode.getString();
if (functionName.isEmpty()) {
functionNames.setFunctionName(name, valueNode);
}
} else if (type == Token.OBJECTLIT) {
// process nested object literal
collectObjectLiteralMethodsNames(valueNode, name);
}
}
}
}
use of com.google.javascript.rhino.Token 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.rhino.Token in project closure-compiler by google.
the class SemanticReverseAbstractInterpreter method getPreciserScopeKnowingConditionOutcome.
@Override
public FlowScope getPreciserScopeKnowingConditionOutcome(Node condition, FlowScope blindScope, boolean 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.isString()) {
typeOfNode = left;
stringNode = right;
} else if (right.isTypeOf() && left.isString()) {
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) {
resultEqualsValue = !resultEqualsValue;
}
return caseTypeOf(operandNode, operandType, stringNode.getString(), resultEqualsValue, blindScope);
}
}
break;
default:
break;
}
switch(operatorToken) {
case AND:
if (outcome) {
return caseAndOrNotShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, true);
} else {
return caseAndOrMaybeShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, true);
}
case OR:
if (!outcome) {
return caseAndOrNotShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, false);
} else {
return caseAndOrMaybeShortCircuiting(condition.getFirstChild(), condition.getLastChild(), blindScope, false);
}
case EQ:
if (outcome) {
return caseEquality(condition, blindScope, EQ);
} else {
return caseEquality(condition, blindScope, NE);
}
case NE:
if (outcome) {
return caseEquality(condition, blindScope, NE);
} else {
return caseEquality(condition, blindScope, EQ);
}
case SHEQ:
if (outcome) {
return caseEquality(condition, blindScope, SHEQ);
} else {
return caseEquality(condition, blindScope, SHNE);
}
case SHNE:
if (outcome) {
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);
case LE:
case LT:
case GE:
case GT:
if (outcome) {
return caseEquality(condition, blindScope, ineq);
}
break;
case INSTANCEOF:
return caseInstanceOf(condition.getFirstChild(), condition.getLastChild(), blindScope, outcome);
case IN:
if (outcome && condition.getFirstChild().isString()) {
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) {
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