Search in sources :

Example 11 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode 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 12 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class AddHtmlCommentsForDebugPass method createSoyDebug.

/**
 * Generates an AST fragment that looks like:
 *
 * <p>{@code {if debugSoyTemplateInfo()}<!--dta_of...-->{/if}}
 *
 * @param insertionLocation The location where it is being inserted
 * @param nodeIdGen The id generator to use
 * @param htmlComment The content of the HTML comment
 */
private IfNode createSoyDebug(SourceLocation insertionLocation, IdGenerator nodeIdGen, String htmlComment) {
    IfNode ifNode = new IfNode(nodeIdGen.genId(), insertionLocation);
    FunctionNode funcNode = new FunctionNode(DebugSoyTemplateInfoFunction.INSTANCE, insertionLocation);
    funcNode.setType(BoolType.getInstance());
    IfCondNode ifCondNode = new IfCondNode(nodeIdGen.genId(), insertionLocation, "if", funcNode);
    HtmlCommentNode htmlCommentNode = new HtmlCommentNode(nodeIdGen.genId(), insertionLocation);
    // We need to escape the input HTML comments, in cases the file location contains "-->".
    htmlCommentNode.addChild(new RawTextNode(nodeIdGen.genId(), htmlEscaper().escape(htmlComment), insertionLocation));
    ifCondNode.addChild(htmlCommentNode);
    ifNode.addChild(ifCondNode);
    return ifNode;
}
Also used : IfCondNode(com.google.template.soy.soytree.IfCondNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode) IfNode(com.google.template.soy.soytree.IfNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) HtmlCommentNode(com.google.template.soy.soytree.HtmlCommentNode)

Example 13 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class ReportSyntaxVersionErrors method visitNode.

private void visitNode(TemplateNode template, Node node) {
    if (!node.couldHaveSyntaxVersionAtLeast(requiredSyntaxVersion)) {
        SyntaxVersionUpperBound syntaxVersionBound = node.getSyntaxVersionUpperBound();
        Preconditions.checkNotNull(syntaxVersionBound);
        errorReporter.report(node.getSourceLocation(), errorKind, requiredSyntaxVersion, syntaxVersionBound.reasonStr);
    }
    if (node instanceof FunctionNode) {
        String functionName = ((FunctionNode) node).getFunctionName();
        if (functionName.equals(BuiltinFunction.V1_EXPRESSION.getName()) && template.couldHaveSyntaxVersionAtLeast(SyntaxVersion.V2_0)) {
            errorReporter.report(node.getSourceLocation(), errorKind, requiredSyntaxVersion, "The v1Expression function can only be used in templates marked with the " + "deprecatedV1=\"true\" attribute.");
        }
    }
}
Also used : SyntaxVersionUpperBound(com.google.template.soy.basetree.SyntaxVersionUpperBound) FunctionNode(com.google.template.soy.exprtree.FunctionNode)

Example 14 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class ParseExpressionTest method testParseFunctionCall.

@Test
public void testParseFunctionCall() throws Exception {
    ExprNode expr = assertThatExpression("isFirst($x)").isValidExpression();
    FunctionNode isFirstFn = (FunctionNode) expr;
    assertThat(isFirstFn.getFunctionName()).isEqualTo("isFirst");
    assertThat(isFirstFn.numChildren()).isEqualTo(1);
    assertThat(isFirstFn.getChild(0).toSourceString()).isEqualTo("$x");
    expr = assertThatExpression("round(3.14159, 2)").isValidExpression();
    FunctionNode roundFn = (FunctionNode) expr;
    assertThat(roundFn.getFunctionName()).isEqualTo("round");
    assertThat(roundFn.numChildren()).isEqualTo(2);
    assertThat(((FloatNode) roundFn.getChild(0)).getValue()).isEqualTo(3.14159);
    assertThat(((IntegerNode) roundFn.getChild(1)).getValue()).isEqualTo(2);
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode) FloatNode(com.google.template.soy.exprtree.FloatNode) Test(org.junit.Test)

Example 15 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class TemplateParserTest method testParseBasicCallStmt.

