Search in sources :

Example 1 with CallNode

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

the class MsgFuncGenerator method collectVarNameListAndToPyExprMap.

/**
 * Private helper to process and collect all variables used within this msg node for code
 * generation.
 *
 * @return A Map populated with all the variables used with in this message node, using {@link
 *     MsgPlaceholderInitialNode#genBasePhName}.
 */
private Map<PyExpr, PyExpr> collectVarNameListAndToPyExprMap() {
    Map<PyExpr, PyExpr> nodePyVarToPyExprMap = new LinkedHashMap<>();
    for (Map.Entry<String, MsgSubstUnitNode> entry : msgNode.getVarNameToRepNodeMap().entrySet()) {
        MsgSubstUnitNode substUnitNode = entry.getValue();
        PyExpr substPyExpr = null;
        if (substUnitNode instanceof MsgPlaceholderNode) {
            SoyNode phInitialNode = ((AbstractParentSoyNode<?>) substUnitNode).getChild(0);
            if (phInitialNode instanceof PrintNode || phInitialNode instanceof CallNode || phInitialNode instanceof RawTextNode) {
                substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.exec(phInitialNode)).toPyString();
            }
            // when the placeholder is generated by HTML tags
            if (phInitialNode instanceof MsgHtmlTagNode) {
                substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.execOnChildren((ParentSoyNode<?>) phInitialNode)).toPyString();
            }
        } else if (substUnitNode instanceof MsgPluralNode) {
            // Translates {@link MsgPluralNode#pluralExpr} into a Python lookup expression.
            // Note that {@code pluralExpr} represents the soy expression of the {@code plural} attr,
            // i.e. the {@code $numDrafts} in {@code {plural $numDrafts}...{/plural}}.
            substPyExpr = translateToPyExprVisitor.exec(((MsgPluralNode) substUnitNode).getExpr());
        } else if (substUnitNode instanceof MsgSelectNode) {
            substPyExpr = translateToPyExprVisitor.exec(((MsgSelectNode) substUnitNode).getExpr());
        }
        if (substPyExpr != null) {
            nodePyVarToPyExprMap.put(new PyStringExpr("'" + entry.getKey() + "'"), substPyExpr);
        }
    }
    return nodePyVarToPyExprMap;
}
Also used : AbstractParentSoyNode(com.google.template.soy.soytree.AbstractParentSoyNode) SoyNode(com.google.template.soy.soytree.SoyNode) ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) AbstractParentSoyNode(com.google.template.soy.soytree.AbstractParentSoyNode) MsgSelectNode(com.google.template.soy.soytree.MsgSelectNode) PyStringExpr(com.google.template.soy.pysrc.restricted.PyStringExpr) MsgSubstUnitNode(com.google.template.soy.soytree.SoyNode.MsgSubstUnitNode) CallNode(com.google.template.soy.soytree.CallNode) LinkedHashMap(java.util.LinkedHashMap) PyExpr(com.google.template.soy.pysrc.restricted.PyExpr) ParentSoyNode(com.google.template.soy.soytree.SoyNode.ParentSoyNode) AbstractParentSoyNode(com.google.template.soy.soytree.AbstractParentSoyNode) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) PrintNode(com.google.template.soy.soytree.PrintNode) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgPlaceholderNode(com.google.template.soy.soytree.MsgPlaceholderNode) MsgPluralNode(com.google.template.soy.soytree.MsgPluralNode)

Example 2 with CallNode

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

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

the class MsgCompiler method putPlaceholderIntoMap.

