Search in sources :

Example 1 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class VeLogInstrumentationVisitor method visitVeLogNode.

/**
 * Adds data-soylog attribute to the top-level DOM node in this {velog} block.
 */
@Override
protected void visitVeLogNode(VeLogNode node) {
    // VeLogValidationPass enforces that the first child is a open tag. We can safely cast it here.
    HtmlOpenTagNode tag = (HtmlOpenTagNode) node.getChild(0);
    SourceLocation insertionLocation = tag.getSourceLocation().getEndPoint().offset(0, tag.isSelfClosing() ? -2 : -1).asLocation(tag.getSourceLocation().getFilePath());
    FunctionNode funcNode = new FunctionNode(VeLogFunction.INSTANCE, insertionLocation);
    funcNode.addChild(new IntegerNode(node.getLoggingId(), insertionLocation));
    funcNode.addChild(node.getConfigExpression() == null ? new NullNode(insertionLocation) : node.getConfigExpression().copy(new CopyState()));
    if (node.getLogonlyExpression() != null) {
        funcNode.addChild(node.getLogonlyExpression().copy(new CopyState()));
    }
    PrintNode attributeNode = new PrintNode(nodeIdGen.genId(), insertionLocation, /* isImplicit= */
    true, /* expr= */
    funcNode, /* attributes= */
    ImmutableList.of(), ErrorReporter.exploding());
    tag.addChild(attributeNode);
    visitChildren(node);
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) IntegerNode(com.google.template.soy.exprtree.IntegerNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode) CopyState(com.google.template.soy.basetree.CopyState) PrintNode(com.google.template.soy.soytree.PrintNode) NullNode(com.google.template.soy.exprtree.NullNode) HtmlOpenTagNode(com.google.template.soy.soytree.HtmlOpenTagNode)

Example 2 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class SoyNodeCompiler method visitPrintNode.

@Override
protected Statement visitPrintNode(PrintNode node) {
    if (node.getExpr().getRoot() instanceof FunctionNode) {
        FunctionNode fn = (FunctionNode) node.getExpr().getRoot();
        if (fn.getSoyFunction() instanceof LoggingFunction) {
            return visitLoggingFunction(node, fn, (LoggingFunction) fn.getSoyFunction());
        }
    }
    // evaluates to a SoyValueProvider.  This will allow us to render incrementally.
    if (areAllPrintDirectivesStreamable(node)) {
        Label reattachPoint = new Label();
        ExprRootNode expr = node.getExpr();
        Optional<Expression> asSoyValueProvider = expressionToSoyValueProviderCompiler.compileAvoidingBoxing(expr, reattachPoint);
        if (asSoyValueProvider.isPresent()) {
            return renderIncrementally(asSoyValueProvider.get(), node.getChildren(), reattachPoint);
        }
    }
    // otherwise we need to apply some non-streaming print directives, or the expression would
    // require boxing to be a print directive (which usually means it is quite trivial).
    Label reattachPoint = new Label();
    SoyExpression value = compilePrintNodeAsExpression(node, reattachPoint);
    // TODO(lukes): call value.render?
    AppendableExpression renderSoyValue = appendableExpression.appendString(value.coerceToString()).labelStart(reattachPoint);
    Statement stmt;
    if (shouldCheckBuffer(node)) {
        stmt = detachState.detachLimited(renderSoyValue);
    } else {
        stmt = renderSoyValue.toStatement();
    }
    return stmt;
}
Also used : SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) SoyExpression(com.google.template.soy.jbcsrc.restricted.SoyExpression) Expression(com.google.template.soy.jbcsrc.restricted.Expression) Statement(com.google.template.soy.jbcsrc.restricted.Statement) FunctionNode(com.google.template.soy.exprtree.FunctionNode) Label(org.objectweb.asm.Label) LoggingFunction(com.google.template.soy.logging.LoggingFunction) ExprRootNode(com.google.template.soy.exprtree.ExprRootNode)

Example 3 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class SoyNodeCompiler method shouldCheckBuffer.

/**
 * Returns true if the print expression should check the rendering buffer and generate a detach.
 *
 * <p>We do not generate detaches for css() and xid() builtin functions, since they are typically
 * very short.
 */
private static boolean shouldCheckBuffer(PrintNode node) {
    if (!(node.getExpr().getRoot() instanceof FunctionNode)) {
        return true;
    }
    FunctionNode fn = (FunctionNode) node.getExpr().getRoot();
    if (!(fn.getSoyFunction() instanceof BuiltinFunction)) {
        return true;
    }
    BuiltinFunction bfn = (BuiltinFunction) fn.getSoyFunction();
    if (bfn != BuiltinFunction.XID && bfn != BuiltinFunction.CSS) {
        return true;
    }
    return false;
}
Also used : BuiltinFunction(com.google.template.soy.shared.internal.BuiltinFunction) FunctionNode(com.google.template.soy.exprtree.FunctionNode)

