* emit its value to a variable "moduleResult___" so that it can used as
* the result of module loading.
*/
@SuppressWarnings("unchecked")
public ParseTreeNode returnLast(ParseTreeNode node) {
ParseTreeNode result = null;
// Code translated from another language should not be used as the module
// result.
if (isForSideEffect(node)) { return node; }
if (node instanceof ExpressionStmt) {
result = new ExpressionStmt(
node.getFilePosition(),
(Expression) QuasiBuilder.substV(
"moduleResult___ = @result;",
"result", ((ExpressionStmt) node).getExpression()));
} else if (node instanceof ParseTreeNodeContainer) {
List<ParseTreeNode> nodes = Lists.newArrayList(node.children());
int lasti = lastRealJavascriptChild(nodes);
if (lasti >= 0) {
nodes.set(lasti, returnLast(nodes.get(lasti)));
result = new ParseTreeNodeContainer(nodes);
}
} else if (node instanceof Block) {
List<Statement> stats = Lists.newArrayList();
stats.addAll((Collection<? extends Statement>) node.children());
int lasti = lastRealJavascriptChild(stats);
if (lasti >= 0) {
stats.set(lasti, (Statement) returnLast(stats.get(lasti)));
result = new Block(node.getFilePosition(), stats);
}
} else if (node instanceof Conditional) {
List<ParseTreeNode> nodes = Lists.newArrayList();
nodes.addAll(node.children());
int lasti = nodes.size() - 1;
for (int i = 1; i <= lasti; i += 2) { // Even are conditions.
nodes.set(i, returnLast(nodes.get(i)));
}
if ((lasti & 1) == 0) { // else clause
nodes.set(lasti, returnLast(nodes.get(lasti)));
}
result = new Conditional(node.getFilePosition(), null, nodes);
} else if (node instanceof TryStmt) {
TryStmt tryer = (TryStmt) node;
result = new TryStmt(
node.getFilePosition(),
(Block) returnLast(tryer.getBody()),
tryer.getCatchClause(),
tryer.getFinallyClause());
}
if (null == result) { return node; }
result.getAttributes().putAll(node.getAttributes());
return result;
}