use of com.google.template.soy.exprtree.ExprNode in project closure-templates by google.
the class SimplifyExprVisitor method visitConditionalOpNode.
@Override
protected void visitConditionalOpNode(ConditionalOpNode node) {
// Recurse.
visitChildren(node);
// Can simplify if operand0 is constant. We assume no side-effects.
SoyValue operand0 = getConstantOrNull(node.getChild(0));
if (operand0 == null) {
// cannot simplify
return;
}
ExprNode replacementNode = operand0.coerceToBoolean() ? node.getChild(1) : node.getChild(2);
node.getParent().replaceChild(node, replacementNode);
}
use of com.google.template.soy.exprtree.ExprNode in project closure-templates by google.
the class EvalVisitor method visitLegacyObjectMapLiteralOrMapLiteralNode.
private SoyValue visitLegacyObjectMapLiteralOrMapLiteralNode(AbstractParentExprNode node) {
checkState(node.getKind() == ExprNode.Kind.LEGACY_OBJECT_MAP_LITERAL_NODE || node.getKind() == ExprNode.Kind.MAP_LITERAL_NODE);
int numItems = node.numChildren() / 2;
boolean isStringKeyed = true;
ExprNode firstNonstringKeyNode = null;
List<SoyValue> keys = Lists.newArrayListWithCapacity(numItems);
List<SoyValue> values = Lists.newArrayListWithCapacity(numItems);
for (int i = 0; i < numItems; i++) {
SoyValue key = visit(node.getChild(2 * i));
if (isStringKeyed && !(key instanceof StringData)) {
isStringKeyed = false;
// temporary until we support nonstring key
firstNonstringKeyNode = node.getChild(2 * i);
}
keys.add(key);
values.add(visit(node.getChild(2 * i + 1)));
}
if (node.getKind() == ExprNode.Kind.LEGACY_OBJECT_MAP_LITERAL_NODE) {
if (!isStringKeyed) {
throw RenderException.create(String.format("legacy_object_map literals must have string keys (key \"%s\" in map %s does not " + "evaluate to a string).", firstNonstringKeyNode.toSourceString(), node.toSourceString()));
}
// Not an ImmutableMap, because map literals allow duplicate keys (last one wins).
Map<String, SoyValue> map = new LinkedHashMap<>();
for (int i = 0; i < numItems; i++) {
map.put(keys.get(i).stringValue(), values.get(i));
}
return DictImpl.forProviderMap(map, RuntimeMapTypeTracker.Type.LEGACY_OBJECT_MAP_OR_RECORD);
} else {
ImmutableMap.Builder<SoyValue, SoyValue> builder = ImmutableMap.builder();
for (int i = 0; i < numItems; ++i) {
SoyValue key = keys.get(i);
SoyValue value = values.get(i);
if (isNullOrUndefinedBase(key)) {
throw RenderException.create(String.format("null key in entry: null=%s", value));
}
builder.put(key, value);
}
return SoyMapImpl.forProviderMap(builder.build());
}
}
use of com.google.template.soy.exprtree.ExprNode in project closure-templates by google.
the class ResolvePackageRelativeCssNamesPass method resolveSelector.
private void resolveSelector(TemplateNode template, FunctionNode node, @Nullable String packagePrefix) {
if (node.getSoyFunction() != BuiltinFunction.CSS) {
return;
}
ExprNode lastChild = Iterables.getLast(node.getChildren());
if (!(lastChild instanceof StringNode)) {
// this will generate an error in CheckFunctionCallsVisitor
return;
}
StringNode selector = (StringNode) Iterables.getLast(node.getChildren());
String selectorText = selector.getValue();
if (!selectorText.startsWith(RELATIVE_SELECTOR_PREFIX)) {
return;
}
if (node.numChildren() > 1) {
errorReporter.report(selector.getSourceLocation(), PACKAGE_RELATIVE_CLASS_NAME_USED_WITH_COMPONENT_NAME, selectorText);
}
if (packagePrefix == null) {
errorReporter.report(selector.getSourceLocation(), NO_CSS_PACKAGE, selectorText, template.getRequiredCssNamespaces().isEmpty() ? "" : " NOTE: ''requirecss'' on a template is not used to infer the CSS package.");
}
// Replace the selector text with resolved selector text
String prefixed = packagePrefix + selectorText.substring(RELATIVE_SELECTOR_PREFIX.length());
StringNode newSelector = new StringNode(prefixed, QuoteStyle.SINGLE, selector.getSourceLocation());
node.replaceChild(selector, newSelector);
}
use of com.google.template.soy.exprtree.ExprNode in project closure-templates by google.
the class TemplateDelegateNodeBuilder method setCommandValues.
@Override
public TemplateNodeBuilder setCommandValues(Identifier templateName, List<CommandTagAttribute> attrs) {
this.cmdText = templateName.identifier() + " " + Joiner.on(' ').join(attrs);
setCommonCommandValues(attrs);
this.delTemplateName = templateName.identifier();
for (CommandTagAttribute attribute : attrs) {
Identifier name = attribute.getName();
if (COMMON_ATTRIBUTE_NAMES.contains(name.identifier())) {
continue;
}
switch(name.identifier()) {
case "variant":
// need to get variant parsing out of this. maybe we can expose some sort of limited
// primitiveOrGlobal parsing solution?
ExprNode variantExpr = attribute.valueAsExpr(errorReporter);
validateVariantExpression(variantExpr, errorReporter);
this.delTemplateVariantExpr = new ExprRootNode(variantExpr);
break;
default:
errorReporter.report(name.location(), CommandTagAttribute.UNSUPPORTED_ATTRIBUTE_KEY, name.identifier(), "deltemplate", ImmutableList.builder().addAll(COMMON_ATTRIBUTE_NAMES).add("variant").build());
}
}
this.delPriority = soyFileHeaderInfo.priority;
genInternalTemplateNameHelper();
return this;
}
use of com.google.template.soy.exprtree.ExprNode in project closure-templates by google.
the class ParseExpressionTest method testParseFunctionCall.
@Test
public void testParseFunctionCall() throws Exception {
ExprNode expr = assertThatExpression("isFirst($x)").isValidExpression();
FunctionNode isFirstFn = (FunctionNode) expr;
assertThat(isFirstFn.getFunctionName()).isEqualTo("isFirst");
assertThat(isFirstFn.numChildren()).isEqualTo(1);
assertThat(isFirstFn.getChild(0).toSourceString()).isEqualTo("$x");
expr = assertThatExpression("round(3.14159, 2)").isValidExpression();
FunctionNode roundFn = (FunctionNode) expr;
assertThat(roundFn.getFunctionName()).isEqualTo("round");
assertThat(roundFn.numChildren()).isEqualTo(2);
assertThat(((FloatNode) roundFn.getChild(0)).getValue()).isEqualTo(3.14159);
assertThat(((IntegerNode) roundFn.getChild(1)).getValue()).isEqualTo(2);
}
Aggregations