Search in sources :

Example 1 with ItemAccessNode

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

the class MsgSubstUnitBaseVarNameUtils method genCandidateBaseNamesForExpr.

/**
 * Private helper for {@code genShortestBaseNameForExpr()} and {@code
 * genNoncollidingBaseNamesForExprs()}.
 *
 * <p>Given an expression that's a data ref or a global, generates the list of all possible base
 * names, from short to long. Shortest contains only the last key. Longest contains up to the
 * first key (unless there are accesses using expressions to compute non-static keys, in which
 * case we cannot generate any more base names). If no base names can be generated for the given
 * expression (i.e. if the expression is not a data ref or global, or the last key is non-static),
 * then returns empty list.
 *
 * <p>For example, given $aaa[0].bbb.cccDdd, generates the list ["CCC_DDD", "BBB_CCC_DDD",
 * "AAA_0_BBB_CCC_DDD"]. One the other hand, given $aaa['xxx'], generates the empty list (because
 * ['xxx'] parses to a DataRefAccessExprNode).
 *
 * @param exprNode The expr root of the expression to generate all candidate base names for.
 * @return The list of all candidate base names, from shortest to longest.
 */
@VisibleForTesting
static List<String> genCandidateBaseNamesForExpr(ExprNode exprNode) {
    if (exprNode instanceof VarRefNode || exprNode instanceof DataAccessNode) {
        List<String> baseNames = Lists.newArrayList();
        String baseName = null;
        while (exprNode != null) {
            String nameSegment = null;
            if (exprNode instanceof VarRefNode) {
                nameSegment = ((VarRefNode) exprNode).getName();
                exprNode = null;
            } else if (exprNode instanceof FieldAccessNode) {
                FieldAccessNode fieldAccess = (FieldAccessNode) exprNode;
                nameSegment = fieldAccess.getFieldName();
                exprNode = fieldAccess.getBaseExprChild();
            } else if (exprNode instanceof ItemAccessNode) {
                ItemAccessNode itemAccess = (ItemAccessNode) exprNode;
                exprNode = itemAccess.getBaseExprChild();
                if (itemAccess.getKeyExprChild() instanceof IntegerNode) {
                    // Prefix with index, but don't add to baseNames list since it's not a valid ident.
                    IntegerNode keyValue = (IntegerNode) itemAccess.getKeyExprChild();
                    if (keyValue.getValue() < 0) {
                        // Stop if we encounter an invalid key.
                        break;
                    }
                    nameSegment = Long.toString(keyValue.getValue());
                    baseName = BaseUtils.convertToUpperUnderscore(nameSegment) + ((baseName != null) ? "_" + baseName : "");
                    continue;
                } else {
                    // Stop if we encounter a non-static key
                    break;
                }
            } else {
                // Stop if we encounter an expression that is not representable as a name.
                break;
            }
            baseName = BaseUtils.convertToUpperUnderscore(nameSegment) + ((baseName != null) ? "_" + baseName : "");
            // new candidate base name whenever we encounter a key
            baseNames.add(baseName);
        }
        return baseNames;
    } else if (exprNode instanceof GlobalNode) {
        String[] globalNameParts = ((GlobalNode) exprNode).getName().split("\\.");
        List<String> baseNames = Lists.newArrayList();
        String baseName = null;
        for (int i = globalNameParts.length - 1; i >= 0; i--) {
            baseName = BaseUtils.convertToUpperUnderscore(globalNameParts[i]) + ((baseName != null) ? "_" + baseName : "");
            baseNames.add(baseName);
        }
        return baseNames;
    } else {
        // We don't handle expressions other than data refs and globals.
        return ImmutableList.of();
    }
}
Also used : DataAccessNode(com.google.template.soy.exprtree.DataAccessNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) ItemAccessNode(com.google.template.soy.exprtree.ItemAccessNode) GlobalNode(com.google.template.soy.exprtree.GlobalNode) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) FieldAccessNode(com.google.template.soy.exprtree.FieldAccessNode) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 2 with ItemAccessNode

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

the class ParseExpressionTest method testParseDataReference.

@Test
public void testParseDataReference() throws Exception {
    SourceLocation loc = SourceLocation.UNKNOWN;
    ExprNode dataRef = assertThatExpression("$boo").isValidExpression();
    assertNodeEquals(new VarRefNode("boo", loc, false, null), dataRef);
    dataRef = assertThatExpression("$boo.foo").isValidExpression();
    assertNodeEquals(new FieldAccessNode(new VarRefNode("boo", loc, false, null), "foo", loc, false), dataRef);
    dataRef = assertThatExpression("$boo[0][$foo]").isValidExpression();
    assertNodeEquals(new ItemAccessNode(new ItemAccessNode(new VarRefNode("boo", loc, false, null), new IntegerNode(0, loc), loc, false), new VarRefNode("foo", loc, false, null), loc, false), dataRef);
    dataRef = assertThatExpression("$boo?[0]?[$foo]").isValidExpression();
    assertNodeEquals(new ItemAccessNode(new ItemAccessNode(new VarRefNode("boo", loc, false, null), new IntegerNode(0, loc), loc, true), new VarRefNode("foo", loc, false, null), loc, true), dataRef);
    dataRef = assertThatExpression("$ij.boo?[0][$ij.foo]").isValidExpression();
    assertNodeEquals(new ItemAccessNode(new ItemAccessNode(new VarRefNode("boo", loc, true, null), new IntegerNode(0, loc), loc, true), new VarRefNode("foo", loc, true, null), loc, false), dataRef);
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) ExprNode(com.google.template.soy.exprtree.ExprNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) ItemAccessNode(com.google.template.soy.exprtree.ItemAccessNode) FieldAccessNode(com.google.template.soy.exprtree.FieldAccessNode) Test(org.junit.Test)

Aggregations

FieldAccessNode (com.google.template.soy.exprtree.FieldAccessNode)2 IntegerNode (com.google.template.soy.exprtree.IntegerNode)2 ItemAccessNode (com.google.template.soy.exprtree.ItemAccessNode)2 VarRefNode (com.google.template.soy.exprtree.VarRefNode)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableList (com.google.common.collect.ImmutableList)1 SourceLocation (com.google.template.soy.base.SourceLocation)1 DataAccessNode (com.google.template.soy.exprtree.DataAccessNode)1 ExprNode (com.google.template.soy.exprtree.ExprNode)1 GlobalNode (com.google.template.soy.exprtree.GlobalNode)1 List (java.util.List)1 Test (org.junit.Test)1