Search in sources :

Example 1 with IfCondNode

use of com.google.template.soy.soytree.IfCondNode in project closure-templates by google.

the class GenJsCodeVisitor method generateNonExpressionIfNode.

/**
 * Generates the JavaScript code for an {if} block that cannot be done as an expression.
 *
 * <p>TODO(user): Instead of interleaving JsCodeBuilders like this, consider refactoring
 * GenJsCodeVisitor to return CodeChunks for each sub-Template level SoyNode.
 */
protected void generateNonExpressionIfNode(IfNode node) {
    ConditionalBuilder conditional = null;
    for (SoyNode child : node.getChildren()) {
        if (child instanceof IfCondNode) {
            IfCondNode condNode = (IfCondNode) child;
            // Convert predicate.
            CodeChunk.WithValue predicate = translateExpr(condNode.getExpr());
            // Convert body.
            CodeChunk consequent = visitChildrenReturningCodeChunk(condNode);
            // Add if-block to conditional.
            if (conditional == null) {
                conditional = ifStatement(predicate, consequent);
            } else {
                conditional.elseif_(predicate, consequent);
            }
        } else if (child instanceof IfElseNode) {
            // Convert body.
            CodeChunk trailingElse = visitChildrenReturningCodeChunk((IfElseNode) child);
            // Add else-block to conditional.
            conditional.else_(trailingElse);
        } else {
            throw new AssertionError();
        }
    }
    jsCodeBuilder.append(conditional.build());
}
Also used : IfElseNode(com.google.template.soy.soytree.IfElseNode) ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) SoyNode(com.google.template.soy.soytree.SoyNode) IfCondNode(com.google.template.soy.soytree.IfCondNode) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) ConditionalBuilder(com.google.template.soy.jssrc.dsl.ConditionalBuilder)

Example 2 with IfCondNode

use of com.google.template.soy.soytree.IfCondNode in project closure-templates by google.

the class GenJsExprsVisitor method visitIfNode.

/**
 * Example:
 * <pre>
 *   {if $boo}
 *     AAA
 *   {elseif $foo}
 *     BBB
 *   {else}
 *     CCC
 *   {/if}
 * </pre>
 * might generate
 * <pre>
 *   (opt_data.boo) ? AAA : (opt_data.foo) ? BBB : CCC
 * </pre>
 */
@Override
protected void visitIfNode(IfNode node) {
    // Create another instance of this visitor class for generating JS expressions from children.
    GenJsExprsVisitor genJsExprsVisitor = genJsExprsVisitorFactory.create(translationContext, templateAliases, errorReporter);
    CodeChunk.Generator generator = translationContext.codeGenerator();
    List<CodeChunk.WithValue> ifs = new ArrayList<>();
    List<CodeChunk.WithValue> thens = new ArrayList<>();
    CodeChunk.WithValue trailingElse = null;
    for (SoyNode child : node.getChildren()) {
        if (child instanceof IfCondNode) {
            IfCondNode ifCond = (IfCondNode) child;
            ifs.add(translateExpr(ifCond.getExpr()));
            thens.add(CodeChunkUtils.concatChunks(genJsExprsVisitor.exec(ifCond)));
        } else if (child instanceof IfElseNode) {
            trailingElse = CodeChunkUtils.concatChunks(genJsExprsVisitor.exec(child));
        } else {
            throw new AssertionError();
        }
    }
    Preconditions.checkState(ifs.size() == thens.size());
    ConditionalExpressionBuilder builder = CodeChunk.ifExpression(ifs.get(0), thens.get(0));
    for (int i = 1; i < ifs.size(); i++) {
        builder.elseif_(ifs.get(i), thens.get(i));
    }
    CodeChunk.WithValue ifChunk = trailingElse != null ? builder.else_(trailingElse).build(generator) : builder.else_(LITERAL_EMPTY_STRING).build(generator);
    chunks.add(ifChunk);
}
Also used : IfElseNode(com.google.template.soy.soytree.IfElseNode) SoyNode(com.google.template.soy.soytree.SoyNode) ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) WithValue(com.google.template.soy.jssrc.dsl.CodeChunk.WithValue) ConditionalExpressionBuilder(com.google.template.soy.jssrc.dsl.ConditionalExpressionBuilder) ArrayList(java.util.ArrayList) IfCondNode(com.google.template.soy.soytree.IfCondNode) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) WithValue(com.google.template.soy.jssrc.dsl.CodeChunk.WithValue)

