use of com.google.template.soy.soytree.SwitchCaseNode in project closure-templates by google.
the class SoyNodeCompiler method visitSwitchNode.
@Override
protected Statement visitSwitchNode(SwitchNode node) {
// A few special cases:
// 1. only a {default} block. In this case we can skip all the switch logic and temporaries
// 2. no children. Just return the empty statement
// Note that in both of these cases we do not evalutate (or generate code) for the switch
// expression.
List<BlockNode> children = node.getChildren();
if (children.isEmpty()) {
return Statement.NULL_STATEMENT;
}
if (children.size() == 1 && children.get(0) instanceof SwitchDefaultNode) {
return visitChildrenInNewScope(children.get(0));
}
// otherwise we need to evaluate the switch variable and generate dispatching logic.
SoyExpression switchVar = exprCompiler.compile(node.getExpr());
Scope scope = variables.enterScope();
Variable variable = scope.createSynthetic(SyntheticVarName.forSwitch(node), switchVar, STORE);
Statement initializer = variable.initializer();
switchVar = switchVar.withSource(variable.local());
List<IfBlock> cases = new ArrayList<>();
Optional<Statement> defaultBlock = Optional.absent();
for (SoyNode child : children) {
if (child instanceof SwitchCaseNode) {
SwitchCaseNode caseNode = (SwitchCaseNode) child;
Label reattachPoint = new Label();
List<Expression> comparisons = new ArrayList<>();
for (ExprRootNode caseExpr : caseNode.getExprList()) {
comparisons.add(compareSoyEquals(switchVar, exprCompiler.compile(caseExpr, reattachPoint)));
}
Expression condition = BytecodeUtils.logicalOr(comparisons).labelStart(reattachPoint);
Statement block = visitChildrenInNewScope(caseNode);
cases.add(IfBlock.create(condition, block));
} else {
SwitchDefaultNode defaultNode = (SwitchDefaultNode) child;
defaultBlock = Optional.of(visitChildrenInNewScope(defaultNode));
}
}
Statement exitScope = scope.exitScope();
// generation that we could maybe use
return Statement.concat(initializer, ControlFlow.ifElseChain(cases, defaultBlock), exitScope);
}
use of com.google.template.soy.soytree.SwitchCaseNode in project closure-templates by google.
the class GenJsCodeVisitor method visitSwitchNode.
/**
* Example:
*
* <pre>
* {switch $boo}
* {case 0}
* ...
* {case 1, 2}
* ...
* {default}
* ...
* {/switch}
* </pre>
*
* might generate
*
* <pre>
* switch (opt_data.boo) {
* case 0:
* ...
* break;
* case 1:
* case 2:
* ...
* break;
* default:
* ...
* }
* </pre>
*/
@Override
protected void visitSwitchNode(SwitchNode node) {
CodeChunk.WithValue switchOn = coerceTypeForSwitchComparison(node.getExpr());
SwitchBuilder switchBuilder = switch_(switchOn);
for (SoyNode child : node.getChildren()) {
if (child instanceof SwitchCaseNode) {
SwitchCaseNode scn = (SwitchCaseNode) child;
ImmutableList.Builder<CodeChunk.WithValue> caseChunks = ImmutableList.builder();
for (ExprNode caseExpr : scn.getExprList()) {
CodeChunk.WithValue caseChunk = translateExpr(caseExpr);
caseChunks.add(caseChunk);
}
CodeChunk body = visitChildrenReturningCodeChunk(scn);
switchBuilder.case_(caseChunks.build(), body);
} else if (child instanceof SwitchDefaultNode) {
CodeChunk body = visitChildrenReturningCodeChunk((SwitchDefaultNode) child);
switchBuilder.default_(body);
} else {
throw new AssertionError();
}
}
jsCodeBuilder.append(switchBuilder.build());
}
use of com.google.template.soy.soytree.SwitchCaseNode in project closure-templates by google.
the class TemplateParserTest method testParseSwitchStmt.
@Test
public void testParseSwitchStmt() throws Exception {
String templateBody = "{@param boo: ?}{@param foo : ?}{@param moo : ?}\n" + " {switch $boo} {case 0}Blah\n" + " {case $foo.goo}\n" + " Bleh\n" + " {case -1, 1, $moo}\n" + " Bluh\n" + " {default}\n" + " Bloh\n" + " {/switch}\n";
List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
assertEquals(1, nodes.size());
SwitchNode sn = (SwitchNode) nodes.get(0);
assertEquals("$boo", sn.getExpr().toSourceString());
assertTrue(sn.getExpr().getRoot() instanceof VarRefNode);
assertEquals(4, sn.numChildren());
SwitchCaseNode scn0 = (SwitchCaseNode) sn.getChild(0);
assertEquals(1, scn0.getExprList().size());
assertTrue(scn0.getExprList().get(0).getRoot() instanceof IntegerNode);
assertEquals(0, ((IntegerNode) scn0.getExprList().get(0).getRoot()).getValue());
SwitchCaseNode scn1 = (SwitchCaseNode) sn.getChild(1);
assertEquals(1, scn1.getExprList().size());
assertTrue(scn1.getExprList().get(0).getRoot() instanceof FieldAccessNode);
assertEquals("$foo.goo", scn1.getExprList().get(0).getRoot().toSourceString());
SwitchCaseNode scn2 = (SwitchCaseNode) sn.getChild(2);
assertEquals(3, scn2.getExprList().size());
assertTrue(scn2.getExprList().get(0).getRoot() instanceof IntegerNode);
assertTrue(scn2.getExprList().get(1).getRoot() instanceof IntegerNode);
assertTrue(scn2.getExprList().get(2).getRoot() instanceof VarRefNode);
assertEquals("-1", scn2.getExprList().get(0).getRoot().toSourceString());
assertEquals("1", scn2.getExprList().get(1).getRoot().toSourceString());
assertEquals("$moo", scn2.getExprList().get(2).getRoot().toSourceString());
assertEquals("Bluh", ((RawTextNode) scn2.getChild(0)).getRawText());
assertEquals("Bloh", ((RawTextNode) ((SwitchDefaultNode) sn.getChild(3)).getChild(0)).getRawText());
assertEquals("{switch $boo}{case 0}Blah{case $foo.goo}Bleh{case -1, 1, $moo}Bluh{default}Bloh{/switch}", sn.toSourceString());
}
Aggregations