use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.
the class TypeInference method traverseAssign.
@CheckReturnValue
private FlowScope traverseAssign(Node n, FlowScope scope) {
Node target = n.getFirstChild();
Node value = n.getLastChild();
if (target.isDestructuringPattern()) {
scope = traverse(value, scope);
JSType valueType = getJSType(value);
n.setJSType(valueType);
return traverseDestructuringPattern(target, scope, valueType, AssignmentType.ASSIGN);
} else {
scope = traverseChildren(n, scope);
JSType valueType = getJSType(value);
n.setJSType(valueType);
return updateScopeForAssignment(scope, target, valueType, AssignmentType.ASSIGN);
}
}
use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.
the class SemanticReverseAbstractInterpreter method caseIn.
/**
* Given 'property in object', ensures that the object has the property in the informed scope by
* defining it as a qualified name if the object type lacks the property and it's not in the blind
* scope.
*
* @param object The node of the right-side of the in.
* @param propertyName The string of the left-side of the in.
*/
@CheckReturnValue
private FlowScope caseIn(Node object, String propertyName, FlowScope blindScope) {
JSType jsType = object.getJSType();
jsType = jsType != null ? jsType.restrictByNotNullOrUndefined() : null;
boolean hasProperty = false;
ObjectType objectType = ObjectType.cast(jsType);
if (objectType != null) {
hasProperty = objectType.hasProperty(propertyName);
}
if (!hasProperty) {
String qualifiedName = object.getQualifiedName();
if (qualifiedName != null) {
String propertyQualifiedName = qualifiedName + "." + propertyName;
if (blindScope.getSlot(propertyQualifiedName) == null) {
JSType unknownType = typeRegistry.getNativeType(JSTypeNative.UNKNOWN_TYPE);
return blindScope.inferQualifiedSlot(object, propertyQualifiedName, unknownType, unknownType, false);
}
}
}
return blindScope;
}
use of com.google.errorprone.annotations.CheckReturnValue 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);
}
use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.
the class SemanticReverseAbstractInterpreter method caseAndOrMaybeShortCircuiting.
@CheckReturnValue
private FlowScope caseAndOrMaybeShortCircuiting(Node left, Node right, FlowScope blindScope, Outcome outcome) {
// Perform two separate refinements, one for if short-circuiting occurred, and one for if it did
// not. Because it's not clear whether short-circuiting occurred, we actually have to ignore
// both separate result flow scopes individually, but if they both refined the same slot, we
// can join the two refinements. TODO(sdh): look into simplifying this. If joining were
// more efficient, we should just be able to join the scopes unconditionally?
Set<String> refinements = new HashSet<>();
blindScope = new RefinementTrackingFlowScope(blindScope, refinements);
FlowScope leftScope = firstPreciserScopeKnowingConditionOutcome(left, blindScope, outcome.not());
StaticTypedSlot leftVar = refinements.size() == 1 ? leftScope.getSlot(refinements.iterator().next()) : null;
if (leftVar == null) {
// must create a child instead.
return unwrap(blindScope);
}
refinements.clear();
// Note: re-wrap the scope, in case it was unwrapped by a nested call to this method.
FlowScope rightScope = new RefinementTrackingFlowScope(firstPreciserScopeKnowingConditionOutcome(left, blindScope, outcome), refinements);
rightScope = firstPreciserScopeKnowingConditionOutcome(right, rightScope, outcome.not());
StaticTypedSlot rightVar = refinements.size() == 1 ? rightScope.getSlot(refinements.iterator().next()) : null;
if (rightVar == null || !leftVar.getName().equals(rightVar.getName())) {
return unwrap(blindScope);
}
JSType type = leftVar.getType().getLeastSupertype(rightVar.getType());
return unwrap(blindScope).inferSlotType(leftVar.getName(), type);
}
use of com.google.errorprone.annotations.CheckReturnValue in project closure-compiler by google.
the class SemanticReverseAbstractInterpreter method caseAndOrNotShortCircuiting.
@CheckReturnValue
private FlowScope caseAndOrNotShortCircuiting(Node left, Node right, FlowScope blindScope, Outcome outcome) {
// left type
JSType leftType = getTypeIfRefinable(left, blindScope);
boolean leftIsRefineable;
if (leftType != null) {
leftIsRefineable = true;
} else {
leftIsRefineable = false;
leftType = left.getJSType();
blindScope = firstPreciserScopeKnowingConditionOutcome(left, blindScope, outcome);
}
// restricting left type
JSType restrictedLeftType = (leftType == null) ? null : leftType.getRestrictedTypeGivenOutcome(outcome);
if (restrictedLeftType == null) {
return firstPreciserScopeKnowingConditionOutcome(right, blindScope, outcome);
}
blindScope = maybeRestrictName(blindScope, left, leftType, leftIsRefineable ? restrictedLeftType : null);
// right type
JSType rightType = getTypeIfRefinable(right, blindScope);
boolean rightIsRefineable;
if (rightType != null) {
rightIsRefineable = true;
} else {
rightIsRefineable = false;
rightType = right.getJSType();
blindScope = firstPreciserScopeKnowingConditionOutcome(right, blindScope, outcome);
}
if (outcome.isTruthy()) {
JSType restrictedRightType = (rightType == null) ? null : rightType.getRestrictedTypeGivenOutcome(outcome);
// creating new scope
return maybeRestrictName(blindScope, right, rightType, rightIsRefineable ? restrictedRightType : null);
}
return blindScope;
}
Aggregations