Search in sources :

Example 11 with StandaloneNode

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

the class TemplateParserTest method testParsePrintStmt.

@Test
public void testParsePrintStmt() throws Exception {
    String templateBody = "{@param boo : ?}{@param goo : ?}\n" + "  {$boo.foo}{$boo.foo}\n" + "  {$goo + 1 |noAutoescape}\n" + "  {print 'blah    blahblahblah' |escapeHtml|insertWordBreaks:8}\n";
    List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
    assertEquals(4, nodes.size());
    PrintNode pn0 = (PrintNode) nodes.get(0);
    assertEquals("$boo.foo", pn0.getExpr().toSourceString());
    assertEquals(0, pn0.getChildren().size());
    assertEquals("FOO", pn0.genBasePhName());
    assertEquals("{$boo.foo}", pn0.toSourceString());
    assertTrue(pn0.getExpr().getRoot() instanceof FieldAccessNode);
    PrintNode pn1 = (PrintNode) nodes.get(1);
    assertTrue(pn0.genSamenessKey().equals(pn1.genSamenessKey()));
    assertTrue(pn1.getExpr().getRoot() instanceof FieldAccessNode);
    PrintNode pn2 = (PrintNode) nodes.get(2);
    assertEquals("$goo + 1", pn2.getExpr().toSourceString());
    assertEquals(1, pn2.getChildren().size());
    PrintDirectiveNode pn2d0 = pn2.getChild(0);
    assertEquals("|noAutoescape", pn2d0.getName());
    assertEquals("XXX", pn2.genBasePhName());
    assertTrue(pn2.getExpr().getRoot() instanceof PlusOpNode);
    PrintNode pn3 = (PrintNode) nodes.get(3);
    assertEquals("'blah    blahblahblah'", pn3.getExpr().toSourceString());
    assertEquals(2, pn3.getChildren().size());
    PrintDirectiveNode pn3d0 = pn3.getChild(0);
    assertEquals("|escapeHtml", pn3d0.getName());
    PrintDirectiveNode pn3d1 = pn3.getChild(1);
    assertEquals("|insertWordBreaks", pn3d1.getName());
    assertEquals(8, ((IntegerNode) pn3d1.getArgs().get(0).getRoot()).getValue());
    assertEquals("XXX", pn3.genBasePhName());
    assertTrue(pn3.getExpr().getRoot() instanceof StringNode);
    assertFalse(pn0.genSamenessKey().equals(pn2.genSamenessKey()));
    assertFalse(pn3.genSamenessKey().equals(pn0.genSamenessKey()));
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) PrintDirectiveNode(com.google.template.soy.soytree.PrintDirectiveNode) StringNode(com.google.template.soy.exprtree.StringNode) PlusOpNode(com.google.template.soy.exprtree.OperatorNodes.PlusOpNode) PrintNode(com.google.template.soy.soytree.PrintNode) FieldAccessNode(com.google.template.soy.exprtree.FieldAccessNode) Test(org.junit.Test)

Example 12 with StandaloneNode

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

the class VeLogInstrumentationVisitor method visitHtmlAttributeNode.

/**
 * For HtmlAttributeNode that has a logging function as its value, replace the logging function
 * with its place holder, and append a new data attribute that contains all the desired
 * information that are used later by the runtime library.
 */
