Search in sources :

Example 1 with SoyNode

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

the class CanInitOutputVarVisitorTest method runTestHelper.

/**
 * @param indicesToNode Series of indices for walking down to the node we want to test.
 */
private static void runTestHelper(String soyCode, boolean isSameValueAsIsComputableAsJsExprsVisitor, int... indicesToNode) {
    ErrorReporter boom = ErrorReporter.exploding();
    SoyFileSetNode soyTree = SoyFileSetParserBuilder.forTemplateContents(soyCode).errorReporter(boom).parse().fileSet();
    SoyNode node = SharedTestUtils.getNode(soyTree, indicesToNode);
    IsComputableAsJsExprsVisitor icajev = new IsComputableAsJsExprsVisitor();
    CanInitOutputVarVisitor ciovv = new CanInitOutputVarVisitor(icajev);
    assertThat(ciovv.exec(node).equals(icajev.exec(node))).isEqualTo(isSameValueAsIsComputableAsJsExprsVisitor);
}
Also used : ErrorReporter(com.google.template.soy.error.ErrorReporter) SoyNode(com.google.template.soy.soytree.SoyNode) SoyFileSetNode(com.google.template.soy.soytree.SoyFileSetNode)

Example 2 with SoyNode

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

the class GenJsCodeVisitorTest method assertGeneratedJsCode.

// -----------------------------------------------------------------------------------------------
// Helpers.
/**
 * @param soyCode The soy code.
 * @param expectedJsCode JavaScript code expected to be generated from the Soy code.
 */
private void assertGeneratedJsCode(String soyCode, String expectedJsCode) {
    ParseResult parseResult = SoyFileSetParserBuilder.forTemplateContents(soyCode).allowUnboundGlobals(true).parse();
    TemplateNode templateNode = parseResult.fileSet().getChild(0).getChild(0);
    // Setup the GenJsCodeVisitor's state before the node is visited.
    genJsCodeVisitor.jsCodeBuilder = new JsCodeBuilder();
    genJsCodeVisitor.jsCodeBuilder.pushOutputVar("output");
    genJsCodeVisitor.jsCodeBuilder.setOutputVarInited();
    UniqueNameGenerator nameGenerator = JsSrcNameGenerators.forLocalVariables();
    CodeChunk.Generator codeGenerator = CodeChunk.Generator.create(nameGenerator);
    TranslationContext translationContext = TranslationContext.of(SoyToJsVariableMappings.startingWith(LOCAL_VAR_TRANSLATIONS), codeGenerator, nameGenerator);
    genJsCodeVisitor.templateTranslationContext = translationContext;
    genJsCodeVisitor.genJsExprsVisitor = JsSrcTestUtils.createGenJsExprsVisitorFactory().create(translationContext, TEMPLATE_ALIASES, ErrorReporter.exploding());
    // will be created when used
    genJsCodeVisitor.assistantForMsgs = null;
    for (SoyNode child : templateNode.getChildren()) {
        genJsCodeVisitor.visitForTesting(child, parseResult.registry(), ErrorReporter.exploding());
    }
    String genCode = genJsCodeVisitor.jsCodeBuilder.getCode();
    assertThat(genCode).isEqualTo(expectedJsCode);
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) SoyNode(com.google.template.soy.soytree.SoyNode) ParseResult(com.google.template.soy.SoyFileSetParser.ParseResult) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) UniqueNameGenerator(com.google.template.soy.base.internal.UniqueNameGenerator)

Example 3 with SoyNode

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

the class GenJsCodeVisitor method visitChildren.

@Override
protected void visitChildren(ParentSoyNode<?> node) {
    // initialize the output var.
    if (node.numChildren() == 0 || !canInitOutputVarVisitor.exec(node.getChild(0))) {
        jsCodeBuilder.initOutputVarIfNecessary();
    }
    // For children that are computed by GenJsExprsVisitor, try to process as many of them as we can
    // before adding to outputVar.
    // 
    // output += 'a' + 'b';
    // is preferable to
    // output += 'a';
    // output += 'b';
    // This is because it is actually easier for the jscompiler to optimize.
    List<CodeChunk.WithValue> consecChunks = new ArrayList<>();
    for (SoyNode child : node.getChildren()) {
        if (isComputableAsJsExprsVisitor.exec(child)) {
            consecChunks.addAll(genJsExprsVisitor.exec(child));
        } else {
            if (!consecChunks.isEmpty()) {
                jsCodeBuilder.addChunksToOutputVar(consecChunks);
                consecChunks.clear();
            }
            visit(child);
        }
    }
    if (!consecChunks.isEmpty()) {
        jsCodeBuilder.addChunksToOutputVar(consecChunks);
        consecChunks.clear();
    }
}
Also used : ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) SoyNode(com.google.template.soy.soytree.SoyNode) ArrayList(java.util.ArrayList)

Example 4 with SoyNode

use of com.google.template.soy.soytree.SoyNode 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 5 with SoyNode

use of com.google.template.soy.soytree.SoyNode 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)

Aggregations

SoyNode (com.google.template.soy.soytree.SoyNode)19 ParentSoyNode (com.google.template.soy.soytree.SoyNode.ParentSoyNode)9 SoyFileSetNode (com.google.template.soy.soytree.SoyFileSetNode)6 IfCondNode (com.google.template.soy.soytree.IfCondNode)5 IfElseNode (com.google.template.soy.soytree.IfElseNode)5 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)4 ArrayList (java.util.ArrayList)4 ErrorReporter (com.google.template.soy.error.ErrorReporter)3 PyExpr (com.google.template.soy.pysrc.restricted.PyExpr)3 ImmutableList (com.google.common.collect.ImmutableList)2 UniqueNameGenerator (com.google.template.soy.base.internal.UniqueNameGenerator)2 IfBlock (com.google.template.soy.jbcsrc.ControlFlow.IfBlock)2 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)2 Statement (com.google.template.soy.jbcsrc.restricted.Statement)2 PyStringExpr (com.google.template.soy.pysrc.restricted.PyStringExpr)2 RawTextNode (com.google.template.soy.soytree.RawTextNode)2 SwitchCaseNode (com.google.template.soy.soytree.SwitchCaseNode)2 SwitchDefaultNode (com.google.template.soy.soytree.SwitchDefaultNode)2 Supplier (com.google.common.base.Supplier)1 ParseResult (com.google.template.soy.SoyFileSetParser.ParseResult)1