Search in sources :

Example 16 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class MsgCompiler method handleTranslationWithPlaceholders.

/**
 * Handles a complex message with placeholders.
 */
private Statement handleTranslationWithPlaceholders(MsgNode msg, ImmutableList<SoyPrintDirective> escapingDirectives, Expression soyMsgParts, Expression locale, ImmutableList<SoyMsgPart> parts) {
    // We need to render placeholders into a buffer and then pack them into a map to pass to
    // Runtime.renderSoyMsgWithPlaceholders.
    Expression placeholderMap = variables.getMsgPlaceholderMapField().accessor(thisVar);
    Map<String, Statement> placeholderNameToPutStatement = new LinkedHashMap<>();
    putPlaceholdersIntoMap(placeholderMap, msg, parts, placeholderNameToPutStatement);
    // sanity check
    checkState(!placeholderNameToPutStatement.isEmpty());
    variables.setMsgPlaceholderMapMinSize(placeholderNameToPutStatement.size());
    Statement populateMap = Statement.concat(placeholderNameToPutStatement.values());
    Statement clearMap = placeholderMap.invokeVoid(MethodRef.LINKED_HASH_MAP_CLEAR);
    Statement render;
    if (areAllPrintDirectivesStreamable(escapingDirectives)) {
        // No need to save/restore since rendering a message doesn't detach.  All detaching for data
        // should have already happened as part of constructing the placholder map.
        AppendableAndOptions wrappedAppendable = applyStreamingEscapingDirectives(escapingDirectives, appendableExpression, parameterLookup.getRenderContext(), variables);
        Statement initAppendable = Statement.NULL_STATEMENT;
        Statement clearAppendable = Statement.NULL_STATEMENT;
        Expression appendableExpression = wrappedAppendable.appendable();
        if (wrappedAppendable.closeable()) {
            Scope scope = variables.enterScope();
            Variable appendableVar = scope.createTemporary("msg_appendable", wrappedAppendable.appendable());
            initAppendable = appendableVar.initializer();
            appendableExpression = appendableVar.local();
            clearAppendable = Statement.concat(appendableVar.local().checkedCast(BytecodeUtils.CLOSEABLE_TYPE).invokeVoid(MethodRef.CLOSEABLE_CLOSE), scope.exitScope());
        }
        render = Statement.concat(initAppendable, MethodRef.RUNTIME_RENDER_SOY_MSG_PARTS_WITH_PLACEHOLDERS.invokeVoid(soyMsgParts, locale, placeholderMap, appendableExpression), clearAppendable);
    } else {
        // render into the handy buffer we already have!
        Statement renderToBuffer = MethodRef.RUNTIME_RENDER_SOY_MSG_PARTS_WITH_PLACEHOLDERS.invokeVoid(soyMsgParts, locale, placeholderMap, tempBuffer());
        // N.B. the type here is always 'string'
        SoyExpression value = SoyExpression.forString(tempBuffer().invoke(MethodRef.ADVISING_STRING_BUILDER_GET_AND_CLEAR));
        for (SoyPrintDirective directive : escapingDirectives) {
            value = parameterLookup.getRenderContext().applyPrintDirective(directive, value);
        }
        render = Statement.concat(renderToBuffer, appendableExpression.appendString(value.coerceToString()).toStatement());
    }
    return Statement.concat(populateMap, render, clearMap);
}
Also used : SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Variable(com.google.template.soy.jbcsrc.TemplateVariableManager.Variable) Scope(com.google.template.soy.jbcsrc.TemplateVariableManager.Scope) SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Expression(com.google.template.soy.jbcsrc.restricted.Expression) SoyPrintDirective(com.google.template.soy.shared.restricted.SoyPrintDirective) Statement(com.google.template.soy.jbcsrc.restricted.Statement) AppendableAndOptions(com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective.Streamable.AppendableAndOptions) LinkedHashMap(java.util.LinkedHashMap)

Example 17 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class MsgCompiler method addHtmlTagNodeToPlaceholderMap.

/**
 * Returns a statement that adds the content of the node to the map.
 *
 * @param mapExpression The map to put the new entry in
 * @param mapKey The map key
 * @param htmlTagNode The node
 */