@Override
protected void visitHtmlAttributeNode(HtmlAttributeNode node) {
    // Skip attributes that do not have a value.
    if (!node.hasValue()) {
        return;
    }
    SourceLocation insertionLocation = node.getSourceLocation();
    for (FunctionNode function : SoyTreeUtils.getAllNodesOfType(node, FunctionNode.class)) {
        if (!(function.getSoyFunction() instanceof LoggingFunction)) {
            continue;
        }
        FunctionNode funcNode = new FunctionNode(VeLogJsSrcLoggingFunction.INSTANCE, insertionLocation);
        funcNode.addChild(new StringNode(function.getFunctionName(), QuoteStyle.SINGLE, insertionLocation));
        funcNode.addChild(new ListLiteralNode(function.getChildren(), insertionLocation));
        StandaloneNode attributeName = node.getChild(0);
        if (attributeName instanceof RawTextNode) {
            // If attribute name is a plain text, directly pass it as a function argument.
            funcNode.addChild(new StringNode(((RawTextNode) attributeName).getRawText(), QuoteStyle.SINGLE, insertionLocation));
        } else {
            // Otherwise wrap the print node or call node into a let block, and use the let variable
            // as a function argument.
            String varName = "soy_logging_function_attribute_" + counter;
            LetContentNode letNode = LetContentNode.forVariable(nodeIdGen.genId(), attributeName.getSourceLocation(), varName, null);
            // Adds a let var which references to the original attribute name, and move the name to
            // the let block.
            node.replaceChild(attributeName, new PrintNode(nodeIdGen.genId(), insertionLocation, /* isImplicit= */
            true, /* expr= */
            new VarRefNode(varName, insertionLocation, false, letNode.getVar()), /* attributes= */
            ImmutableList.of(), ErrorReporter.exploding()));
            letNode.addChild(attributeName);
            node.getParent().addChild(node.getParent().getChildIndex(node), letNode);
            funcNode.addChild(new VarRefNode(varName, insertionLocation, false, letNode.getVar()));
        }
        funcNode.addChild(new IntegerNode(counter++, insertionLocation));
        PrintNode loggingFunctionAttribute = new PrintNode(nodeIdGen.genId(), insertionLocation, /* isImplicit= */
        true, /* expr= */
        funcNode, /* attributes= */
        ImmutableList.of(), ErrorReporter.exploding());
        // Append the logging function attribute to its parent
        int appendIndex = node.getParent().getChildIndex(node) + 1;
        node.getParent().addChild(appendIndex, loggingFunctionAttribute);
        // Replace the original attribute value to the placeholder.
        HtmlAttributeValueNode placeHolder = new HtmlAttributeValueNode(nodeIdGen.genId(), insertionLocation, Quotes.DOUBLE);
        placeHolder.addChild(new RawTextNode(nodeIdGen.genId(), ((LoggingFunction) function.getSoyFunction()).getPlaceholder(), insertionLocation));
        node.replaceChild(node.getChild(1), placeHolder);
        // logging function in a html attribute value.
        break;
    }
    visitChildren(node);
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) ListLiteralNode(com.google.template.soy.exprtree.ListLiteralNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode) StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) StringNode(com.google.template.soy.exprtree.StringNode) LoggingFunction(com.google.template.soy.logging.LoggingFunction) PrintNode(com.google.template.soy.soytree.PrintNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) LetContentNode(com.google.template.soy.soytree.LetContentNode) HtmlAttributeValueNode(com.google.template.soy.soytree.HtmlAttributeValueNode)

Example 13 with StandaloneNode

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

the class InsertMsgsVisitor method buildReplacementNodesFromTranslation.

/**
 * Private helper for visitMsgFallbackGroupNode() to build the list of replacement nodes for a
 * message from its translation.
 */
private void buildReplacementNodesFromTranslation(MsgNode msg, SoyMsg translation) {
    currReplacementNodes = Lists.newArrayList();
    for (SoyMsgPart msgPart : translation.getParts()) {
        if (msgPart instanceof SoyMsgRawTextPart) {
            // Append a new RawTextNode to the currReplacementNodes list.
            String rawText = ((SoyMsgRawTextPart) msgPart).getRawText();
            currReplacementNodes.add(new RawTextNode(nodeIdGen.genId(), rawText, msg.getSourceLocation()));
        } else if (msgPart instanceof SoyMsgPlaceholderPart) {
            // Get the representative placeholder node and iterate through its contents.
            String placeholderName = ((SoyMsgPlaceholderPart) msgPart).getPlaceholderName();
            MsgPlaceholderNode placeholderNode = msg.getRepPlaceholderNode(placeholderName);
            for (StandaloneNode contentNode : placeholderNode.getChildren()) {
                // simply add the content node to the currReplacementNodes list being built.
                if (contentNode instanceof MsgHtmlTagNode) {
                    currReplacementNodes.addAll(((MsgHtmlTagNode) contentNode).getChildren());
                } else {
                    currReplacementNodes.add(contentNode);
                }
            }
        } else {
            throw new AssertionError();
        }
    }
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) SoyMsgPlaceholderPart(com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) SoyMsgRawTextPart(com.google.template.soy.msgs.restricted.SoyMsgRawTextPart) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgPlaceholderNode(com.google.template.soy.soytree.MsgPlaceholderNode) SoyMsgPart(com.google.template.soy.msgs.restricted.SoyMsgPart)

Example 14 with StandaloneNode

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

the class GenJsCodeVisitorAssistantForMsgs method genGoogMsgPlaceholder.

/**
 * Returns a code chunk for the given placeholder node.
 */
