use of com.google.template.soy.soytree.SoyNode.ParentSoyNode in project closure-templates by google.
the class GenJsCodeVisitor method visitChildren.
@Override
protected void visitChildren(ParentSoyNode<?> node) {
// initialize the output var.
if (node.numChildren() == 0 || !canInitOutputVarVisitor.exec(node.getChild(0))) {
jsCodeBuilder.initOutputVarIfNecessary();
}
// For children that are computed by GenJsExprsVisitor, try to process as many of them as we can
// before adding to outputVar.
//
// output += 'a' + 'b';
// is preferable to
// output += 'a';
// output += 'b';
// This is because it is actually easier for the jscompiler to optimize.
List<CodeChunk.WithValue> consecChunks = new ArrayList<>();
for (SoyNode child : node.getChildren()) {
if (isComputableAsJsExprsVisitor.exec(child)) {
consecChunks.addAll(genJsExprsVisitor.exec(child));
} else {
if (!consecChunks.isEmpty()) {
jsCodeBuilder.addChunksToOutputVar(consecChunks);
consecChunks.clear();
}
visit(child);
}
}
if (!consecChunks.isEmpty()) {
jsCodeBuilder.addChunksToOutputVar(consecChunks);
consecChunks.clear();
}
}
use of com.google.template.soy.soytree.SoyNode.ParentSoyNode in project closure-templates by google.
the class MsgFuncGenerator method collectVarNameListAndToPyExprMap.
/**
* Private helper to process and collect all variables used within this msg node for code
* generation.
*
* @return A Map populated with all the variables used with in this message node, using {@link
* MsgPlaceholderInitialNode#genBasePhName}.
*/
private Map<PyExpr, PyExpr> collectVarNameListAndToPyExprMap() {
Map<PyExpr, PyExpr> nodePyVarToPyExprMap = new LinkedHashMap<>();
for (Map.Entry<String, MsgSubstUnitNode> entry : msgNode.getVarNameToRepNodeMap().entrySet()) {
MsgSubstUnitNode substUnitNode = entry.getValue();
PyExpr substPyExpr = null;
if (substUnitNode instanceof MsgPlaceholderNode) {
SoyNode phInitialNode = ((AbstractParentSoyNode<?>) substUnitNode).getChild(0);
if (phInitialNode instanceof PrintNode || phInitialNode instanceof CallNode || phInitialNode instanceof RawTextNode) {
substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.exec(phInitialNode)).toPyString();
}
// when the placeholder is generated by HTML tags
if (phInitialNode instanceof MsgHtmlTagNode) {
substPyExpr = PyExprUtils.concatPyExprs(genPyExprsVisitor.execOnChildren((ParentSoyNode<?>) phInitialNode)).toPyString();
}
} else if (substUnitNode instanceof MsgPluralNode) {
// Translates {@link MsgPluralNode#pluralExpr} into a Python lookup expression.
// Note that {@code pluralExpr} represents the soy expression of the {@code plural} attr,
// i.e. the {@code $numDrafts} in {@code {plural $numDrafts}...{/plural}}.
substPyExpr = translateToPyExprVisitor.exec(((MsgPluralNode) substUnitNode).getExpr());
} else if (substUnitNode instanceof MsgSelectNode) {
substPyExpr = translateToPyExprVisitor.exec(((MsgSelectNode) substUnitNode).getExpr());
}
if (substPyExpr != null) {
nodePyVarToPyExprMap.put(new PyStringExpr("'" + entry.getKey() + "'"), substPyExpr);
}
}
return nodePyVarToPyExprMap;
}
use of com.google.template.soy.soytree.SoyNode.ParentSoyNode in project closure-templates by google.
the class CombineConsecutiveRawTextNodesPass method visit.
private void visit(ParentSoyNode<?> node) {
// The raw text node at the beginning of the current sequence
int start = -1;
int lastNonEmptyRawTextNode = -1;
int i = 0;
for (; i < node.numChildren(); i++) {
SoyNode child = node.getChild(i);
if (child instanceof RawTextNode) {
RawTextNode childAsRawText = (RawTextNode) child;
if (start == -1) {
// drop empty raw text nodes at the prefix
if (childAsRawText.getRawText().isEmpty()) {
node.removeChild(i);
i--;
} else {
// mark the beginning of a sequence of nonempty raw text
start = i;
lastNonEmptyRawTextNode = i;
}
} else {
if (!childAsRawText.getRawText().isEmpty()) {
lastNonEmptyRawTextNode = i;
}
}
} else {
i = mergeRange(node, start, lastNonEmptyRawTextNode, i);
// reset
start = -1;
if (child instanceof ParentSoyNode) {
// recurse
visit((ParentSoyNode<?>) child);
}
// else do nothing since it cannot contain raw text nodes
}
}
mergeRange(node, start, lastNonEmptyRawTextNode, i);
}
use of com.google.template.soy.soytree.SoyNode.ParentSoyNode in project closure-templates by google.
the class CombineConsecutiveRawTextNodesPass method mergeRange.
// There is no generic type we could give to ParentSoyNode that wouldn't require unchecked casts
// either here or in our caller. This is safe however since we are only adding or removing
// RawTextNodes and if we can remove a RawTextNode, we can also add one.
@SuppressWarnings("unchecked")
private int mergeRange(ParentSoyNode<?> parent, int start, int lastNonEmptyRawTextNode, int end) {
checkArgument(start < end);
if (start == -1 || end == start + 1) {
return end;
}
// general case, there are N rawtextnodes to merge where n > 1
// merge all the nodes together, then drop all the raw text nodes from the end
RawTextNode newNode = RawTextNode.concat((List<RawTextNode>) parent.getChildren().subList(start, lastNonEmptyRawTextNode + 1));
((ParentSoyNode) parent).replaceChild(start, newNode);
for (int i = end - 1; i > start; i--) {
parent.removeChild(i);
}
return start + 1;
}
Aggregations