Example 3 with IfCondNode

use of com.google.template.soy.soytree.IfCondNode in project closure-templates by google.

the class ResolveExpressionTypesVisitor method visitIfNode.

@Override
protected void visitIfNode(IfNode node) {
    // TODO(user): Also support switch / case.
    TypeSubstitution savedSubstitutionState = substitutions;
    for (SoyNode child : node.getChildren()) {
        if (child instanceof IfCondNode) {
            IfCondNode icn = (IfCondNode) child;
            visitExpressions(icn);
            // Visit the conditional expression to compute which types can be narrowed.
            TypeNarrowingConditionVisitor visitor = new TypeNarrowingConditionVisitor();
            visitor.exec(icn.getExpr());
            // Save the state of substitutions from the previous if block.
            TypeSubstitution previousSubstitutionState = substitutions;
            // Modify the current set of type substitutions for the 'true' branch
            // of the if statement.
            addTypeSubstitutions(visitor.positiveTypeConstraints);
            visitChildren(icn);
            // Rewind the substitutions back to the state before the if-condition.
            // Add in the negative substitutions, which will affect subsequent blocks
            // of the if statement.
            // So for example if we have a variable whose type is (A|B|C) and the
            // first if-block tests whether that variable is type A, then in the
            // 'else' block it must be of type (B|C); If a subsequent 'elseif'
            // statement tests whether it's type B, then in the following else block
            // it can only be of type C.
            substitutions = previousSubstitutionState;
            addTypeSubstitutions(visitor.negativeTypeConstraints);
        } else if (child instanceof IfElseNode) {
            // For the else node, we simply inherit the previous set of subsitutions.
            IfElseNode ien = (IfElseNode) child;
            visitChildren(ien);
        }
    }
    substitutions = savedSubstitutionState;
}
Also used : IfElseNode(com.google.template.soy.soytree.IfElseNode) ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) SoyNode(com.google.template.soy.soytree.SoyNode) IfCondNode(com.google.template.soy.soytree.IfCondNode)

Example 4 with IfCondNode

use of com.google.template.soy.soytree.IfCondNode in project closure-templates by google.

the class ContentSecurityPolicyNonceInjectionPass method createCspInjection.

/**
 * Generates an AST fragment that looks like: {if $ij.csp_nonce}nonce="{$ij.csp_nonce}"{/if}
 *
 * @param insertionLocation The location where it is being inserted
 * @param nodeIdGen The id generator to use
 */
private static IfNode createCspInjection(SourceLocation insertionLocation, IdGenerator nodeIdGen) {
    IfNode ifNode = new IfNode(nodeIdGen.genId(), insertionLocation);
    IfCondNode ifCondNode = new IfCondNode(nodeIdGen.genId(), insertionLocation, "if", referenceCspNonce(insertionLocation));
    ifNode.addChild(ifCondNode);
    HtmlAttributeNode nonceAttribute = new HtmlAttributeNode(nodeIdGen.genId(), insertionLocation, insertionLocation.getBeginPoint());
    ifCondNode.addChild(nonceAttribute);
    nonceAttribute.addChild(new RawTextNode(nodeIdGen.genId(), "nonce", insertionLocation));
    HtmlAttributeValueNode attributeValue = new HtmlAttributeValueNode(nodeIdGen.genId(), insertionLocation, HtmlAttributeValueNode.Quotes.DOUBLE);
    nonceAttribute.addChild(attributeValue);
    // NOTE: we do not need to insert any print directives here, unlike the old implementation since
    // we are running before the autoescaper, so the escaper should insert whatever print directives
    // are appropriate.
    PrintNode printNode = new PrintNode(nodeIdGen.genId(), insertionLocation, // Implicit.  {$ij.csp_nonce} not {print $ij.csp_nonce}
    true, /* isImplicit= */
    referenceCspNonce(insertionLocation), /* attributes= */
    ImmutableList.of(), ErrorReporter.exploding());
    attributeValue.addChild(printNode);
    return ifNode;
}
Also used : IfCondNode(com.google.template.soy.soytree.IfCondNode) HtmlAttributeNode(com.google.template.soy.soytree.HtmlAttributeNode) IfNode(com.google.template.soy.soytree.IfNode) PrintNode(com.google.template.soy.soytree.PrintNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) HtmlAttributeValueNode(com.google.template.soy.soytree.HtmlAttributeValueNode)

