Search in sources :

Example 1 with VarRefNode

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

the class ExpressionCompilerTest method createTemplateBody.

private String createTemplateBody(String soyExpr) {
    // collect all varrefs and apply them as template parameters.  This way all varrefs have a valid
    // vardef
    // TODO(lukes): this logic would be useful in a lot of tests and potentially unblock efforts to
    // eliminate UNDECLARED vars
    ExprNode expr = SoyFileParser.parseExpression(soyExpr, PluginResolver.nullResolver(Mode.ALLOW_UNDEFINED, ErrorReporter.exploding()), ErrorReporter.exploding());
    final StringBuilder templateBody = new StringBuilder();
    new AbstractExprNodeVisitor<Void>() {

        final Set<String> names = new HashSet<>();

        @Override
        protected void visitVarRefNode(VarRefNode node) {
            if (names.add(node.getName())) {
                SoyType type = variables.get(node.getName()).soyType();
                templateBody.append("{@param ").append(node.getName()).append(": ").append(type).append("}\n");
            }
        }

        @Override
        protected void visitExprNode(ExprNode node) {
            if (node instanceof ParentExprNode) {
                visitChildren((ParentExprNode) node);
            }
        }
    }.exec(expr);
    templateBody.append("{" + soyExpr + "}\n");
    return templateBody.toString();
}
Also used : ParentExprNode(com.google.template.soy.exprtree.ExprNode.ParentExprNode) ExprNode(com.google.template.soy.exprtree.ExprNode) ParentExprNode(com.google.template.soy.exprtree.ExprNode.ParentExprNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) SoyType(com.google.template.soy.types.SoyType) HashSet(java.util.HashSet)

Example 2 with VarRefNode

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

the class CheckTemplateParamsVisitor method visitTemplateNode.

// -----------------------------------------------------------------------------------------------
// Implementations for specific nodes.
@Override
protected void visitTemplateNode(TemplateNode node) {
    if (!node.couldHaveSyntaxVersionAtLeast(SyntaxVersion.V2_0)) {
        return;
    }
    ListMultimap<String, SourceLocation> dataKeys = ArrayListMultimap.create();
    for (VarRefNode varRefNode : SoyTreeUtils.getAllNodesOfType(node, VarRefNode.class)) {
        if (varRefNode.isPossibleParam()) {
            dataKeys.put(varRefNode.getName(), varRefNode.getSourceLocation());
        }
    }
    IndirectParamsInfo ipi = new FindIndirectParamsVisitor(templateRegistry).exec(node);
    Set<String> allParamNames = new HashSet<>();
    List<TemplateParam> unusedParams = new ArrayList<>();
    for (TemplateParam param : node.getAllParams()) {
        allParamNames.add(param.name());
        if (dataKeys.containsKey(param.name())) {
            // Good: Declared and referenced in template. We remove these from dataKeys so
            // that at the end of the for-loop, dataKeys will only contain the keys that are referenced
            // but not declared in SoyDoc.
            dataKeys.removeAll(param.name());
        } else if (ipi.paramKeyToCalleesMultimap.containsKey(param.name()) || ipi.mayHaveIndirectParamsInExternalCalls || ipi.mayHaveIndirectParamsInExternalDelCalls) {
        // Good: Declared in SoyDoc and either (a) used in a call that passes all data or (b) used
        // in an external call or delcall that passes all data, which may need the param (we can't
        // verify).
        } else {
            // Bad: Declared in SoyDoc but not referenced in template.
            unusedParams.add(param);
        }
    }
    // At this point, the only keys left in dataKeys are undeclared.
    for (Entry<String, SourceLocation> undeclared : dataKeys.entries()) {
        String extraErrorMessage = SoyErrors.getDidYouMeanMessage(allParamNames, undeclared.getKey());
        errorReporter.report(undeclared.getValue(), UNDECLARED_DATA_KEY, undeclared.getKey(), extraErrorMessage);
    }
    // of the same delegate may need to use those params.
    if (node instanceof TemplateBasicNode) {
        for (TemplateParam unusedParam : unusedParams) {
            errorReporter.report(unusedParam.nameLocation(), UNUSED_PARAM, unusedParam.name());
        }
    }
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) TemplateBasicNode(com.google.template.soy.soytree.TemplateBasicNode) ArrayList(java.util.ArrayList) VarRefNode(com.google.template.soy.exprtree.VarRefNode) IndirectParamsInfo(com.google.template.soy.passes.FindIndirectParamsVisitor.IndirectParamsInfo) TemplateParam(com.google.template.soy.soytree.defn.TemplateParam) HashSet(java.util.HashSet)

Example 3 with VarRefNode

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

the class GenIncrementalDomCodeVisitor method tryGenerateFunctionCall.

/**
 * Emits a call to a value of type ATTRIBUTES or HTML, which is actually a JS function. Currently,
 * the only supported expressions for this operation are direct variable references and {X ?: ''}.
 *
 * @param expectedKind The kind of content that the expression must match.
 */
