Search in sources :

Example 11 with ExprNode

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

the class TemplateDelegateNodeBuilder method genInternalTemplateNameHelper.

/**
 * Private helper for both setCmdText() and setCmdTextInfo() to generate and set the internal-use
 * partial template name and template name.
 */
private void genInternalTemplateNameHelper() {
    Preconditions.checkState(id != null);
    // encode all the deltemplate information into the name to get a unique string
    // though... it might make more sense for this to not have a user visible name given that the
    // calling convention is indirect.
    String variant = "";
    if (delTemplateVariantExpr != null) {
        // this is hacky.  perhaps we should come up with a less ambiguous strategy
        ExprNode expr = delTemplateVariantExpr.getRoot();
        if (expr instanceof StringNode) {
            variant = ((StringNode) expr).getValue();
        } else {
            variant = expr.toSourceString();
        }
    }
    String delPackageTemplateAndVariantStr = (soyFileHeaderInfo.delPackageName == null ? "" : soyFileHeaderInfo.delPackageName) + "_" + delTemplateName.replace('.', '_') + "_" + variant;
    delPackageTemplateAndVariantStr = delPackageTemplateAndVariantStr.replace('.', '_');
    // Generate the actual internal-use template name.
    String generatedPartialTemplateName = ".__deltemplate_" + delPackageTemplateAndVariantStr;
    String generatedTemplateName = soyFileHeaderInfo.namespace + generatedPartialTemplateName;
    setTemplateNames(generatedTemplateName, generatedPartialTemplateName);
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) StringNode(com.google.template.soy.exprtree.StringNode)

Example 12 with ExprNode

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

the class TemplateDelegateNode method resolveVariantExpression.

/**
 * Calculate a DeltemplateKey for the variant.
 *
 * <p>This is done lazily so that global references can be resolved. This is not ideal since
 * nothing guarantees that resolution happens before access.
 *
 * <p>Note we don't do validation of the variant values since that is handled by the
 * TemplateDelegateNodeBuilder during construction
 */
private DelTemplateKey resolveVariantExpression() {
    if (delTemplateVariantExpr == null) {
        delTemplateKey = DelTemplateKey.create(delTemplateName, "");
        return delTemplateKey;
    }
    ExprNode exprNode = delTemplateVariantExpr.getRoot();
    if (exprNode instanceof GlobalNode) {
        GlobalNode globalNode = (GlobalNode) exprNode;
        if (globalNode.isResolved()) {
            exprNode = globalNode.getValue();
        } else {
            // For this reason we also don't store the key, instead we just return it.
            return DelTemplateKey.create(delTemplateName, globalNode.getName());
        }
    }
    if (exprNode instanceof IntegerNode) {
        // Globals were already substituted: We may now create the definitive variant and key fields
        // on this node.
        long variantValue = ((IntegerNode) exprNode).getValue();
        delTemplateKey = DelTemplateKey.create(delTemplateName, String.valueOf(variantValue));
    } else if (exprNode instanceof StringNode) {
        // Globals were already substituted: We may now create the definitive variant and key fields
        // on this node.
        delTemplateKey = DelTemplateKey.create(delTemplateName, ((StringNode) exprNode).getValue());
    } else {
        // We must have already reported an error, just create an arbitrary variant expr.
        delTemplateKey = DelTemplateKey.create(delTemplateName, exprNode.toSourceString());
    }
    return delTemplateKey;
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) StringNode(com.google.template.soy.exprtree.StringNode) GlobalNode(com.google.template.soy.exprtree.GlobalNode)

Example 13 with ExprNode

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

the class MsgSubstUnitBaseVarNameUtils method genNoncollidingBaseNamesForExprs.