Example 4 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class MsgIdFunctionPass method handleMsgIdCall.

/**
 * Rewrites calls to msgId($msgVar) to either a static constant message id or a conditional if
 * there is a fallback.
 */
private void handleMsgIdCall(FunctionNode fn, MsgFallbackGroupNode msgNode) {
    ExprNode replacement;
    long primaryMsgId = MsgUtils.computeMsgIdForDualFormat(msgNode.getChild(0));
    if (msgNode.numChildren() == 1) {
        // easy peasy
        replacement = createMsgIdNode(primaryMsgId, fn.getSourceLocation());
    } else {
        long fallbackMsgId = MsgUtils.computeMsgIdForDualFormat(msgNode.getChild(1));
        ConditionalOpNode condOpNode = new ConditionalOpNode(fn.getSourceLocation());
        FunctionNode isPrimaryMsgInUse = new FunctionNode(BuiltinFunction.IS_PRIMARY_MSG_IN_USE, fn.getSourceLocation());
        // We add the varRef, and the 2 message ids to the funcitonnode as arguments so they are
        // trivial to access in the backends.  This is a little hacky however since we never generate
        // code for these things.
        // We could formalize the hack by providing a way to stash arbitrary data in the FunctionNode
        // and then just pack this up in a non-AST datastructure.
        isPrimaryMsgInUse.addChild(fn.getChild(0));
        isPrimaryMsgInUse.addChild(new IntegerNode(primaryMsgId, fn.getSourceLocation()));
        isPrimaryMsgInUse.addChild(new IntegerNode(fallbackMsgId, fn.getSourceLocation()));
        condOpNode.addChild(isPrimaryMsgInUse);
        condOpNode.addChild(createMsgIdNode(primaryMsgId, fn.getSourceLocation()));
        condOpNode.addChild(createMsgIdNode(fallbackMsgId, fn.getSourceLocation()));
        replacement = condOpNode;
    }
    fn.getParent().replaceChild(fn, replacement);
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) ConditionalOpNode(com.google.template.soy.exprtree.OperatorNodes.ConditionalOpNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode)

Example 5 with FunctionNode

use of com.google.template.soy.exprtree.FunctionNode in project closure-templates by google.

the class XidPass method run.

@Override
public void run(SoyFileNode file, IdGenerator nodeIdGen) {
    for (FunctionNode fn : SoyTreeUtils.getAllNodesOfType(file, FunctionNode.class)) {
        if (fn.getSoyFunction() == BuiltinFunction.XID) {
            if (fn.numChildren() != 1) {
                // if it isn't == 1, then an error has already been reported, move along.
                continue;
            }
            ExprNode child = fn.getChild(0);
            switch(child.getKind()) {
                case GLOBAL_NODE:
                    GlobalNode global = (GlobalNode) child;
                    if (global.isResolved()) {
                        // This doesn't have to be an error. but it is confusing if it is is since it is
                        // unclear if the user intended to xid the identifier or the value.
                        reporter.report(global.getSourceLocation(), GLOBAL_XID_ARG_IS_RESOLVED, global.getType().toString(), global.getValue().toSourceString());
                    }
                    fn.replaceChild(0, new StringNode(global.getName(), QuoteStyle.SINGLE, global.getSourceLocation()));
                    break;
                case STRING_NODE:
                    break;
                default:
                    reporter.report(child.getSourceLocation(), STRING_OR_GLOBAL_REQUIRED);
            }
        }
    }
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode) StringNode(com.google.template.soy.exprtree.StringNode) GlobalNode(com.google.template.soy.exprtree.GlobalNode)

Aggregations

FunctionNode (com.google.template.soy.exprtree.FunctionNode)20 PrintNode (com.google.template.soy.soytree.PrintNode)8 StringNode (com.google.template.soy.exprtree.StringNode)7 Test (org.junit.Test)7 TemplateNode (com.google.template.soy.soytree.TemplateNode)6 ExprNode (com.google.template.soy.exprtree.ExprNode)5 IntegerNode (com.google.template.soy.exprtree.IntegerNode)4 RawTextNode (com.google.template.soy.soytree.RawTextNode)3 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)3 SourceLocation (com.google.template.soy.base.SourceLocation)2 VarRefNode (com.google.template.soy.exprtree.VarRefNode)2 LoggingFunction (com.google.template.soy.logging.LoggingFunction)2 CallParamContentNode (com.google.template.soy.soytree.CallParamContentNode)2 CallParamValueNode (com.google.template.soy.soytree.CallParamValueNode)2 SoyType (com.google.template.soy.types.SoyType)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 IncrementingIdGenerator (com.google.template.soy.base.internal.IncrementingIdGenerator)1 CopyState (com.google.template.soy.basetree.CopyState)1 SyntaxVersionUpperBound (com.google.template.soy.basetree.SyntaxVersionUpperBound)1 ParentExprNode (com.google.template.soy.exprtree.ExprNode.ParentExprNode)1