private GenerateFunctionCallResult tryGenerateFunctionCall(SoyType.Kind expectedKind, ExprNode expr) {
    IncrementalDomCodeBuilder jsCodeBuilder = getJsCodeBuilder();
    if (expr instanceof VarRefNode && expr.getType().getKind() == expectedKind) {
        VarRefNode varRefNode = (VarRefNode) expr;
        CodeChunk.WithValue call = templateTranslationContext.soyToJsVariableMappings().get(varRefNode.getName()).call();
        jsCodeBuilder.append(call);
        return GenerateFunctionCallResult.EMITTED;
    }
    if (!(expr instanceof NullCoalescingOpNode)) {
        return GenerateFunctionCallResult.INDIRECT_NODE;
    }
    // ResolveExpressionTypesVisitor will resolve {$attributes ?: ''} to String because '' is not of
    // type ATTRIBUTES.  Therefore, we must check the type of the first operand, not the whole node.
    NullCoalescingOpNode opNode = (NullCoalescingOpNode) expr;
    if (!(opNode.getLeftChild() instanceof VarRefNode) || !(opNode.getRightChild() instanceof StringNode) || opNode.getLeftChild().getType().getKind() != expectedKind) {
        return GenerateFunctionCallResult.INDIRECT_NODE;
    }
    if (!((StringNode) opNode.getRightChild()).getValue().isEmpty()) {
        errorReporter.report(expr.getSourceLocation(), NULL_COALESCING_NON_EMPTY);
        return GenerateFunctionCallResult.ILLEGAL_NODE;
    }
    VarRefNode varRefNode = (VarRefNode) opNode.getLeftChild();
    CodeChunk.WithValue varName = templateTranslationContext.soyToJsVariableMappings().get(varRefNode.getName());
    CodeChunk conditionalCall = CodeChunk.ifStatement(varName, varName.call()).build();
    jsCodeBuilder.append(conditionalCall);
    return GenerateFunctionCallResult.EMITTED;
}
Also used : NullCoalescingOpNode(com.google.template.soy.exprtree.OperatorNodes.NullCoalescingOpNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) StringNode(com.google.template.soy.exprtree.StringNode)

Example 4 with VarRefNode

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

the class TemplateCompiler method generateTemplateMetadata.

/**
 * Writes a {@link TemplateMetadata} to the generated class.
 */
private void generateTemplateMetadata() {
    SanitizedContentKind contentKind = template.node().getContentKind();
    String kind = contentKind == null ? "" : contentKind.name();
    // using linked hash sets below for determinism
    Set<String> uniqueIjs = new LinkedHashSet<>();
    for (VarRefNode var : getAllNodesOfType(template.node(), VarRefNode.class)) {
        if (var.isInjected()) {
            uniqueIjs.add(var.getName());
        }
    }
    Set<String> callees = new LinkedHashSet<>();
    for (CallBasicNode call : getAllNodesOfType(template.node(), CallBasicNode.class)) {
        callees.add(call.getCalleeName());
    }
    Set<String> delCallees = new LinkedHashSet<>();
    for (CallDelegateNode call : getAllNodesOfType(template.node(), CallDelegateNode.class)) {
        delCallees.add(call.getDelCalleeName());
    }
    TemplateMetadata.DelTemplateMetadata deltemplateMetadata;
    if (template.node().getKind() == SoyNode.Kind.TEMPLATE_DELEGATE_NODE) {
        TemplateDelegateNode delegateNode = (TemplateDelegateNode) template.node();
        deltemplateMetadata = createDelTemplateMetadata(delegateNode.getDelPackageName() == null ? "" : delegateNode.getDelPackageName(), delegateNode.getDelTemplateName(), delegateNode.getDelTemplateVariant());
    } else {
        deltemplateMetadata = createDefaultDelTemplateMetadata();
    }
    TemplateMetadata metadata = createTemplateMetadata(kind, uniqueIjs, callees, delCallees, deltemplateMetadata);
    TEMPLATE_METADATA_REF.write(metadata, writer);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) TemplateDelegateNode(com.google.template.soy.soytree.TemplateDelegateNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind) CallBasicNode(com.google.template.soy.soytree.CallBasicNode) TemplateMetadata(com.google.template.soy.jbcsrc.shared.TemplateMetadata) CallDelegateNode(com.google.template.soy.soytree.CallDelegateNode)

Example 5 with VarRefNode

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

the class EvalVisitor method visitIndexFunction.

private SoyValue visitIndexFunction(FunctionNode node) {
    int localVarIndex;
    try {
        VarRefNode dataRef = (VarRefNode) node.getChild(0);
        localVarIndex = env.getIndex((LoopVar) dataRef.getDefnDecl());
    } catch (Exception e) {
        throw RenderException.create("Failed to evaluate function call " + node.toSourceString() + ".", e);
    }
    return convertResult(localVarIndex);
}
Also used : LoopVar(com.google.template.soy.soytree.defn.LoopVar) VarRefNode(com.google.template.soy.exprtree.VarRefNode) IOException(java.io.IOException) SoyDataException(com.google.template.soy.data.SoyDataException)

Aggregations

VarRefNode (com.google.template.soy.exprtree.VarRefNode)22 Test (org.junit.Test)9 SourceLocation (com.google.template.soy.base.SourceLocation)5 ExprNode (com.google.template.soy.exprtree.ExprNode)4 FieldAccessNode (com.google.template.soy.exprtree.FieldAccessNode)4 IntegerNode (com.google.template.soy.exprtree.IntegerNode)4 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)4 SoyDataException (com.google.template.soy.data.SoyDataException)3 PrintNode (com.google.template.soy.soytree.PrintNode)3 TemplateNode (com.google.template.soy.soytree.TemplateNode)3 LoopVar (com.google.template.soy.soytree.defn.LoopVar)3 IOException (java.io.IOException)3 HashSet (java.util.HashSet)3 ParentExprNode (com.google.template.soy.exprtree.ExprNode.ParentExprNode)2 FunctionNode (com.google.template.soy.exprtree.FunctionNode)2 GlobalNode (com.google.template.soy.exprtree.GlobalNode)2 ItemAccessNode (com.google.template.soy.exprtree.ItemAccessNode)2 StringNode (com.google.template.soy.exprtree.StringNode)2 IfCondNode (com.google.template.soy.soytree.IfCondNode)2 IfNode (com.google.template.soy.soytree.IfNode)2