/**
 * Generates base names for all the expressions in a list, where for each expression, we use the
 * shortest candidate base name that does not collide with any of the candidate base names
 * generated from other expressions in the list. Two candidate base names are considered to
 * collide if they are identical or if one is a suffix of the other beginning after an underscore
 * character.
 *
 * <p>For example, given the expressions $userGender and $target.gender, the generated base names
 * would be USER_GENDER and TARGET_GENDER. (Even though the shortest candidate base names are
 * USER_GENDER and GENDER, the latter one is not used since it collides with the former one.)
 *
 * <p>Note: We prefer the shorter candidate base names when possible, because the translator
 * usually doesn't care about all the names. E.g. $data.actionTargets[0].personInfo.gender turns
 * into GENDER as opposed to DATA_ACTION_TARGETS_0_PERSON_INFO_GENDER, which is overkill and
 * probably more confusing. Another reason is that refactorings that change higher-level names
 * should not change messages unnecessarily. E.g. a refactoring that changes
 * $data.actionTargets[0].personInfo.gender -> $userData.actionTargets[0].personInfo.gender should
 * not change the placeholder name.
 *
 * @param exprNodes The expr nodes of the expressions to generate noncolliding base names for.
 * @param fallbackBaseName The fallback base name.
 * @param errorReporter For reporting collision errors.
 * @return The list of generated noncolliding base names.
 */
