use of com.google.template.soy.soytree.RawTextNode in project closure-templates by google.
the class CombineConsecutiveRawTextNodesPassTest method testCombineConsecutiveRawTextNodes_preserveSourceLocations.
@Test
public void testCombineConsecutiveRawTextNodes_preserveSourceLocations() {
String testFileContent = "{namespace boo}{template .foo}\nbl{nil}ah\n{/template}";
ErrorReporter boom = ErrorReporter.exploding();
SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(testFileContent).errorReporter(boom).parse().fileSet();
TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
assertThat(template.numChildren()).isEqualTo(1);
RawTextNode node = (RawTextNode) template.getChild(0);
assertThat(node.getRawText()).isEqualTo("blah");
assertThat(node.getSourceLocation().getBeginPoint()).isEqualTo(Point.create(2, 1));
assertThat(node.getSourceLocation().getEndPoint()).isEqualTo(Point.create(2, 9));
// we also know the locations of individual characters
assertThat(node.locationOf(2)).isEqualTo(Point.create(2, 8));
// split it up into 1 node per character
// arbitrary
int newId = 1;
RawTextNode c1 = node.substring(newId, 0, 1);
RawTextNode c2 = node.substring(newId, 1, 2);
RawTextNode c3 = node.substring(newId, 2, 3);
RawTextNode c4 = node.substring(newId, 3, 4);
template.removeChild(node);
template.addChildren(Arrays.asList(c1, c2, c3, c4));
assertThat(template.numChildren()).isEqualTo(4);
new CombineConsecutiveRawTextNodesPass().run(soyTree);
assertThat(template.numChildren()).isEqualTo(1);
node = (RawTextNode) template.getChild(0);
// all the data is preserved across the join operation
assertThat(node.getRawText()).isEqualTo("blah");
assertThat(node.getSourceLocation().getBeginPoint()).isEqualTo(Point.create(2, 1));
assertThat(node.getSourceLocation().getEndPoint()).isEqualTo(Point.create(2, 9));
assertThat(node.locationOf(2)).isEqualTo(Point.create(2, 8));
}
use of com.google.template.soy.soytree.RawTextNode in project closure-templates by google.
the class InsertMsgsVisitorTest method testFallbackMsgsUsingMsgBundle.
@Test
public void testFallbackMsgsUsingMsgBundle() {
SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(FALLBACK_TEST_FILE_CONTENT).parse().fileSet();
TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
// Before.
assertThat(template.numChildren()).isEqualTo(4);
assertThat(((MsgFallbackGroupNode) template.getChild(0)).numChildren()).isEqualTo(2);
assertThat(((MsgFallbackGroupNode) template.getChild(1)).numChildren()).isEqualTo(2);
assertThat(((MsgFallbackGroupNode) template.getChild(2)).numChildren()).isEqualTo(2);
assertThat(((MsgFallbackGroupNode) template.getChild(3)).numChildren()).isEqualTo(2);
// Build the translated message bundle.
List<SoyMsg> translatedMsgs = Lists.newArrayList();
MsgNode trans1FirstInstance = ((MsgFallbackGroupNode) template.getChild(1)).getChild(0);
translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(trans1FirstInstance)).setLocaleString("x-zz").setParts(ImmutableList.<SoyMsgPart>of(SoyMsgRawTextPart.of("ztrans1"))).build());
MsgNode trans2FirstInstance = ((MsgFallbackGroupNode) template.getChild(2)).getChild(1);
translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(trans2FirstInstance)).setLocaleString("x-zz").setParts(ImmutableList.<SoyMsgPart>of(SoyMsgRawTextPart.of("ztrans2"))).build());
SoyMsgBundle msgBundle = new SoyMsgBundleImpl("x-zz", translatedMsgs);
// Execute the visitor.
new InsertMsgsVisitor(msgBundle, FAIL).insertMsgs(template);
// After.
assertThat(template.numChildren()).isEqualTo(4);
assertThat(((RawTextNode) template.getChild(0)).getRawText()).isEqualTo("noTrans1");
assertThat(((RawTextNode) template.getChild(1)).getRawText()).isEqualTo("ztrans1");
assertThat(((RawTextNode) template.getChild(2)).getRawText()).isEqualTo("ztrans2");
assertThat(((RawTextNode) template.getChild(3)).getRawText()).isEqualTo("ztrans1");
}
use of com.google.template.soy.soytree.RawTextNode in project closure-templates by google.
the class InsertMsgsVisitorTest method testBasicMsgsUsingMsgBundle.
@Test
public void testBasicMsgsUsingMsgBundle() {
SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(BASIC_TEST_FILE_CONTENT).parse().fileSet();
TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
// Before.
assertThat(template.numChildren()).isEqualTo(5);
MsgNode msg = ((MsgFallbackGroupNode) template.getChild(2)).getChild(0);
assertThat(msg.numChildren()).isEqualTo(5);
MsgHtmlTagNode msgHtmlTag2 = (MsgHtmlTagNode) ((MsgPlaceholderNode) msg.getChild(2)).getChild(0);
assertThat(msgHtmlTag2.numChildren()).isEqualTo(3);
MsgHtmlTagNode msgHtmlTag4 = (MsgHtmlTagNode) ((MsgPlaceholderNode) msg.getChild(4)).getChild(0);
assertThat(msgHtmlTag4.numChildren()).isEqualTo(1);
assertThat(((RawTextNode) msgHtmlTag4.getChild(0)).getRawText()).isEqualTo("</a>");
// Build the translated message bundle.
List<SoyMsg> translatedMsgs = Lists.newArrayList();
// Original (en): random{{FOO}}{{START_LINK}}slimy{{END_LINK}}
// Translation (x-zz): {{START_LINK}}zslimy{{END_LINK}}{{FOO}}zrandom
translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(msg)).setLocaleString("x-zz").setParts(ImmutableList.of(new SoyMsgPlaceholderPart("START_LINK", /* placeholderExample= */
null), SoyMsgRawTextPart.of("zslimy"), new SoyMsgPlaceholderPart("END_LINK", /* placeholderExample= */
null), new SoyMsgPlaceholderPart("FOO", /* placeholderExample= */
null), SoyMsgRawTextPart.of("zrandom"))).build());
// Note: This bundle has no translation for the message "dairy{$moo}".
SoyMsgBundle msgBundle = new SoyMsgBundleImpl("x-zz", translatedMsgs);
// Execute the visitor.
new InsertMsgsVisitor(msgBundle, FAIL).insertMsgs(template);
// After.
assertThat(template.numChildren()).isEqualTo(12);
assertThat(((PrintNode) template.getChild(0)).getExpr().toSourceString()).isEqualTo("$boo");
assertThat(((RawTextNode) template.getChild(1)).getRawText()).isEqualTo("scary ");
assertThat(((RawTextNode) template.getChild(2)).getRawText()).isEqualTo("<a href=\"");
assertThat(((PrintNode) template.getChild(3)).getExpr().toSourceString()).isEqualTo("$goo");
assertThat(((RawTextNode) template.getChild(4)).getRawText()).isEqualTo("\">");
assertThat(((RawTextNode) template.getChild(5)).getRawText()).isEqualTo("zslimy");
assertThat(((RawTextNode) template.getChild(6)).getRawText()).isEqualTo("</a>");
assertThat(((PrintNode) template.getChild(7)).getExpr().toSourceString()).isEqualTo("$foo");
assertThat(((RawTextNode) template.getChild(8)).getRawText()).isEqualTo("zrandom");
assertThat(((RawTextNode) template.getChild(9)).getRawText()).isEqualTo(" ");
assertThat(((RawTextNode) template.getChild(10)).getRawText()).isEqualTo("dairy");
assertThat(((PrintNode) template.getChild(11)).getExpr().toSourceString()).isEqualTo("$moo");
}
use of com.google.template.soy.soytree.RawTextNode 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.soytree.RawTextNode in project closure-templates by google.
the class InsertMsgsVisitor method buildReplacementNodesFromTranslation.
/**
* Private helper for visitMsgFallbackGroupNode() to build the list of replacement nodes for a
* message from its translation.
*/
private void buildReplacementNodesFromTranslation(MsgNode msg, SoyMsg translation) {
currReplacementNodes = Lists.newArrayList();
for (SoyMsgPart msgPart : translation.getParts()) {
if (msgPart instanceof SoyMsgRawTextPart) {
// Append a new RawTextNode to the currReplacementNodes list.
String rawText = ((SoyMsgRawTextPart) msgPart).getRawText();
currReplacementNodes.add(new RawTextNode(nodeIdGen.genId(), rawText, msg.getSourceLocation()));
} else if (msgPart instanceof SoyMsgPlaceholderPart) {
// Get the representative placeholder node and iterate through its contents.
String placeholderName = ((SoyMsgPlaceholderPart) msgPart).getPlaceholderName();
MsgPlaceholderNode placeholderNode = msg.getRepPlaceholderNode(placeholderName);
for (StandaloneNode contentNode : placeholderNode.getChildren()) {
// simply add the content node to the currReplacementNodes list being built.
if (contentNode instanceof MsgHtmlTagNode) {
currReplacementNodes.addAll(((MsgHtmlTagNode) contentNode).getChildren());
} else {
currReplacementNodes.add(contentNode);
}
}
} else {
throw new AssertionError();
}
}
}
Aggregations