Search in sources :

Example 6 with CallParamContentNode

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

the class GenPyCallExprVisitor method genObjToPass.

/**
 * Generates the Python expression for the object to pass in a given call. This expression will be
 * a combination of passed data and additional content params. If both are passed, they'll be
 * combined into one dictionary.
 *
 * @param callNode The call to generate code for.
 * @return The Python expression for the object to pass in the call.
 */
public String genObjToPass(CallNode callNode) {
    TranslateToPyExprVisitor translator = new TranslateToPyExprVisitor(localVarStack, errorReporter);
    // Generate the expression for the original data to pass.
    String dataToPass;
    if (callNode.isPassingAllData()) {
        dataToPass = "data";
    } else if (callNode.isPassingData()) {
        dataToPass = translator.exec(callNode.getDataExpr()).getText();
    } else {
        dataToPass = "{}";
    }
    // Case 1: No additional params.
    if (callNode.numChildren() == 0) {
        return dataToPass;
    }
    // Build an object literal containing the additional params.
    Map<PyExpr, PyExpr> additionalParams = new LinkedHashMap<>();
    for (CallParamNode child : callNode.getChildren()) {
        PyExpr key = new PyStringExpr("'" + child.getKey().identifier() + "'");
        if (child instanceof CallParamValueNode) {
            CallParamValueNode cpvn = (CallParamValueNode) child;
            additionalParams.put(key, translator.exec(cpvn.getExpr()));
        } else {
            CallParamContentNode cpcn = (CallParamContentNode) child;
            PyExpr valuePyExpr;
            if (isComputableAsPyExprVisitor.exec(cpcn)) {
                valuePyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitorFactory.create(localVarStack, errorReporter).exec(cpcn));
            } else {
                // This is a param with content that cannot be represented as Python expressions, so we
                // assume that code has been generated to define the temporary variable 'param<n>'.
                String paramExpr = "param" + cpcn.getId();
                // The param can be assumed to be a list at this point since it was created as an output
                // variable.
                valuePyExpr = new PyListExpr(paramExpr, Integer.MAX_VALUE);
            }
            // Param content nodes require a content kind in strict autoescaping, so the content must be
            // wrapped as SanitizedContent.
            valuePyExpr = InternalPyExprUtils.wrapAsSanitizedContent(cpcn.getContentKind(), valuePyExpr.toPyString());
            additionalParams.put(key, valuePyExpr);
        }
    }
    PyExpr additionalParamsExpr = PyExprUtils.convertMapToPyExpr(additionalParams);
    // Cases 2 and 3: Additional params with and without original data to pass.
    if (callNode.isPassingData()) {
        // make a shallow copy so we don't accidentally modify the param
        dataToPass = "dict(" + dataToPass + ")";
        return "runtime.merge_into_dict(" + dataToPass + ", " + additionalParamsExpr.getText() + ")";
    } else {
        return additionalParamsExpr.getText();
    }
}
Also used : PyExpr(com.google.template.soy.pysrc.restricted.PyExpr) CallParamContentNode(com.google.template.soy.soytree.CallParamContentNode) CallParamNode(com.google.template.soy.soytree.CallParamNode) PyListExpr(com.google.template.soy.pysrc.restricted.PyListExpr) CallParamValueNode(com.google.template.soy.soytree.CallParamValueNode) PyStringExpr(com.google.template.soy.pysrc.restricted.PyStringExpr) LinkedHashMap(java.util.LinkedHashMap)

Example 7 with CallParamContentNode

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

Example 8 with CallParamContentNode

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

the class TemplateParserTest method testParseDelegateCallStmt.

