use of com.google.template.soy.exprtree.StringNode in project closure-templates by google.
the class TranslateExprNodeVisitor method visitLegacyObjectMapLiteralNode.
/**
* Helper to visit a LegacyObjectMapLiteralNode, with the extra option of whether to quote keys.
*/
private CodeChunk.WithValue visitLegacyObjectMapLiteralNode(LegacyObjectMapLiteralNode node, boolean doQuoteKeys) {
// If there are only string keys, then the expression will be
// {aa: 11, bb: 22} or {'aa': 11, 'bb': 22}
// where the former is with unquoted keys and the latter with quoted keys.
// If there are both string and nonstring keys, then the expression will be
// (function() { var $$tmp0 = {'aa': 11}; $$tmp0[opt_data.bb] = 22; return $$tmp0; })()
// Since we are outputting JS code to be processed by Closure Compiler, it is important that
// any unquoted map literal keys are string literals, since Closure Compiler can rename unquoted
// map keys and we want everything to be renamed at the same time.
// We will divide the map literal contents into two categories.
//
// Key-value pairs with StringNode keys can be included in the JS object literal.
// Key-value pairs that are not StringNodes (VarRefs, IJ values, etc.) must be passed through
// the soy.$$checkLegacyObjectMapLiteralKey() function, cannot be included in the JS object
// literal, and must generate code in the form of:
// $$map[soy.$$checkLegacyObjectMapLiteralKey(key)] = value
LinkedHashMap<CodeChunk.WithValue, CodeChunk.WithValue> objLiteral = new LinkedHashMap<>();
LinkedHashMap<CodeChunk.WithValue, CodeChunk.WithValue> assignments = new LinkedHashMap<>();
for (int i = 0; i < node.numChildren(); i += 2) {
ExprNode keyNode = node.getChild(i);
ExprNode valueNode = node.getChild(i + 1);
// roll it into the next case.
if (!(keyNode instanceof StringNode) && keyNode instanceof PrimitiveNode) {
errorReporter.report(keyNode.getSourceLocation(), CONSTANT_USED_AS_KEY_IN_MAP_LITERAL, keyNode.toSourceString());
continue;
}
// since the compiler may change the names of any unquoted map keys.
if (!doQuoteKeys && !(keyNode instanceof StringNode)) {
errorReporter.report(keyNode.getSourceLocation(), EXPR_IN_MAP_LITERAL_REQUIRES_QUOTE_KEYS_IF_JS, keyNode.toSourceString());
continue;
}
if (keyNode instanceof StringNode) {
if (doQuoteKeys) {
objLiteral.put(visit(keyNode), visit(valueNode));
} else {
String strKey = ((StringNode) keyNode).getValue();
if (BaseUtils.isIdentifier(strKey)) {
objLiteral.put(id(strKey), visit(valueNode));
} else {
errorReporter.report(keyNode.getSourceLocation(), MAP_LITERAL_WITH_NON_ID_KEY_REQUIRES_QUOTE_KEYS_IF_JS, keyNode.toSourceString());
continue;
}
}
} else {
// key is not a StringNode; key must be passed through
// soy.$$checkLegacyObjectMapLiteralKey() and the pair cannot be included in the JS object
// literal.
CodeChunk.WithValue rawKey = visit(keyNode);
assignments.put(SOY_CHECK_LEGACY_OBJECT_MAP_LITERAL_KEY.call(rawKey), visit(valueNode));
}
}
// Build the map literal
ImmutableList<CodeChunk.WithValue> keys = ImmutableList.copyOf(objLiteral.keySet());
ImmutableList<CodeChunk.WithValue> values = ImmutableList.copyOf(objLiteral.values());
CodeChunk.WithValue map = mapLiteral(keys, values);
if (assignments.isEmpty()) {
// to a tmp var.
return map;
}
// Otherwise, we need to bail to a tmp var and emit assignment statements.
CodeChunk.WithValue mapVar = codeGenerator.declarationBuilder().setRhs(map).build().ref();
ImmutableList.Builder<CodeChunk> initialStatements = ImmutableList.builder();
for (Map.Entry<CodeChunk.WithValue, CodeChunk.WithValue> entry : assignments.entrySet()) {
initialStatements.add(mapVar.bracketAccess(entry.getKey()).assign(entry.getValue()));
}
return mapVar.withInitialStatements(initialStatements.build());
}
use of com.google.template.soy.exprtree.StringNode in project closure-templates by google.
the class VeLogInstrumentationVisitor method visitHtmlAttributeNode.
/**
* For HtmlAttributeNode that has a logging function as its value, replace the logging function
* with its place holder, and append a new data attribute that contains all the desired
* information that are used later by the runtime library.
*/
@Override
protected void visitHtmlAttributeNode(HtmlAttributeNode node) {
// Skip attributes that do not have a value.
if (!node.hasValue()) {
return;
}
SourceLocation insertionLocation = node.getSourceLocation();
for (FunctionNode function : SoyTreeUtils.getAllNodesOfType(node, FunctionNode.class)) {
if (!(function.getSoyFunction() instanceof LoggingFunction)) {
continue;
}
FunctionNode funcNode = new FunctionNode(VeLogJsSrcLoggingFunction.INSTANCE, insertionLocation);
funcNode.addChild(new StringNode(function.getFunctionName(), QuoteStyle.SINGLE, insertionLocation));
funcNode.addChild(new ListLiteralNode(function.getChildren(), insertionLocation));
StandaloneNode attributeName = node.getChild(0);
if (attributeName instanceof RawTextNode) {
// If attribute name is a plain text, directly pass it as a function argument.
funcNode.addChild(new StringNode(((RawTextNode) attributeName).getRawText(), QuoteStyle.SINGLE, insertionLocation));
} else {
// Otherwise wrap the print node or call node into a let block, and use the let variable
// as a function argument.
String varName = "soy_logging_function_attribute_" + counter;
LetContentNode letNode = LetContentNode.forVariable(nodeIdGen.genId(), attributeName.getSourceLocation(), varName, null);
// Adds a let var which references to the original attribute name, and move the name to
// the let block.
node.replaceChild(attributeName, new PrintNode(nodeIdGen.genId(), insertionLocation, /* isImplicit= */
true, /* expr= */
new VarRefNode(varName, insertionLocation, false, letNode.getVar()), /* attributes= */
ImmutableList.of(), ErrorReporter.exploding()));
letNode.addChild(attributeName);
node.getParent().addChild(node.getParent().getChildIndex(node), letNode);
funcNode.addChild(new VarRefNode(varName, insertionLocation, false, letNode.getVar()));
}
funcNode.addChild(new IntegerNode(counter++, insertionLocation));
PrintNode loggingFunctionAttribute = new PrintNode(nodeIdGen.genId(), insertionLocation, /* isImplicit= */
true, /* expr= */
funcNode, /* attributes= */
ImmutableList.of(), ErrorReporter.exploding());
// Append the logging function attribute to its parent
int appendIndex = node.getParent().getChildIndex(node) + 1;
node.getParent().addChild(appendIndex, loggingFunctionAttribute);
// Replace the original attribute value to the placeholder.
HtmlAttributeValueNode placeHolder = new HtmlAttributeValueNode(nodeIdGen.genId(), insertionLocation, Quotes.DOUBLE);
placeHolder.addChild(new RawTextNode(nodeIdGen.genId(), ((LoggingFunction) function.getSoyFunction()).getPlaceholder(), insertionLocation));
node.replaceChild(node.getChild(1), placeHolder);
// logging function in a html attribute value.
break;
}
visitChildren(node);
}
use of com.google.template.soy.exprtree.StringNode 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.StringNode in project closure-templates by google.
the class InternalValueUtilsTest method testConvertPrimitiveExprToData.
@Test
public void testConvertPrimitiveExprToData() {
assertTrue(InternalValueUtils.convertPrimitiveExprToData(new NullNode(SourceLocation.UNKNOWN)) instanceof NullData);
assertTrue(InternalValueUtils.convertPrimitiveExprToData(new BooleanNode(true, SourceLocation.UNKNOWN)).booleanValue());
assertEquals(-1, InternalValueUtils.convertPrimitiveExprToData(new IntegerNode(-1, SourceLocation.UNKNOWN)).integerValue());
assertEquals(6.02e23, InternalValueUtils.convertPrimitiveExprToData(new FloatNode(6.02e23, SourceLocation.UNKNOWN)).floatValue(), 0.0);
assertEquals("foo", InternalValueUtils.convertPrimitiveExprToData(new StringNode("foo", QuoteStyle.SINGLE, SourceLocation.UNKNOWN)).stringValue());
}
use of com.google.template.soy.exprtree.StringNode in project closure-templates by google.
the class ParseExpressionTest method testParsePrimitives.
@Test
public void testParsePrimitives() throws Exception {
ExprNode expr = assertThatExpression("null").isValidExpression();
assertThat(expr).isInstanceOf(NullNode.class);
expr = assertThatExpression("true").isValidExpression();
assertThat(((BooleanNode) expr).getValue()).isTrue();
expr = assertThatExpression("false").isValidExpression();
assertThat(((BooleanNode) expr).getValue()).isFalse();
expr = assertThatExpression("26").isValidExpression();
assertThat(((IntegerNode) expr).getValue()).isEqualTo(26);
expr = assertThatExpression("0xCAFE").isValidExpression();
assertThat(((IntegerNode) expr).getValue()).isEqualTo(0xCAFE);
expr = assertThatExpression("3.14").isValidExpression();
assertThat(((FloatNode) expr).getValue()).isEqualTo(3.14);
expr = assertThatExpression("3e-3").isValidExpression();
assertThat(((FloatNode) expr).getValue()).isEqualTo(3e-3);
expr = assertThatExpression("'Aa`! \\n \\r \\t \\\\ \\\' \"'").isValidExpression();
assertThat(((StringNode) expr).getValue()).isEqualTo("Aa`! \n \r \t \\ \' \"");
expr = assertThatExpression("'\\u2222 \\uEEEE \\u9EC4 \\u607A'").isValidExpression();
assertThat(((StringNode) expr).getValue()).isEqualTo("\u2222 \uEEEE \u9EC4 \u607A");
expr = assertThatExpression("'\u2222 \uEEEE \u9EC4 \u607A'").isValidExpression();
assertThat(((StringNode) expr).getValue()).isEqualTo("\u2222 \uEEEE \u9EC4 \u607A");
}
Aggregations