protected CodeChunk.WithValue genGoogMsgPlaceholder(MsgPlaceholderNode msgPhNode) {
    List<CodeChunk.WithValue> contentChunks = new ArrayList<>();
    for (StandaloneNode contentNode : msgPhNode.getChildren()) {
        if (contentNode instanceof MsgHtmlTagNode && !isComputableAsJsExprsVisitor.exec(contentNode)) {
            // This is a MsgHtmlTagNode that is not computable as JS expressions. Visit it to
            // generate code to define the 'htmlTag<n>' variable.
            visit(contentNode);
            contentChunks.add(id("htmlTag" + contentNode.getId()));
        } else if (contentNode instanceof CallNode) {
            // If the CallNode has any CallParamContentNode children that are not computable as JS
            // expressions, visit them to generate code to define their respective 'param<n>' variables.
            CallNode callNode = (CallNode) contentNode;
            for (CallParamNode grandchild : callNode.getChildren()) {
                if (grandchild instanceof CallParamContentNode && !isComputableAsJsExprsVisitor.exec(grandchild)) {
                    visit(grandchild);
                }
            }
            CodeChunk.WithValue call = genCallCodeUtils.gen(callNode, templateAliases, translationContext, errorReporter);
            contentChunks.add(call);
        } else {
            List<CodeChunk.WithValue> chunks = genJsExprsVisitor.exec(contentNode);
            contentChunks.add(CodeChunkUtils.concatChunks(chunks));
        }
    }
    return CodeChunkUtils.concatChunks(contentChunks);
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) CallParamContentNode(com.google.template.soy.soytree.CallParamContentNode) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) CallParamNode(com.google.template.soy.soytree.CallParamNode) ArrayList(java.util.ArrayList) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) CallNode(com.google.template.soy.soytree.CallNode)

Example 15 with StandaloneNode

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

the class RewriteGenderMsgsVisitor method splitMsgForGender.

/**
 * Helper to split a msg for gender, by adding a 'select' node and cloning the msg's contents into
 * all 3 cases of the 'select' node ('female'/'male'/default).
 *
 * @param msg The message to split.
 * @param genderExpr The expression for the gender value.
 * @param baseSelectVarName The base select var name to use, or null if it should be generated
 *     from the gender expression.
 */
private void splitMsgForGender(MsgNode msg, ExprRootNode genderExpr, @Nullable String baseSelectVarName) {
    List<StandaloneNode> origChildren = ImmutableList.copyOf(msg.getChildren());
    msg.clearChildren();
    MsgSelectCaseNode femaleCase = new MsgSelectCaseNode(nodeIdGen.genId(), msg.getSourceLocation(), "female");
    femaleCase.addChildren(SoyTreeUtils.cloneListWithNewIds(origChildren, nodeIdGen));
    MsgSelectCaseNode maleCase = new MsgSelectCaseNode(nodeIdGen.genId(), msg.getSourceLocation(), "male");
    maleCase.addChildren(SoyTreeUtils.cloneListWithNewIds(origChildren, nodeIdGen));
    MsgSelectDefaultNode defaultCase = new MsgSelectDefaultNode(nodeIdGen.genId(), msg.getSourceLocation());
    defaultCase.addChildren(SoyTreeUtils.cloneListWithNewIds(origChildren, nodeIdGen));
    MsgSelectNode selectNode = new MsgSelectNode(nodeIdGen.genId(), msg.getSourceLocation(), genderExpr, baseSelectVarName);
    selectNode.addChild(femaleCase);
    selectNode.addChild(maleCase);
    selectNode.addChild(defaultCase);
    msg.addChild(selectNode);
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) MsgSelectDefaultNode(com.google.template.soy.soytree.MsgSelectDefaultNode) MsgSelectNode(com.google.template.soy.soytree.MsgSelectNode) MsgSelectCaseNode(com.google.template.soy.soytree.MsgSelectCaseNode)

Aggregations

StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)30 Test (org.junit.Test)19 RawTextNode (com.google.template.soy.soytree.RawTextNode)10 MsgPlaceholderNode (com.google.template.soy.soytree.MsgPlaceholderNode)9 MsgNode (com.google.template.soy.soytree.MsgNode)8 PrintNode (com.google.template.soy.soytree.PrintNode)8 MsgFallbackGroupNode (com.google.template.soy.soytree.MsgFallbackGroupNode)7 MsgHtmlTagNode (com.google.template.soy.soytree.MsgHtmlTagNode)5 FieldAccessNode (com.google.template.soy.exprtree.FieldAccessNode)4 VarRefNode (com.google.template.soy.exprtree.VarRefNode)4 MsgSelectNode (com.google.template.soy.soytree.MsgSelectNode)4 FunctionNode (com.google.template.soy.exprtree.FunctionNode)3 CallParamContentNode (com.google.template.soy.soytree.CallParamContentNode)3 MsgSelectCaseNode (com.google.template.soy.soytree.MsgSelectCaseNode)3 MsgSelectDefaultNode (com.google.template.soy.soytree.MsgSelectDefaultNode)3 ImmutableList (com.google.common.collect.ImmutableList)2 IntegerNode (com.google.template.soy.exprtree.IntegerNode)2 StringNode (com.google.template.soy.exprtree.StringNode)2 SoyMsgPart (com.google.template.soy.msgs.restricted.SoyMsgPart)2 SoyMsgPlaceholderPart (com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart)2