public static List<String> genNoncollidingBaseNamesForExprs(List<ExprNode> exprNodes, String fallbackBaseName, ErrorReporter errorReporter) {
    int numExprs = exprNodes.size();
    // --- Compute candidate base names for each expression. ---
    List<List<String>> candidateBaseNameLists = Lists.newArrayListWithCapacity(numExprs);
    for (ExprNode exprRoot : exprNodes) {
        candidateBaseNameLists.add(genCandidateBaseNamesForExpr(exprRoot));
    }
    // --- Build a multiset of collision strings (if key has > 1 values, then it's a collision). ---
    // Note: We could combine this loop with the previous loop, but it's more readable this way.
    Multimap<String, ExprNode> collisionStrToLongestCandidatesMultimap = HashMultimap.create();
    for (int i = 0; i < numExprs; i++) {
        ExprNode exprRoot = exprNodes.get(i);
        List<String> candidateBaseNameList = candidateBaseNameLists.get(i);
        if (candidateBaseNameList.isEmpty()) {
            continue;
        }
        String longestCandidate = candidateBaseNameList.get(candidateBaseNameList.size() - 1);
        // Add longest candidate as a collision string.
        collisionStrToLongestCandidatesMultimap.put(longestCandidate, exprRoot);
        // Add all suffixes that begin after an underscore char as collision strings.
        for (int j = 0, n = longestCandidate.length(); j < n; j++) {
            if (longestCandidate.charAt(j) == '_') {
                collisionStrToLongestCandidatesMultimap.put(longestCandidate.substring(j + 1), exprRoot);
            }
        }
    }
    // --- Find the shortest noncolliding candidate base name for each expression. ---
    List<String> noncollidingBaseNames = Lists.newArrayListWithCapacity(numExprs);
    OUTER: for (int i = 0; i < numExprs; i++) {
        List<String> candidateBaseNameList = candidateBaseNameLists.get(i);
        if (!candidateBaseNameList.isEmpty()) {
            for (String candidateBaseName : candidateBaseNameList) {
                if (collisionStrToLongestCandidatesMultimap.get(candidateBaseName).size() == 1) {
                    // Found candidate with 1 value in multimap, which means no collision.
                    noncollidingBaseNames.add(candidateBaseName);
                    continue OUTER;
                }
            }
            // Did not find any candidate with no collision.
            ExprNode exprRoot = exprNodes.get(i);
            String longestCandidate = candidateBaseNameList.get(candidateBaseNameList.size() - 1);
            ExprNode collidingExprRoot = null;
            for (ExprNode er : collisionStrToLongestCandidatesMultimap.get(longestCandidate)) {
                if (er != exprRoot) {
                    collidingExprRoot = er;
                    break;
                }
            }
            errorReporter.report(collidingExprRoot.getSourceLocation(), COLLIDING_EXPRESSIONS, exprRoot.toSourceString(), collidingExprRoot.toSourceString());
            return noncollidingBaseNames;
        } else {
            // No candidates: Use fallback.
            noncollidingBaseNames.add(fallbackBaseName);
        }
    }
    return noncollidingBaseNames;
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 14 with ExprNode

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

the class ParseExpressionTest method testParseListsAndMaps.

@Test
public void testParseListsAndMaps() throws Exception {
    ExprNode expr = assertThatExpression("[]").isValidExpression();
    assertThat(((ListLiteralNode) expr).numChildren()).isEqualTo(0);
    expr = assertThatExpression("[55]").isValidExpression();
    assertThat(((ListLiteralNode) expr).numChildren()).isEqualTo(1);
    expr = assertThatExpression("[55,]").isValidExpression();
    assertThat(((ListLiteralNode) expr).numChildren()).isEqualTo(1);
    expr = assertThatExpression("['blah', 123, $boo]").isValidExpression();
    assertThat(((ListLiteralNode) expr).numChildren()).isEqualTo(3);
    expr = assertThatExpression("['blah', 123, $boo,]").isValidExpression();
    assertThat(((ListLiteralNode) expr).numChildren()).isEqualTo(3);
    expr = assertThatExpression("[:]").isValidExpression();
    assertThat(((LegacyObjectMapLiteralNode) expr).numChildren()).isEqualTo(0);
    expr = assertThatExpression("['aa': 55]").isValidExpression();
    assertThat(((LegacyObjectMapLiteralNode) expr).numChildren()).isEqualTo(2);
    expr = assertThatExpression("['aa': 55,]").isValidExpression();
    assertThat(((LegacyObjectMapLiteralNode) expr).numChildren()).isEqualTo(2);
    expr = assertThatExpression("['aaa': 'blah', 'bbb': 123, $foo.bar: $boo]").isValidExpression();
    assertThat(((LegacyObjectMapLiteralNode) expr).numChildren()).isEqualTo(6);
    expr = assertThatExpression("['aaa': 'blah', 'bbb': 123, $foo.bar: $boo,]").isValidExpression();
    assertThat(((LegacyObjectMapLiteralNode) expr).numChildren()).isEqualTo(6);
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) ListLiteralNode(com.google.template.soy.exprtree.ListLiteralNode) LegacyObjectMapLiteralNode(com.google.template.soy.exprtree.LegacyObjectMapLiteralNode) Test(org.junit.Test)

Example 15 with ExprNode

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

the class MsgSubstUnitBaseVarNameUtilsTest method assertShortestBaseNameForExpr.

private void assertShortestBaseNameForExpr(String expected, String exprText) {
    ExprNode exprRoot = parse(exprText);
    String actual = MsgSubstUnitBaseVarNameUtils.genShortestBaseNameForExpr(exprRoot, "FALLBACK");
    assertEquals(expected, actual);
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode)

Aggregations

ExprNode (com.google.template.soy.exprtree.ExprNode)38 ParentExprNode (com.google.template.soy.exprtree.ExprNode.ParentExprNode)7 IntegerNode (com.google.template.soy.exprtree.IntegerNode)7 StringNode (com.google.template.soy.exprtree.StringNode)7 FunctionNode (com.google.template.soy.exprtree.FunctionNode)5 Test (org.junit.Test)5 ImmutableList (com.google.common.collect.ImmutableList)4 SoyValue (com.google.template.soy.data.SoyValue)4 GlobalNode (com.google.template.soy.exprtree.GlobalNode)4 VarRefNode (com.google.template.soy.exprtree.VarRefNode)4 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)4 SoyType (com.google.template.soy.types.SoyType)4 LinkedHashMap (java.util.LinkedHashMap)4 AbstractParentExprNode (com.google.template.soy.exprtree.AbstractParentExprNode)3 FloatNode (com.google.template.soy.exprtree.FloatNode)3 SourceLocation (com.google.template.soy.base.SourceLocation)2 ErrorReporter (com.google.template.soy.error.ErrorReporter)2 BooleanNode (com.google.template.soy.exprtree.BooleanNode)2 PrimitiveNode (com.google.template.soy.exprtree.ExprNode.PrimitiveNode)2 ExprRootNode (com.google.template.soy.exprtree.ExprRootNode)2