Search in sources :

Example 21 with Expression

use of com.google.template.soy.jbcsrc.restricted.Expression 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 22 with Expression

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

the class LazyClosureCompiler method compileLazyContent.

Expression compileLazyContent(String namePrefix, RenderUnitNode renderUnit, String varName) {
    Optional<Expression> asRawText = asRawTextOnly(renderUnit);
    if (asRawText.isPresent()) {
        return asRawText.get();
    }
    TypeInfo type = innerClasses.registerInnerClassWithGeneratedName(getProposedName(namePrefix, varName), LAZY_CLOSURE_ACCESS);
    SoyClassWriter writer = SoyClassWriter.builder(type).setAccess(LAZY_CLOSURE_ACCESS).extending(DETACHABLE_CONTENT_PROVIDER_TYPE).sourceFileName(renderUnit.getSourceLocation().getFileName()).build();
    Expression expr = new CompilationUnit(writer, type, DETACHABLE_CONTENT_PROVIDER_TYPE, renderUnit).compileRenderable(renderUnit);
    innerClasses.registerAsInnerClass(writer, type);
    writer.visitEnd();
    innerClasses.add(writer.toClassData());
    return expr;
}
Also used : Statement.returnExpression(com.google.template.soy.jbcsrc.restricted.Statement.returnExpression) SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Expression(com.google.template.soy.jbcsrc.restricted.Expression) SoyClassWriter(com.google.template.soy.jbcsrc.internal.SoyClassWriter) TypeInfo(com.google.template.soy.jbcsrc.restricted.TypeInfo)

Example 23 with Expression

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

the class LazyClosureCompiler method asRawTextOnly.

private Optional<Expression> asRawTextOnly(RenderUnitNode renderUnit) {
    StringBuilder builder = null;
    for (StandaloneNode child : renderUnit.getChildren()) {
        if (child instanceof RawTextNode) {
            if (builder == null) {
                builder = new StringBuilder();
            }
            builder.append(((RawTextNode) child).getRawText());
        } else {
            return Optional.absent();
        }
    }
    // TODO(lukes): ideally this would be a static final StringData field rather than reboxing each
    // time, but we don't (yet) have a good mechanism for that.
    SanitizedContentKind kind = renderUnit.getContentKind();
    Expression constant = constant(builder == null ? "" : builder.toString(), parentVariables);
    if (kind == null) {
        return Optional.<Expression>of(MethodRef.STRING_DATA_FOR_VALUE.invoke(constant));
    } else {
        return Optional.<Expression>of(MethodRef.ORDAIN_AS_SAFE.invoke(constant, constantSanitizedContentKindAsContentKind(kind)));
    }
}
Also used : StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) Statement.returnExpression(com.google.template.soy.jbcsrc.restricted.Statement.returnExpression) SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Expression(com.google.template.soy.jbcsrc.restricted.Expression) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind) RawTextNode(com.google.template.soy.soytree.RawTextNode)

Example 24 with Expression

use of com.google.template.soy.jbcsrc.restricted.Expression 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 25 with Expression

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

the class SoyNodeCompiler method calculateRangeArgs.

/**
 * Interprets the given expressions as the arguments of a {@code range(...)} expression in a
 * {@code foreach} loop.
 */
private CompiledForeachRangeArgs calculateRangeArgs(ForNode forNode, Scope scope) {
    RangeArgs rangeArgs = RangeArgs.createFromNode(forNode).get();
    ForNonemptyNode nonEmptyNode = (ForNonemptyNode) forNode.getChild(0);
    ImmutableList.Builder<Statement> initStatements = ImmutableList.builder();
    Expression startExpression = computeRangeValue(SyntheticVarName.foreachLoopRangeStart(nonEmptyNode), rangeArgs.start(), 0, scope, initStatements);
    Expression stepExpression = computeRangeValue(SyntheticVarName.foreachLoopRangeStep(nonEmptyNode), rangeArgs.increment(), 1, scope, initStatements);
    Expression endExpression = computeRangeValue(SyntheticVarName.foreachLoopRangeEnd(nonEmptyNode), Optional.of(rangeArgs.limit()), Integer.MAX_VALUE, scope, initStatements);
    return new AutoValue_SoyNodeCompiler_CompiledForeachRangeArgs(startExpression, endExpression, stepExpression, initStatements.build());
}
Also used : SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Expression(com.google.template.soy.jbcsrc.restricted.Expression) RangeArgs(com.google.template.soy.shared.RangeArgs) ImmutableList(com.google.common.collect.ImmutableList) Statement(com.google.template.soy.jbcsrc.restricted.Statement) ForNonemptyNode(com.google.template.soy.soytree.ForNonemptyNode)

Aggregations

Expression (com.google.template.soy.jbcsrc.restricted.Expression)32 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)26 Statement (com.google.template.soy.jbcsrc.restricted.Statement)15 Label (org.objectweb.asm.Label)15 CodeBuilder (com.google.template.soy.jbcsrc.restricted.CodeBuilder)8 ArrayList (java.util.ArrayList)8 Statement.returnExpression (com.google.template.soy.jbcsrc.restricted.Statement.returnExpression)5 Scope (com.google.template.soy.jbcsrc.TemplateVariableManager.Scope)4 Variable (com.google.template.soy.jbcsrc.TemplateVariableManager.Variable)4 LocalVariable (com.google.template.soy.jbcsrc.restricted.LocalVariable)4 AppendableAndOptions (com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective.Streamable.AppendableAndOptions)4 ImmutableList (com.google.common.collect.ImmutableList)2 ExprRootNode (com.google.template.soy.exprtree.ExprRootNode)2 SoyClassWriter (com.google.template.soy.jbcsrc.internal.SoyClassWriter)2 FieldRef (com.google.template.soy.jbcsrc.restricted.FieldRef)2 TypeInfo (com.google.template.soy.jbcsrc.restricted.TypeInfo)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 LinkedHashMap (java.util.LinkedHashMap)2