Code with Finding: |
class ExpressionDecomposer {
/**
* Rewrite the call so "this" is preserved.
* a.b(c);
* becomes:
* var temp1 = a;
* var temp0 = temp1.b;
* temp0.call(temp1,c);
*
* @return The replacement node.
*/
private Node rewriteCallExpression(Node call, DecompositionState state) {
Preconditions.checkArgument(call.getType() == Token.CALL);
Node first = call.getFirstChild();
Preconditions.checkArgument(NodeUtil.isGet(first));
// Extracts the expression representing the function to call. For example:
// "a['b'].c" from "a['b'].c()"
Node getVarNode = extractExpression(
first, state.extractBeforeStatement);
state.extractBeforeStatement = getVarNode;
// Extracts the object reference to be used as "this". For example:
// "a['b']" from "a['b'].c"
Node getExprNode = getVarNode.getFirstChild().getFirstChild();
Preconditions.checkArgument(NodeUtil.isGet(getExprNode));
Node thisVarNode = extractExpression(
getExprNode.getFirstChild(), state.extractBeforeStatement);
state.extractBeforeStatement = thisVarNode;
// Rewrite the CALL expression.
Node thisNameNode = thisVarNode.getFirstChild();
Node functionNameNode = getVarNode.getFirstChild();
// CALL
// GETPROP
// functionName
// "call"
// thisName
// original-parameter1
// original-parameter2
// ...
Node newCall = new Node(Token.CALL,
new Node(Token.GETPROP,
functionNameNode.cloneNode(),
Node.newString("call")),
thisNameNode.cloneNode(), call.getLineno(), call.getCharno());
// Throw away the call name
call.removeFirstChild();
if (call.hasChildren()) {
// Add the call parameters to the new call.
newCall.addChildrenToBack(call.removeChildren());
}
// Replace the call.
Node callParent = call.getParent();
callParent.replaceChild(call, newCall);
return newCall;
}
}
|