Example 5 with IfCondNode

use of com.google.template.soy.soytree.IfCondNode in project closure-templates by google.

the class TemplateParserTest method testParseIfStmt.

@Test
public void testParseIfStmt() throws Exception {
    String templateBody = "{@param zoo : ?}{@param boo: ?}{@param foo : ?}{@param moo : ?}\n" + "  {if $zoo}{$zoo}{/if}\n" + "  {if $boo}\n" + "    Blah\n" + "  {elseif $foo.goo > 2}\n" + "    {$moo}\n" + "  {else}\n" + "    Blah {$moo}\n" + "  {/if}\n";
    List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
    assertEquals(2, nodes.size());
    IfNode in0 = (IfNode) nodes.get(0);
    assertEquals(1, in0.numChildren());
    IfCondNode in0icn0 = (IfCondNode) in0.getChild(0);
    assertEquals("$zoo", in0icn0.getExpr().toSourceString());
    assertEquals(1, in0icn0.numChildren());
    assertEquals("$zoo", ((PrintNode) in0icn0.getChild(0)).getExpr().toSourceString());
    assertTrue(in0icn0.getExpr().getRoot() instanceof VarRefNode);
    IfNode in1 = (IfNode) nodes.get(1);
    assertEquals(3, in1.numChildren());
    IfCondNode in1icn0 = (IfCondNode) in1.getChild(0);
    assertEquals("$boo", in1icn0.getExpr().toSourceString());
    assertTrue(in1icn0.getExpr().getRoot() instanceof VarRefNode);
    IfCondNode in1icn1 = (IfCondNode) in1.getChild(1);
    assertEquals("$foo.goo > 2", in1icn1.getExpr().toSourceString());
    assertTrue(in1icn1.getExpr().getRoot() instanceof GreaterThanOpNode);
    assertEquals("{if $boo}Blah{elseif $foo.goo > 2}{$moo}{else}Blah {$moo}{/if}", in1.toSourceString());
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) IfCondNode(com.google.template.soy.soytree.IfCondNode) GreaterThanOpNode(com.google.template.soy.exprtree.OperatorNodes.GreaterThanOpNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) IfNode(com.google.template.soy.soytree.IfNode) PrintNode(com.google.template.soy.soytree.PrintNode) Test(org.junit.Test)

Aggregations

IfCondNode (com.google.template.soy.soytree.IfCondNode)9 IfElseNode (com.google.template.soy.soytree.IfElseNode)5 SoyNode (com.google.template.soy.soytree.SoyNode)5 IfNode (com.google.template.soy.soytree.IfNode)4 ParentSoyNode (com.google.template.soy.soytree.SoyNode.ParentSoyNode)4 PrintNode (com.google.template.soy.soytree.PrintNode)3 VarRefNode (com.google.template.soy.exprtree.VarRefNode)2 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)2 RawTextNode (com.google.template.soy.soytree.RawTextNode)2 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)2 ArrayList (java.util.ArrayList)2 Test (org.junit.Test)2 FieldAccessNode (com.google.template.soy.exprtree.FieldAccessNode)1 FunctionNode (com.google.template.soy.exprtree.FunctionNode)1 GreaterThanOpNode (com.google.template.soy.exprtree.OperatorNodes.GreaterThanOpNode)1 IfBlock (com.google.template.soy.jbcsrc.ControlFlow.IfBlock)1 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)1 Statement (com.google.template.soy.jbcsrc.restricted.Statement)1 WithValue (com.google.template.soy.jssrc.dsl.CodeChunk.WithValue)1 ConditionalBuilder (com.google.template.soy.jssrc.dsl.ConditionalBuilder)1