use of com.google.template.soy.exprtree.VarRefNode 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();
}
}
use of com.google.template.soy.exprtree.VarRefNode in project closure-templates by google.
the class TemplateParserTest method testParseIfStmt.
@Test
public void testParseIfStmt() throws Exception {
String templateBody = "{@param zoo : ?}{@param boo: ?}{@param foo : ?}{@param moo : ?}\n" + " {if $zoo}{$zoo}{/if}\n" + " {if $boo}\n" + " Blah\n" + " {elseif $foo.goo > 2}\n" + " {$moo}\n" + " {else}\n" + " Blah {$moo}\n" + " {/if}\n";
List<StandaloneNode> nodes = parseTemplateContent(templateBody, FAIL).getChildren();
assertEquals(2, nodes.size());
IfNode in0 = (IfNode) nodes.get(0);
assertEquals(1, in0.numChildren());
IfCondNode in0icn0 = (IfCondNode) in0.getChild(0);
assertEquals("$zoo", in0icn0.getExpr().toSourceString());
assertEquals(1, in0icn0.numChildren());
assertEquals("$zoo", ((PrintNode) in0icn0.getChild(0)).getExpr().toSourceString());
assertTrue(in0icn0.getExpr().getRoot() instanceof VarRefNode);
IfNode in1 = (IfNode) nodes.get(1);
assertEquals(3, in1.numChildren());
IfCondNode in1icn0 = (IfCondNode) in1.getChild(0);
assertEquals("$boo", in1icn0.getExpr().toSourceString());
assertTrue(in1icn0.getExpr().getRoot() instanceof VarRefNode);
IfCondNode in1icn1 = (IfCondNode) in1.getChild(1);
assertEquals("$foo.goo > 2", in1icn1.getExpr().toSourceString());
assertTrue(in1icn1.getExpr().getRoot() instanceof GreaterThanOpNode);
assertEquals("{if $boo}Blah{elseif $foo.goo > 2}{$moo}{else}Blah {$moo}{/if}", in1.toSourceString());
}
use of com.google.template.soy.exprtree.VarRefNode in project closure-templates by google.
the class HtmlCloseTagNodeTest method testToSourceString.
@Test
public void testToSourceString() {
RawTextNode node = new RawTextNode(0, "div", SourceLocation.UNKNOWN);
HtmlCloseTagNode closeTag = new HtmlCloseTagNode(1, new TagName(node), SourceLocation.UNKNOWN);
closeTag.addChild(node);
assertThat(closeTag.toSourceString()).isEqualTo("</div>");
PrintNode dynamicTagName = new PrintNode(2, SourceLocation.UNKNOWN, true, new VarRefNode("tag", SourceLocation.UNKNOWN, false, null), ImmutableList.of(), ErrorReporter.exploding());
closeTag = new HtmlCloseTagNode(1, new TagName(dynamicTagName), SourceLocation.UNKNOWN);
closeTag.addChild(dynamicTagName);
assertThat(closeTag.toSourceString()).isEqualTo("</{$tag}>");
}
use of com.google.template.soy.exprtree.VarRefNode in project closure-templates by google.
the class PrintNodeTest method testToSourceString.
@Test
public void testToSourceString() {
VarRefNode boo = new VarRefNode("boo", X, false, null);
PrintNode pn = new PrintNode(0, X, true, /* isImplicit */
boo, ImmutableList.of(), FAIL);
assertThat(pn.toSourceString()).isEqualTo("{$boo}");
pn = new PrintNode(0, X, false, /* isImplicit */
boo, ImmutableList.of(), FAIL);
assertThat(pn.toSourceString()).isEqualTo("{print $boo}");
}
use of com.google.template.soy.exprtree.VarRefNode in project closure-templates by google.
the class SoyUtils method parseCompileTimeGlobals.
/**
* Parses a globals file in the format created by {@link #generateCompileTimeGlobalsFile} into a
* map from global name to primitive value.
*
* @param inputSource A source that returns a reader for the globals file.
* @return The parsed globals map.
* @throws IOException If an error occurs while reading the globals file.
* @throws IllegalStateException If the globals file is not in the correct format.
*/
public static ImmutableMap<String, PrimitiveData> parseCompileTimeGlobals(CharSource inputSource) throws IOException {
Builder<String, PrimitiveData> compileTimeGlobalsBuilder = ImmutableMap.builder();
ErrorReporter errorReporter = ErrorReporter.exploding();
try (BufferedReader reader = inputSource.openBufferedStream()) {
int lineNum = 1;
for (String line = reader.readLine(); line != null; line = reader.readLine(), ++lineNum) {
if (line.startsWith("//") || line.trim().length() == 0) {
continue;
}
SourceLocation sourceLocation = new SourceLocation("globals", lineNum, 1, lineNum, 1);
Matcher matcher = COMPILE_TIME_GLOBAL_LINE.matcher(line);
if (!matcher.matches()) {
errorReporter.report(sourceLocation, INVALID_FORMAT, line);
continue;
}
String name = matcher.group(1);
String valueText = matcher.group(2).trim();
ExprNode valueExpr = SoyFileParser.parseExprOrDie(valueText);
// TODO: Consider allowing non-primitives (e.g. list/map literals).
if (!(valueExpr instanceof PrimitiveNode)) {
if (valueExpr instanceof GlobalNode || valueExpr instanceof VarRefNode) {
errorReporter.report(sourceLocation, INVALID_VALUE, valueExpr.toSourceString());
} else {
errorReporter.report(sourceLocation, NON_PRIMITIVE_VALUE, valueExpr.toSourceString());
}
continue;
}
// Default case.
compileTimeGlobalsBuilder.put(name, InternalValueUtils.convertPrimitiveExprToData((PrimitiveNode) valueExpr));
}
}
return compileTimeGlobalsBuilder.build();
}
Aggregations