Search in sources :

Example 1 with IntegerNode

use of com.google.template.soy.exprtree.IntegerNode 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 IntegerNode

use of com.google.template.soy.exprtree.IntegerNode 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 3 with IntegerNode

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

the class RewriteGlobalsPass method resolveGlobal.

private void resolveGlobal(GlobalNode global) {
    // First check to see if this global matches a proto enum.  We do this because the enums from
    // the type registry have better type information and for applications with legacy globals
    // configs there is often overlap, so the order in which we check is actually important.
    // proto enums are dotted identifiers
    String name = global.getName();
    int lastDot = name.lastIndexOf('.');
    if (lastDot > 0) {
        String enumTypeName = name.substring(0, lastDot);
        SoyType type = typeRegistry.getType(enumTypeName);
        if (type != null && type.getKind() == SoyType.Kind.PROTO_ENUM) {
            SoyProtoEnumType enumType = (SoyProtoEnumType) type;
            String enumMemberName = name.substring(lastDot + 1);
            Integer enumValue = enumType.getValue(enumMemberName);
            if (enumValue != null) {
                // TODO(lukes): consider introducing a new PrimitiveNode for enums
                global.resolve(enumType, new IntegerNode(enumValue, global.getSourceLocation()));
            } else {
                // If we found the type definition but not the value, then that's an error
                // regardless of whether we're allowing unbound globals or not.
                errorReporter.report(global.getSourceLocation(), ENUM_MEMBERSHIP_ERROR, enumMemberName, enumTypeName);
            }
            // TODO(lukes): issue a warning if a registered global also matches
            return;
        }
    }
    // if that doesn't work, see if it was registered in the globals file.
    PrimitiveData value = compileTimeGlobals.get(global.getName());
    if (value != null) {
        PrimitiveNode expr = InternalValueUtils.convertPrimitiveDataToExpr(value, global.getSourceLocation());
        global.resolve(expr.getType(), expr);
    }
}
Also used : PrimitiveNode(com.google.template.soy.exprtree.ExprNode.PrimitiveNode) PrimitiveData(com.google.template.soy.data.restricted.PrimitiveData) IntegerNode(com.google.template.soy.exprtree.IntegerNode) SoyType(com.google.template.soy.types.SoyType) SoyProtoEnumType(com.google.template.soy.types.SoyProtoEnumType)

Example 4 with IntegerNode

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

the class TemplateDelegateNode method resolveVariantExpression.

/**
 * Calculate a DeltemplateKey for the variant.
 *
 * <p>This is done lazily so that global references can be resolved. This is not ideal since
 * nothing guarantees that resolution happens before access.
 *
 * <p>Note we don't do validation of the variant values since that is handled by the
 * TemplateDelegateNodeBuilder during construction
 */
private DelTemplateKey resolveVariantExpression() {
    if (delTemplateVariantExpr == null) {
        delTemplateKey = DelTemplateKey.create(delTemplateName, "");
        return delTemplateKey;
    }
    ExprNode exprNode = delTemplateVariantExpr.getRoot();
    if (exprNode instanceof GlobalNode) {
        GlobalNode globalNode = (GlobalNode) exprNode;
        if (globalNode.isResolved()) {
            exprNode = globalNode.getValue();
        } else {
            // For this reason we also don't store the key, instead we just return it.
            return DelTemplateKey.create(delTemplateName, globalNode.getName());
        }
    }
    if (exprNode instanceof IntegerNode) {
        // Globals were already substituted: We may now create the definitive variant and key fields
        // on this node.
        long variantValue = ((IntegerNode) exprNode).getValue();
        delTemplateKey = DelTemplateKey.create(delTemplateName, String.valueOf(variantValue));
    } else if (exprNode instanceof StringNode) {
        // Globals were already substituted: We may now create the definitive variant and key fields
        // on this node.
        delTemplateKey = DelTemplateKey.create(delTemplateName, ((StringNode) exprNode).getValue());
    } else {
        // We must have already reported an error, just create an arbitrary variant expr.
        delTemplateKey = DelTemplateKey.create(delTemplateName, exprNode.toSourceString());
    }
    return delTemplateKey;
}
Also used : ExprNode(com.google.template.soy.exprtree.ExprNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) StringNode(com.google.template.soy.exprtree.StringNode) GlobalNode(com.google.template.soy.exprtree.GlobalNode)

Example 5 with IntegerNode

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

the class MsgSubstUnitBaseVarNameUtils method genCandidateBaseNamesForExpr.