@SuppressWarnings({ "ConstantConditions" })
@Test
public void testParseBasicCallStmt() throws Exception {
    String templateBody = "{@param too : ?}{@param animals: ?}\n" + "  {call .booTemplate_ /}\n" + "  {call foo.goo.mooTemplate data=\"all\" /}\n" + "  {call .booTemplate_ /}\n" + "  {call .zooTemplate data=\"$animals\"}\n" + "    {param yoo: round($too) /}\n" + "    {param woo kind=\"html\"}poo{/param}\n" + "    {param zoo: 0 /}\n" + "    {param doo kind=\"html\"}doopoo{/param}\n" + "  {/call}\n";
    List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
    assertThat(nodes).hasSize(4);
    CallBasicNode cn0 = (CallBasicNode) nodes.get(0);
    assertEquals("brittle.test.ns.booTemplate_", cn0.getCalleeName());
    assertEquals(".booTemplate_", cn0.getSourceCalleeName());
    assertEquals(false, cn0.isPassingData());
    assertEquals(false, cn0.isPassingAllData());
    assertEquals(null, cn0.getDataExpr());
    assertEquals("XXX", cn0.genBasePhName());
    assertEquals(0, cn0.numChildren());
    CallBasicNode cn1 = (CallBasicNode) nodes.get(1);
    assertEquals("foo.goo.mooTemplate", cn1.getCalleeName());
    assertEquals("foo.goo.mooTemplate", cn1.getSourceCalleeName());
    assertEquals(true, cn1.isPassingData());
    assertEquals(true, cn1.isPassingAllData());
    assertEquals(null, cn1.getDataExpr());
    assertFalse(cn1.genSamenessKey().equals(cn0.genSamenessKey()));
    assertEquals(0, cn1.numChildren());
    CallBasicNode cn2 = (CallBasicNode) nodes.get(2);
    assertEquals("brittle.test.ns.booTemplate_", cn2.getCalleeName());
    assertEquals(".booTemplate_", cn2.getSourceCalleeName());
    assertFalse(cn2.isPassingData());
    assertEquals(false, cn2.isPassingAllData());
    assertEquals(null, cn2.getDataExpr());
    assertEquals("XXX", cn2.genBasePhName());
    assertEquals(0, cn2.numChildren());
    CallBasicNode cn3 = (CallBasicNode) nodes.get(3);
    assertEquals("brittle.test.ns.zooTemplate", cn3.getCalleeName());
    assertEquals(".zooTemplate", cn3.getSourceCalleeName());
    assertEquals(true, cn3.isPassingData());
    assertEquals(false, cn3.isPassingAllData());
    assertTrue(cn3.getDataExpr().getRoot() != null);
    assertEquals("$animals", cn3.getDataExpr().toSourceString());
    assertEquals(4, cn3.numChildren());
    {
        final CallParamValueNode cn4cpvn0 = (CallParamValueNode) cn3.getChild(0);
        assertEquals("yoo", cn4cpvn0.getKey().identifier());
        assertEquals("round($too)", cn4cpvn0.getExpr().toSourceString());
        assertTrue(cn4cpvn0.getExpr().getRoot() instanceof FunctionNode);
    }
    {
        final CallParamContentNode cn4cpcn1 = (CallParamContentNode) cn3.getChild(1);
        assertEquals("woo", cn4cpcn1.getKey().identifier());
        assertEquals(SanitizedContentKind.HTML, cn4cpcn1.getContentKind());
        assertEquals("poo", ((RawTextNode) cn4cpcn1.getChild(0)).getRawText());
    }
    {
        final CallParamValueNode cn4cpvn2 = (CallParamValueNode) cn3.getChild(2);
        assertEquals("zoo", cn4cpvn2.getKey().identifier());
        assertEquals("0", cn4cpvn2.getExpr().toSourceString());
    }
    {
        final CallParamContentNode cn4cpcn3 = (CallParamContentNode) cn3.getChild(3);
        assertEquals("doo", cn4cpcn3.getKey().identifier());
        assertNotNull(cn4cpcn3.getContentKind());
        assertEquals(SanitizedContentKind.HTML, cn4cpcn3.getContentKind());
        assertEquals("doopoo", ((RawTextNode) cn4cpcn3.getChild(0)).getRawText());
    }
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) CallParamContentNode(com.google.template.soy.soytree.CallParamContentNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode) CallParamValueNode(com.google.template.soy.soytree.CallParamValueNode) CallBasicNode(com.google.template.soy.soytree.CallBasicNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) Test(org.junit.Test)

Aggregations

FunctionNode (com.google.template.soy.exprtree.FunctionNode)20 PrintNode (com.google.template.soy.soytree.PrintNode)8 StringNode (com.google.template.soy.exprtree.StringNode)7 Test (org.junit.Test)7 TemplateNode (com.google.template.soy.soytree.TemplateNode)6 ExprNode (com.google.template.soy.exprtree.ExprNode)5 IntegerNode (com.google.template.soy.exprtree.IntegerNode)4 RawTextNode (com.google.template.soy.soytree.RawTextNode)3 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)3 SourceLocation (com.google.template.soy.base.SourceLocation)2 VarRefNode (com.google.template.soy.exprtree.VarRefNode)2 LoggingFunction (com.google.template.soy.logging.LoggingFunction)2 CallParamContentNode (com.google.template.soy.soytree.CallParamContentNode)2 CallParamValueNode (com.google.template.soy.soytree.CallParamValueNode)2 SoyType (com.google.template.soy.types.SoyType)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 IncrementingIdGenerator (com.google.template.soy.base.internal.IncrementingIdGenerator)1 CopyState (com.google.template.soy.basetree.CopyState)1 SyntaxVersionUpperBound (com.google.template.soy.basetree.SyntaxVersionUpperBound)1 ParentExprNode (com.google.template.soy.exprtree.ExprNode.ParentExprNode)1