use of com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective in project closure-templates by google.
the class GenCallCodeUtils method gen.
/**
* Generates the JS expression for a given call.
*
* <p> Important: If there are CallParamContentNode children whose contents are not computable as
* JS expressions, then this function assumes that, elsewhere, code has been generated to define
* their respective 'param<n>' temporary variables.
*
* <p> Here are five example calls:
* <pre>
* {call some.func data="all" /}
* {call some.func data="$boo.foo" /}
* {call some.func}
* {param goo = $moo /}
* {/call}
* {call some.func data="$boo"}
* {param goo}Blah{/param}
* {/call}
* {call some.func}
* {param goo}
* {for $i in range(3)}{$i}{/for}
* {/param}
* {/call}
* </pre>
* Their respective generated calls might be the following:
* <pre>
* some.func(opt_data)
* some.func(opt_data.boo.foo)
* some.func({goo: opt_data.moo})
* some.func(soy.$$assignDefaults({goo: 'Blah'}, opt_data.boo))
* some.func({goo: param65})
* </pre>
* Note that in the last case, the param content is not computable as JS expressions, so we assume
* that code has been generated to define the temporary variable 'param<n>'.
*
* @param callNode The call to generate code for.
* @param templateAliases A mapping of fully qualified calls to a variable in scope.
* @return The JS expression for the call.
*/
public CodeChunk.WithValue gen(CallNode callNode, TemplateAliases templateAliases, TranslationContext translationContext, ErrorReporter errorReporter) {
// Build the JS CodeChunk for the callee's name.
CodeChunk.WithValue callee;
if (callNode instanceof CallBasicNode) {
// Case 1: Basic call.
// TODO(lukes): add the logic for the goog.require here. The simplest strategy requires a
// TemplateRegistry to detect external templates.
callee = CodeChunk.dottedIdNoRequire(templateAliases.get(((CallBasicNode) callNode).getCalleeName()));
} else {
// Case 2: Delegate call.
CallDelegateNode callDelegateNode = (CallDelegateNode) callNode;
CodeChunk.WithValue calleeId = JsRuntime.SOY_GET_DELTEMPLATE_ID.call(stringLiteral(delTemplateNamer.getDelegateName(callDelegateNode)));
ExprRootNode variantSoyExpr = callDelegateNode.getDelCalleeVariantExpr();
CodeChunk.WithValue variant;
if (variantSoyExpr == null) {
// Case 2a: Delegate call with empty variant.
variant = LITERAL_EMPTY_STRING;
} else {
// Case 2b: Delegate call with variant expression.
variant = new TranslateExprNodeVisitor(translationContext, errorReporter).exec(variantSoyExpr);
}
callee = SOY_GET_DELEGATE_FN.call(calleeId, variant, callDelegateNode.allowEmptyDefault() ? LITERAL_TRUE : LITERAL_FALSE);
}
// Generate the data object to pass to callee
CodeChunk.WithValue objToPass = genObjToPass(callNode, templateAliases, translationContext, errorReporter);
// Generate the main call expression.
CodeChunk.WithValue call = callee.call(objToPass, JsRuntime.OPT_IJ_DATA);
if (callNode.getEscapingDirectives().isEmpty()) {
return call;
}
// Apply escaping directives as necessary.
//
// The print directive system continues to use JsExpr, as it is a publicly available API and
// migrating it to CodeChunk would be a major change. Therefore, we convert our CodeChunks
// to JsExpr and back here.
JsExpr callResult = call.singleExprOrName();
RequiresCollector.IntoImmutableSet collector = new RequiresCollector.IntoImmutableSet();
call.collectRequires(collector);
for (SoyPrintDirective directive : callNode.getEscapingDirectives()) {
Preconditions.checkState(directive instanceof SoyJsSrcPrintDirective, "Contextual autoescaping produced a bogus directive: %s", directive.getName());
callResult = ((SoyJsSrcPrintDirective) directive).applyForJsSrc(callResult, ImmutableList.<JsExpr>of());
if (directive instanceof SoyLibraryAssistedJsSrcPrintDirective) {
for (String name : ((SoyLibraryAssistedJsSrcPrintDirective) directive).getRequiredJsLibNames()) {
collector.add(GoogRequire.create(name));
}
}
}
return fromExpr(callResult, collector.get()).withInitialStatements(call.initialStatements());
}
use of com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective in project closure-templates by google.
the class GenJsExprsVisitor method visitPrintNode.
/**
* Example:
* <pre>
* {$boo.foo}
* {$goo.moo + 5}
* </pre>
* might generate
* <pre>
* opt_data.boo.foo
* gooData4.moo + 5
* </pre>
*/
@Override
protected void visitPrintNode(PrintNode node) {
CodeChunk.WithValue expr = translateExpr(node.getExpr());
// Process directives.
for (PrintDirectiveNode directiveNode : node.getChildren()) {
// Get directive.
SoyPrintDirective directive = directiveNode.getPrintDirective();
if (!(directive instanceof SoyJsSrcPrintDirective)) {
errorReporter.report(node.getSourceLocation(), UNKNOWN_SOY_JS_SRC_PRINT_DIRECTIVE, directiveNode.getName());
return;
}
// Get directive args.
List<ExprRootNode> argNodes = directiveNode.getArgs();
// Convert args to CodeChunks.
List<CodeChunk.WithValue> argChunks = new ArrayList<>(argNodes.size());
for (ExprRootNode argNode : argNodes) {
argChunks.add(translateExpr(argNode));
}
// Apply directive.
expr = SoyJsPluginUtils.applyDirective(translationContext.codeGenerator(), expr, (SoyJsSrcPrintDirective) directive, argChunks);
}
chunks.add(expr);
}
use of com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective in project closure-templates by google.
the class GenJsCodeVisitorAssistantForMsgs method generateMsgGroupVariable.
/**
* Returns a code chunk representing a translated variable.
*
* <p>Example:
*
* <pre>
* {msg desc="Link to help content."}Learn more{/msg}
* {msg desc="Tells user how to access a product." hidden="true"}
* Click <a href="}{$url}">here</a> to access {$productName}.
* {/msg}
* </pre>
*
* might return the following code chunk:
*
* <pre>
* /** @desc Link to help content. *{@literal /}
* var MSG_UNNAMED_9 = goog.getMsg('Learn more');
* var msg_s9 = MSG_UNNAMED_9;
* /** @desc Tells user how to access a product.
* * @hidden *{@literal /}
* var MSG_UNNAMED_10 = goog.getMsg(
* 'Click {$startLink}here{$endLink} to access {$productName}.',
* {startLink: '<a href="' + opt_data.url + '">',
* endLink: '</a>',
* productName: opt_data.productName});
* </pre>
*/
public CodeChunk.WithValue generateMsgGroupVariable(MsgFallbackGroupNode node) {
String tmpVarName = translationContext.nameGenerator().generateName("msg_s");
CodeChunk.WithValue msg;
if (node.numChildren() == 1) {
translationContext.soyToJsVariableMappings().setIsPrimaryMsgInUse(node, CodeChunk.WithValue.LITERAL_TRUE);
msg = generateSingleMsgVariable(node.getChild(0), tmpVarName);
} else {
// has fallbackmsg children
msg = generateMsgGroupVariable(node, tmpVarName);
}
// handle escaping
for (SoyPrintDirective printDirective : node.getEscapingDirectives()) {
msg = SoyJsPluginUtils.applyDirective(translationContext.codeGenerator(), msg, (SoyJsSrcPrintDirective) printDirective, /* args= */
ImmutableList.<CodeChunk.WithValue>of());
}
return msg;
}
Aggregations