private void putPlaceholderIntoMap(Expression mapExpression, MsgNode originalMsg, Map<String, Statement> placeholderNameToPutStatement, SoyMsgPlaceholderPart placeholder) throws AssertionError {
    String placeholderName = placeholder.getPlaceholderName();
    if (!placeholderNameToPutStatement.containsKey(placeholderName)) {
        MsgPlaceholderNode repPlaceholderNode = originalMsg.getRepPlaceholderNode(placeholder.getPlaceholderName());
        if (repPlaceholderNode.numChildren() == 0) {
            throw new IllegalStateException("empty rep node for: " + placeholderName);
        }
        StandaloneNode initialNode = repPlaceholderNode.getChild(0);
        Statement putEntyInMap;
        if (initialNode instanceof MsgHtmlTagNode) {
            putEntyInMap = addHtmlTagNodeToPlaceholderMap(mapExpression, placeholderName, (MsgHtmlTagNode) initialNode);
        } else if (initialNode instanceof CallNode) {
            putEntyInMap = addCallNodeToPlaceholderMap(mapExpression, placeholderName, (CallNode) initialNode);
        } else if (initialNode instanceof PrintNode) {
            putEntyInMap = addPrintNodeToPlaceholderMap(mapExpression, placeholderName, (PrintNode) initialNode);
        } else if (initialNode instanceof RawTextNode) {
            putEntyInMap = addRawTextNodeToPlaceholderMap(mapExpression, placeholderName, (RawTextNode) initialNode);
        } else {
            // the AST for MsgNodes guarantee that these are the only options
            throw new AssertionError("Unexpected child: " + initialNode.getClass());
        }
        placeholderNameToPutStatement.put(placeholder.getPlaceholderName(), putEntyInMap.withSourceLocation(repPlaceholderNode.getSourceLocation()));
    }
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) Statement(com.google.template.soy.jbcsrc.restricted.Statement) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) PrintNode(com.google.template.soy.soytree.PrintNode) CallNode(com.google.template.soy.soytree.CallNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgPlaceholderNode(com.google.template.soy.soytree.MsgPlaceholderNode)

Example 4 with CallNode

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

the class ContextualAutoescaperTest method testStrictModeEscapesCallSites.

@Test
public void testStrictModeEscapesCallSites() {
    String source = "{namespace ns}\n\n" + "{template .main}\n" + "{call .htmltemplate /}" + "<script>var x={call .htmltemplate /};</script>\n" + "<script>var x={call .jstemplate /};</script>\n" + "{call .externtemplate /}" + "\n{/template}\n\n" + "{template .htmltemplate}\n" + "Hello World" + "\n{/template}\n\n" + "{template .jstemplate kind=\"js\"}\n" + "foo()" + "\n{/template}";
    TemplateNode mainTemplate = rewrite(source).getChild(0);
    assertWithMessage("Sanity check").that(mainTemplate.getTemplateName()).isEqualTo("ns.main");
    final List<CallNode> callNodes = SoyTreeUtils.getAllNodesOfType(mainTemplate, CallNode.class);
    assertThat(callNodes).hasSize(4);
    assertWithMessage("HTML->HTML escaping should be pruned").that(callNodes.get(0).getEscapingDirectives()).isEmpty();
    assertWithMessage("JS -> HTML call should be escaped").that(getDirectiveNames(callNodes.get(1).getEscapingDirectives())).containsExactly("|escapeJsValue");
    assertWithMessage("JS -> JS pruned").that(callNodes.get(2).getEscapingDirectives()).isEmpty();
    assertWithMessage("HTML -> extern call should be escaped").that(getDirectiveNames(callNodes.get(3).getEscapingDirectives())).containsExactly("|escapeHtml");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) CallNode(com.google.template.soy.soytree.CallNode) Test(org.junit.Test)

Example 5 with CallNode

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

the class ContextualAutoescaperTest method testStrictModeOptimizesDelegates.

@Test
public void testStrictModeOptimizesDelegates() {
    String source = "{namespace ns}\n\n" + "{template .main}\n" + "{delcall ns.delegateHtml /}" + "{delcall ns.delegateText /}" + "\n{/template}\n\n" + "/** A delegate returning HTML. */\n" + "{deltemplate ns.delegateHtml}\n" + "Hello World" + "\n{/deltemplate}\n\n" + "/** A delegate returning JS. */\n" + "{deltemplate ns.delegateText kind=\"text\"}\n" + "Hello World" + "\n{/deltemplate}";
    TemplateNode mainTemplate = rewrite(source).getChild(0);
    assertWithMessage("Sanity check").that(mainTemplate.getTemplateName()).isEqualTo("ns.main");
    final List<CallNode> callNodes = SoyTreeUtils.getAllNodesOfType(mainTemplate, CallNode.class);
    assertThat(callNodes).hasSize(2);
    assertWithMessage("We're compiling a complete set; we can optimize based on usages.").that(callNodes.get(0).getEscapingDirectives()).isEmpty();
    assertWithMessage("HTML -> TEXT requires escaping").that(getDirectiveNames(callNodes.get(1).getEscapingDirectives())).containsExactly("|escapeHtml");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) CallNode(com.google.template.soy.soytree.CallNode) Test(org.junit.Test)

Aggregations

CallNode (com.google.template.soy.soytree.CallNode)6 MsgHtmlTagNode (com.google.template.soy.soytree.MsgHtmlTagNode)3 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)2 MsgPlaceholderNode (com.google.template.soy.soytree.MsgPlaceholderNode)2 PrintNode (com.google.template.soy.soytree.PrintNode)2 RawTextNode (com.google.template.soy.soytree.RawTextNode)2 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)2 TemplateNode (com.google.template.soy.soytree.TemplateNode)2 Test (org.junit.Test)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 UniqueNameGenerator (com.google.template.soy.base.internal.UniqueNameGenerator)1 Statement (com.google.template.soy.jbcsrc.restricted.Statement)1 PyExpr (com.google.template.soy.pysrc.restricted.PyExpr)1 PyStringExpr (com.google.template.soy.pysrc.restricted.PyStringExpr)1 SoyPrintDirective (com.google.template.soy.shared.restricted.SoyPrintDirective)1 AbstractParentSoyNode (com.google.template.soy.soytree.AbstractParentSoyNode)1 CallParamContentNode (com.google.template.soy.soytree.CallParamContentNode)1 CallParamNode (com.google.template.soy.soytree.CallParamNode)1 MsgPluralNode (com.google.template.soy.soytree.MsgPluralNode)1