/**
 * Private helper for {@code genShortestBaseNameForExpr()} and {@code
 * genNoncollidingBaseNamesForExprs()}.
 *
 * <p>Given an expression that's a data ref or a global, generates the list of all possible base
 * names, from short to long. Shortest contains only the last key. Longest contains up to the
 * first key (unless there are accesses using expressions to compute non-static keys, in which
 * case we cannot generate any more base names). If no base names can be generated for the given
 * expression (i.e. if the expression is not a data ref or global, or the last key is non-static),
 * then returns empty list.
 *
 * <p>For example, given $aaa[0].bbb.cccDdd, generates the list ["CCC_DDD", "BBB_CCC_DDD",
 * "AAA_0_BBB_CCC_DDD"]. One the other hand, given $aaa['xxx'], generates the empty list (because
 * ['xxx'] parses to a DataRefAccessExprNode).
 *
 * @param exprNode The expr root of the expression to generate all candidate base names for.
 * @return The list of all candidate base names, from shortest to longest.
 */
@VisibleForTesting
static List<String> genCandidateBaseNamesForExpr(ExprNode exprNode) {
    if (exprNode instanceof VarRefNode || exprNode instanceof DataAccessNode) {
        List<String> baseNames = Lists.newArrayList();
        String baseName = null;
        while (exprNode != null) {
            String nameSegment = null;
            if (exprNode instanceof VarRefNode) {
                nameSegment = ((VarRefNode) exprNode).getName();
                exprNode = null;
            } else if (exprNode instanceof FieldAccessNode) {
                FieldAccessNode fieldAccess = (FieldAccessNode) exprNode;
                nameSegment = fieldAccess.getFieldName();
                exprNode = fieldAccess.getBaseExprChild();
            } else if (exprNode instanceof ItemAccessNode) {
                ItemAccessNode itemAccess = (ItemAccessNode) exprNode;
                exprNode = itemAccess.getBaseExprChild();
                if (itemAccess.getKeyExprChild() instanceof IntegerNode) {
                    // Prefix with index, but don't add to baseNames list since it's not a valid ident.
                    IntegerNode keyValue = (IntegerNode) itemAccess.getKeyExprChild();
                    if (keyValue.getValue() < 0) {
                        // Stop if we encounter an invalid key.
                        break;
                    }
                    nameSegment = Long.toString(keyValue.getValue());
                    baseName = BaseUtils.convertToUpperUnderscore(nameSegment) + ((baseName != null) ? "_" + baseName : "");
                    continue;
                } else {
                    // Stop if we encounter a non-static key
                    break;
                }
            } else {
                // Stop if we encounter an expression that is not representable as a name.
                break;
            }
            baseName = BaseUtils.convertToUpperUnderscore(nameSegment) + ((baseName != null) ? "_" + baseName : "");
            // new candidate base name whenever we encounter a key
            baseNames.add(baseName);
        }
        return baseNames;
    } else if (exprNode instanceof GlobalNode) {
        String[] globalNameParts = ((GlobalNode) exprNode).getName().split("\\.");
        List<String> baseNames = Lists.newArrayList();
        String baseName = null;
        for (int i = globalNameParts.length - 1; i >= 0; i--) {
            baseName = BaseUtils.convertToUpperUnderscore(globalNameParts[i]) + ((baseName != null) ? "_" + baseName : "");
            baseNames.add(baseName);
        }
        return baseNames;
    } else {
        // We don't handle expressions other than data refs and globals.
        return ImmutableList.of();
    }
}
Also used : DataAccessNode(com.google.template.soy.exprtree.DataAccessNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) ItemAccessNode(com.google.template.soy.exprtree.ItemAccessNode) GlobalNode(com.google.template.soy.exprtree.GlobalNode) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) FieldAccessNode(com.google.template.soy.exprtree.FieldAccessNode) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

IntegerNode (com.google.template.soy.exprtree.IntegerNode)15 Test (org.junit.Test)8 ExprNode (com.google.template.soy.exprtree.ExprNode)7 StringNode (com.google.template.soy.exprtree.StringNode)6 BooleanNode (com.google.template.soy.exprtree.BooleanNode)4 FloatNode (com.google.template.soy.exprtree.FloatNode)4 FunctionNode (com.google.template.soy.exprtree.FunctionNode)4 GlobalNode (com.google.template.soy.exprtree.GlobalNode)4 VarRefNode (com.google.template.soy.exprtree.VarRefNode)4 SourceLocation (com.google.template.soy.base.SourceLocation)3 FieldAccessNode (com.google.template.soy.exprtree.FieldAccessNode)3 ItemAccessNode (com.google.template.soy.exprtree.ItemAccessNode)2 NullNode (com.google.template.soy.exprtree.NullNode)2 ConditionalOpNode (com.google.template.soy.exprtree.OperatorNodes.ConditionalOpNode)2 PrintNode (com.google.template.soy.soytree.PrintNode)2 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableList (com.google.common.collect.ImmutableList)1 CopyState (com.google.template.soy.basetree.CopyState)1 NullData (com.google.template.soy.data.restricted.NullData)1