Search in sources :

Example 1 with SoyLibraryAssistedJsSrcPrintDirective

use of com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective 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&lt;n&gt;' 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&lt;n&gt;'.
 *
 * @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());
}
Also used : JsExpr(com.google.template.soy.jssrc.restricted.JsExpr) CallBasicNode(com.google.template.soy.soytree.CallBasicNode) RequiresCollector(com.google.template.soy.jssrc.dsl.CodeChunk.RequiresCollector) CallDelegateNode(com.google.template.soy.soytree.CallDelegateNode) ExprRootNode(com.google.template.soy.exprtree.ExprRootNode) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) SoyPrintDirective(com.google.template.soy.shared.restricted.SoyPrintDirective) SoyJsSrcPrintDirective(com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective) SoyLibraryAssistedJsSrcPrintDirective(com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective)

Example 2 with SoyLibraryAssistedJsSrcPrintDirective

use of com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective in project closure-templates by google.

the class SoyJsPluginUtils method applyDirective.

/**
 * Applies the given print directive to {@code expr} and returns the result.
 *
 * @param generator The CodeChunk generator to use.
 * @param expr The expression to apply the print directive to.
 * @param directive The print directive to apply.
 * @param args Print directive args, if any.
 */
public static CodeChunk.WithValue applyDirective(CodeChunk.Generator generator, CodeChunk.WithValue expr, SoyJsSrcPrintDirective directive, List<CodeChunk.WithValue> args) {
    List<JsExpr> argExprs = Lists.transform(args, TO_JS_EXPR);
    JsExpr applied = directive.applyForJsSrc(expr.singleExprOrName(), argExprs);
    RequiresCollector.IntoImmutableSet collector = new RequiresCollector.IntoImmutableSet();
    expr.collectRequires(collector);
    for (CodeChunk.WithValue arg : args) {
        arg.collectRequires(collector);
    }
    if (directive instanceof SoyLibraryAssistedJsSrcPrintDirective) {
        for (String name : ((SoyLibraryAssistedJsSrcPrintDirective) directive).getRequiredJsLibNames()) {
            collector.add(GoogRequire.create(name));
        }
    }
    ImmutableList.Builder<CodeChunk> initialStatements = ImmutableList.<CodeChunk>builder().addAll(expr.initialStatements());
    for (CodeChunk.WithValue arg : args) {
        initialStatements.addAll(arg.initialStatements());
    }
    return fromExpr(applied, collector.get()).withInitialStatements(initialStatements.build());
}
Also used : JsExpr(com.google.template.soy.jssrc.restricted.JsExpr) WithValue(com.google.template.soy.jssrc.dsl.CodeChunk.WithValue) ImmutableList(com.google.common.collect.ImmutableList) RequiresCollector(com.google.template.soy.jssrc.dsl.CodeChunk.RequiresCollector) SoyLibraryAssistedJsSrcPrintDirective(com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective)

Aggregations

RequiresCollector (com.google.template.soy.jssrc.dsl.CodeChunk.RequiresCollector)2 JsExpr (com.google.template.soy.jssrc.restricted.JsExpr)2 SoyLibraryAssistedJsSrcPrintDirective (com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective)2 ImmutableList (com.google.common.collect.ImmutableList)1 ExprRootNode (com.google.template.soy.exprtree.ExprRootNode)1 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)1 WithValue (com.google.template.soy.jssrc.dsl.CodeChunk.WithValue)1 SoyJsSrcPrintDirective (com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective)1 SoyPrintDirective (com.google.template.soy.shared.restricted.SoyPrintDirective)1 CallBasicNode (com.google.template.soy.soytree.CallBasicNode)1 CallDelegateNode (com.google.template.soy.soytree.CallDelegateNode)1