@SuppressWarnings({ "ConstantConditions" })
@Test
public void testParseDelegateCallStmt() throws Exception {
    String templateBody = "{@param animals : ?}{@param too : ?}\n" + "  {delcall booTemplate /}\n" + "  {delcall foo.goo.mooTemplate data=\"all\" /}\n" + "  {delcall MySecretFeature.zooTemplate data=\"$animals\"}\n" + "    {param yoo: round($too) /}\n" + "    {param woo kind=\"html\"}poo{/param}\n" + "  {/delcall}\n";
    List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
    assertEquals(3, nodes.size());
    CallDelegateNode cn0 = (CallDelegateNode) nodes.get(0);
    assertEquals("booTemplate", cn0.getDelCalleeName());
    assertEquals(false, cn0.isPassingData());
    assertEquals(false, cn0.isPassingAllData());
    assertEquals(null, cn0.getDataExpr());
    assertEquals("XXX", cn0.genBasePhName());
    assertEquals(0, cn0.numChildren());
    CallDelegateNode cn1 = (CallDelegateNode) nodes.get(1);
    assertEquals("foo.goo.mooTemplate", cn1.getDelCalleeName());
    assertEquals(true, cn1.isPassingData());
    assertEquals(true, cn1.isPassingAllData());
    assertEquals(null, cn1.getDataExpr());
    assertFalse(cn1.genSamenessKey().equals(cn0.genSamenessKey()));
    assertEquals(0, cn1.numChildren());
    CallDelegateNode cn2 = (CallDelegateNode) nodes.get(2);
    assertEquals("MySecretFeature.zooTemplate", cn2.getDelCalleeName());
    assertEquals(true, cn2.isPassingData());
    assertEquals(false, cn2.isPassingAllData());
    assertTrue(cn2.getDataExpr().getRoot() != null);
    assertEquals("$animals", cn2.getDataExpr().toSourceString());
    assertEquals(2, cn2.numChildren());
    CallParamValueNode cn2cpvn0 = (CallParamValueNode) cn2.getChild(0);
    assertEquals("yoo", cn2cpvn0.getKey().identifier());
    assertEquals("round($too)", cn2cpvn0.getExpr().toSourceString());
    assertTrue(cn2cpvn0.getExpr().getRoot() instanceof FunctionNode);
    CallParamContentNode cn2cpcn1 = (CallParamContentNode) cn2.getChild(1);
    assertEquals("woo", cn2cpcn1.getKey().identifier());
    assertEquals("poo", ((RawTextNode) cn2cpcn1.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) CallDelegateNode(com.google.template.soy.soytree.CallDelegateNode) Test(org.junit.Test)

Example 9 with CallParamContentNode

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

the class SoyNodeCompiler method prepareParamsHelper.

private Expression prepareParamsHelper(CallNode node, Label reattachPoint) {
    if (node.numChildren() == 0) {
        // Easy, just use the data attribute
        return getDataExpression(node, reattachPoint);
    } else {
        // Otherwise we need to build a dictionary from {param} statements.
        Expression paramStoreExpression = getParamStoreExpression(node, reattachPoint);
        for (CallParamNode child : node.getChildren()) {
            String paramKey = child.getKey().identifier();
            Expression valueExpr;
            if (child instanceof CallParamContentNode) {
                valueExpr = lazyClosureCompiler.compileLazyContent("param", (CallParamContentNode) child, paramKey);
            } else {
                valueExpr = lazyClosureCompiler.compileLazyExpression("param", child, paramKey, ((CallParamValueNode) child).getExpr());
            }
            // ParamStore.setField return 'this' so we can just chain the invocations together.
            paramStoreExpression = MethodRef.PARAM_STORE_SET_FIELD.invoke(paramStoreExpression, BytecodeUtils.constant(paramKey), valueExpr);
        }
        return paramStoreExpression;
    }
}
Also used : SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Expression(com.google.template.soy.jbcsrc.restricted.Expression) CallParamContentNode(com.google.template.soy.soytree.CallParamContentNode) CallParamNode(com.google.template.soy.soytree.CallParamNode) CallParamValueNode(com.google.template.soy.soytree.CallParamValueNode)

Aggregations

CallParamContentNode (com.google.template.soy.soytree.CallParamContentNode)9 CallParamNode (com.google.template.soy.soytree.CallParamNode)7 CallParamValueNode (com.google.template.soy.soytree.CallParamValueNode)6 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)4 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)3 ImmutableList (com.google.common.collect.ImmutableList)2 SanitizedContentKind (com.google.template.soy.base.internal.SanitizedContentKind)2 FunctionNode (com.google.template.soy.exprtree.FunctionNode)2 Test (org.junit.Test)2 ContentKind (com.google.template.soy.data.SanitizedContent.ContentKind)1 SoyRecord (com.google.template.soy.data.SoyRecord)1 SoyValue (com.google.template.soy.data.SoyValue)1 AugmentedParamStore (com.google.template.soy.data.internal.AugmentedParamStore)1 BasicParamStore (com.google.template.soy.data.internal.BasicParamStore)1 ParamStore (com.google.template.soy.data.internal.ParamStore)1 Expression (com.google.template.soy.jbcsrc.restricted.Expression)1 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)1 PyExpr (com.google.template.soy.pysrc.restricted.PyExpr)1 PyListExpr (com.google.template.soy.pysrc.restricted.PyListExpr)1 PyStringExpr (com.google.template.soy.pysrc.restricted.PyStringExpr)1