private Statement addHtmlTagNodeToPlaceholderMap(Expression mapExpression, String mapKey, MsgHtmlTagNode htmlTagNode) {
    Optional<String> rawText = tryGetRawTextContent(htmlTagNode);
    Statement putStatement;
    if (rawText.isPresent()) {
        putStatement = mapExpression.invoke(MethodRef.LINKED_HASH_MAP_PUT, constant(mapKey), constant(rawText.get())).toStatement();
    } else {
        Statement renderIntoBuffer = soyNodeCompiler.compileToBuffer(htmlTagNode, tempBuffer());
        Statement putBuffer = putBufferIntoMapForPlaceholder(mapExpression, mapKey);
        putStatement = Statement.concat(renderIntoBuffer, putBuffer);
    }
    return putStatement.withSourceLocation(htmlTagNode.getSourceLocation());
}
Also used : Statement(com.google.template.soy.jbcsrc.restricted.Statement)

Example 18 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class MsgCompiler method putPlaceholderIntoMap.

private void putPlaceholderIntoMap(Expression mapExpression, MsgNode originalMsg, Map<String, Statement> placeholderNameToPutStatement, SoyMsgPlaceholderPart placeholder) throws AssertionError {
    String placeholderName = placeholder.getPlaceholderName();
    if (!placeholderNameToPutStatement.containsKey(placeholderName)) {
        MsgPlaceholderNode repPlaceholderNode = originalMsg.getRepPlaceholderNode(placeholder.getPlaceholderName());
        if (repPlaceholderNode.numChildren() == 0) {
            throw new IllegalStateException("empty rep node for: " + placeholderName);
        }
        StandaloneNode initialNode = repPlaceholderNode.getChild(0);
        Statement putEntyInMap;
        if (initialNode instanceof MsgHtmlTagNode) {
            putEntyInMap = addHtmlTagNodeToPlaceholderMap(mapExpression, placeholderName, (MsgHtmlTagNode) initialNode);
        } else if (initialNode instanceof CallNode) {
            putEntyInMap = addCallNodeToPlaceholderMap(mapExpression, placeholderName, (CallNode) initialNode);
        } else if (initialNode instanceof PrintNode) {
            putEntyInMap = addPrintNodeToPlaceholderMap(mapExpression, placeholderName, (PrintNode) initialNode);
        } else if (initialNode instanceof RawTextNode) {
            putEntyInMap = addRawTextNodeToPlaceholderMap(mapExpression, placeholderName, (RawTextNode) initialNode);
        } else {
            // the AST for MsgNodes guarantee that these are the only options
            throw new AssertionError("Unexpected child: " + initialNode.getClass());
        }
        placeholderNameToPutStatement.put(placeholder.getPlaceholderName(), putEntyInMap.withSourceLocation(repPlaceholderNode.getSourceLocation()));
    }
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) Statement(com.google.template.soy.jbcsrc.restricted.Statement) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) PrintNode(com.google.template.soy.soytree.PrintNode) CallNode(com.google.template.soy.soytree.CallNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgPlaceholderNode(com.google.template.soy.soytree.MsgPlaceholderNode)

Example 19 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class PrintDirectives method applyStreamingPrintDirectivesTo.

private static AppendableAndOptions applyStreamingPrintDirectivesTo(List<DirectiveWithArgs> directivesToApply, Expression appendable, JbcSrcPluginContext context, TemplateVariableManager variableManager) {
    final List<LocalVariable> closeables = new ArrayList<>();
    final List<Variable> appendableVars = new ArrayList<>();
    Scope scope = variableManager.enterScope();
    AppendableAndOptions prev = AppendableAndOptions.create(appendable);
    Variable prevVar = scope.createTemporary("tmp_appendable", appendable);
    appendableVars.add(prevVar);
    // appendable with the last directive first. so iterate in reverse order.
    for (DirectiveWithArgs directiveToApply : Lists.reverse(directivesToApply)) {
        AppendableAndOptions curr = directiveToApply.apply(context, prevVar.local());
        Variable currVar = scope.createTemporary("tmp_appendable", curr.appendable());
        appendableVars.add(currVar);
        if (curr.closeable()) {
            closeables.add(currVar.local());
        }
        prev = curr;
        prevVar = currVar;
    }
    // Check if we need to apply a wrapper to make sure close propagates to all the right places
    // this is necessary if there are multiple closeable wrappers.
    final Expression appendableExpression;
    final boolean closeable;
    if (closeables.isEmpty()) {
        appendableExpression = prev.appendable();
        closeable = false;
    } else if (closeables.size() == 1 && prev.closeable()) {
        // there is exactly one closeable and it is first, we don't need a wrapper
        appendableExpression = prev.appendable();
        closeable = true;
    } else {
        // there is either more than one closeable, or it is not the first one, so we need a wrapper
        // We need to reverse the list of closeables so that we close them in the correct order. for
        // example, given '|foo|bar' we will first wrap the delegate with bar and then with foo but we
        // need to close foo first.
        appendableExpression = RUNTIME_PROPAGATE_CLOSE.invoke(Iterables.getLast(appendableVars).local(), BytecodeUtils.asImmutableList(Lists.reverse(closeables)));
        closeable = true;
    }
    final Statement exitScope = scope.exitScope();
    Expression result = new Expression(appendableExpression.resultType()) {

        @Override
        protected void doGen(CodeBuilder adapter) {
            for (Variable var : appendableVars) {
                var.initializer().gen(adapter);
            }
            appendableExpression.gen(adapter);
            exitScope.gen(adapter);
        }
    };
    if (closeable) {
        return AppendableAndOptions.createCloseable(result);
    } else {
        return AppendableAndOptions.create(result);
    }
}
Also used : Variable(com.google.template.soy.jbcsrc.TemplateVariableManager.Variable) LocalVariable(com.google.template.soy.jbcsrc.restricted.LocalVariable) Scope(com.google.template.soy.jbcsrc.TemplateVariableManager.Scope) SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Expression(com.google.template.soy.jbcsrc.restricted.Expression) Statement(com.google.template.soy.jbcsrc.restricted.Statement) AppendableAndOptions(com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective.Streamable.AppendableAndOptions) LocalVariable(com.google.template.soy.jbcsrc.restricted.LocalVariable) ArrayList(java.util.ArrayList) CodeBuilder(com.google.template.soy.jbcsrc.restricted.CodeBuilder)

Example 20 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class SoyNodeCompiler method visitIfNode.

@Override
protected Statement visitIfNode(IfNode node) {
    List<IfBlock> ifs = new ArrayList<>();
    Optional<Statement> elseBlock = Optional.absent();
    for (SoyNode child : node.getChildren()) {
        if (child instanceof IfCondNode) {
            IfCondNode icn = (IfCondNode) child;
            SoyExpression cond = exprCompiler.compile(icn.getExpr()).coerceToBoolean();
            Statement block = visitChildrenInNewScope(icn);
            ifs.add(IfBlock.create(cond, block));
        } else {
            IfElseNode ien = (IfElseNode) child;
            elseBlock = Optional.of(visitChildrenInNewScope(ien));
        }
    }
    return ControlFlow.ifElseChain(ifs, elseBlock);
}
Also used : IfElseNode(com.google.template.soy.soytree.IfElseNode) SoyNode(com.google.template.soy.soytree.SoyNode) IfCondNode(com.google.template.soy.soytree.IfCondNode) SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Statement(com.google.template.soy.jbcsrc.restricted.Statement) ArrayList(java.util.ArrayList) IfBlock(com.google.template.soy.jbcsrc.ControlFlow.IfBlock)

Aggregations

Statement (com.google.template.soy.jbcsrc.restricted.Statement)30 Expression (com.google.template.soy.jbcsrc.restricted.Expression)15 Label (org.objectweb.asm.Label)14 CodeBuilder (com.google.template.soy.jbcsrc.restricted.CodeBuilder)13 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)11 ArrayList (java.util.ArrayList)8 LocalVariable (com.google.template.soy.jbcsrc.restricted.LocalVariable)7 Scope (com.google.template.soy.jbcsrc.TemplateVariableManager.Scope)5 Variable (com.google.template.soy.jbcsrc.TemplateVariableManager.Variable)4 AppendableAndOptions (com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective.Streamable.AppendableAndOptions)4 IfBlock (com.google.template.soy.jbcsrc.ControlFlow.IfBlock)3 SaveRestoreState (com.google.template.soy.jbcsrc.TemplateVariableManager.SaveRestoreState)3 FieldRef (com.google.template.soy.jbcsrc.restricted.FieldRef)3 LinkedHashMap (java.util.LinkedHashMap)3 ExprRootNode (com.google.template.soy.exprtree.ExprRootNode)2 ClassData (com.google.template.soy.jbcsrc.internal.ClassData)2 Statement.returnExpression (com.google.template.soy.jbcsrc.restricted.Statement.returnExpression)2 RangeArgs (com.google.template.soy.shared.RangeArgs)2 SoyPrintDirective (com.google.template.soy.shared.restricted.SoyPrintDirective)2 ForNonemptyNode (com.google.template.soy.soytree.ForNonemptyNode)2