private JsExprStmt extractPrototypeSetup(
final LivenessPredicate livenessPredicate,
final LivenessPredicate alreadyLoadedPredicate, JsStatement stat,
final JClassType vtableTypeAssigned) {
final boolean[] anyLiveCode = new boolean[1];
Cloner c = new Cloner() {
@Override
public void endVisit(JsBinaryOperation x, JsContext ctx) {
JsExpression rhs = stack.pop();
JsNameRef lhs = (JsNameRef) stack.pop();
if (rhs instanceof JsNew || rhs instanceof JsObjectLiteral) {
// The super op is being assigned to the seed prototype.
if (alreadyLoadedPredicate.isLive(vtableTypeAssigned)) {
stack.push(lhs);
return;
} else {
anyLiveCode[0] = true;
}
} else if (lhs.getQualifier() == null) {
// The underscore is being assigned to.
assert "_".equals(lhs.getIdent());
} else {
// A constructor function is being assigned to.
assert "prototype".equals(lhs.getIdent());
JsNameRef ctorRef = (JsNameRef) lhs.getQualifier();
JConstructor ctor = (JConstructor) map.nameToMethod(ctorRef.getName());
assert ctor != null;
if (livenessPredicate.isLive(ctor)
&& !alreadyLoadedPredicate.isLive(ctor)) {
anyLiveCode[0] = true;
} else {
stack.push(rhs);
return;
}
}
JsBinaryOperation toReturn = new JsBinaryOperation(x.getSourceInfo(),
x.getOperator());
toReturn.setArg2(rhs);
toReturn.setArg1(lhs);
stack.push(toReturn);
}
};
c.accept(((JsExprStmt) stat).getExpression());
JsExprStmt result = anyLiveCode[0] ? c.getExpression().makeStmt() : null;
return result;
}