use of com.google.template.soy.exprtree.DataAccessNode 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();
}
}
Aggregations