if (!x.getArg1().hasSideEffects()) {
ctx.replaceMe(x.getArg2());
return;
}
JsBinaryOperation toUpdate = isComma(x.getArg2());
if (toUpdate == null) {
/*
* We have a JsBinaryOperation that's structurally normal: (X, a). Now
* it may be the case that the inner expression X is a comma expression
* (Y, b). If b creates no side-effects, we can remove it, leaving (Y,
* a) as the expression.
*/
JsBinaryOperation inner = isComma(x.getArg1());
if (inner != null && !inner.getArg2().hasSideEffects()) {
x.setArg1(inner.getArg1());
didChange = true;
}
/*
* Eliminate the pattern (localVar = expr, localVar). This tends to
* occur when a method interacted with pruned fields or had statements
* removed.
*/
JsName assignmentRef = null;
JsExpression expr = null;
JsName returnRef = null;
if (x.getArg1() instanceof JsBinaryOperation) {
JsBinaryOperation op = (JsBinaryOperation) x.getArg1();
if (op.getOperator() == JsBinaryOperator.ASG
&& op.getArg1() instanceof JsNameRef) {
JsNameRef nameRef = (JsNameRef) op.getArg1();
if (nameRef.getQualifier() == null) {
assignmentRef = nameRef.getName();
expr = op.getArg2();
}
}
}
if (x.getArg2() instanceof JsNameRef) {
JsNameRef nameRef = (JsNameRef) x.getArg2();
if (nameRef.getQualifier() == null) {
returnRef = nameRef.getName();
}
}
if (assignmentRef != null && assignmentRef.equals(returnRef)
&& localVariableNames.contains(assignmentRef)) {
assert expr != null;
localVariableNames.remove(assignmentRef);
ctx.replaceMe(expr);
}
return;
}
// Find the left-most, nested comma expression
while (isComma(toUpdate.getArg1()) != null) {
toUpdate = (JsBinaryOperation) toUpdate.getArg1();
}
/*
* Create a new comma expression with the original LHS and the LHS of the
* nested comma expression.
*/
JsBinaryOperation newOp = new JsBinaryOperation(
x.getSourceInfo().makeChild(CommaNormalizer.class,
"Simplifying comma expression"), JsBinaryOperator.COMMA);
newOp.setArg1(x.getArg1());
newOp.setArg2(toUpdate.getArg1());
// Set the LHS of the nested comma expression to the new comma expression
toUpdate.setArg1(newOp);
// Replace the original node with its updated RHS