Search in sources :

Example 1 with SanitizedContentKind

use of com.google.template.soy.base.internal.SanitizedContentKind in project closure-templates by google.

the class GenJsCodeVisitor method generateFunctionBody.

/**
 * Generates the function body.
 */
@CheckReturnValue
protected CodeChunk generateFunctionBody(TemplateNode node) {
    // Type check parameters.
    CodeChunk paramDeclarations = genParamTypeChecks(node);
    SanitizedContentKind kind = node.getContentKind();
    CodeChunk bodyAndReturn;
    if (isComputableAsJsExprsVisitor.exec(node)) {
        // Case 1: The code style is 'concat' and the whole template body can be represented as JS
        // expressions. We specially handle this case because we don't want to generate the variable
        // 'output' at all. We simply concatenate the JS expressions and return the result.
        List<CodeChunk.WithValue> templateBodyChunks = genJsExprsVisitor.exec(node);
        if (kind == null) {
            // The template is not strict. Thus, it may not apply an escaping directive to *every* print
            // command, which means that some of its print commands could produce a number. Thus, there
            // is a danger that a plus operator between two expressions in the list will do numeric
            // addition instead of string concatenation. Furthermore, a non-strict template always needs
            // to return a string, but if there is just one expression in the list, and we return it as
            // is, we may not always produce a string (since an escaping directive may not be getting
            // applied in that expression at all, or a directive might be getting applied that produces
            // SanitizedContent). We thus call a method that makes sure to return an expression that
            // produces a string and is in no danger of using numeric addition when concatenating the
            // expressions in the list.
            bodyAndReturn = return_(CodeChunkUtils.concatChunksForceString(templateBodyChunks));
        } else {
            // The template is strict. Thus, it applies an escaping directive to *every* print command,
            // which means that no print command produces a number, which means that there is no danger
            // of a plus operator between two print commands doing numeric addition instead of string
            // concatenation. And since a strict template needs to return SanitizedContent, it is ok to
            // get an expression that produces SanitizedContent, which is indeed possible with an
            // escaping directive that produces SanitizedContent. Thus, we do not have to be extra
            // careful when concatenating the expressions in the list.
            bodyAndReturn = return_(sanitize(CodeChunkUtils.concatChunks(templateBodyChunks), kind));
        }
    } else {
        // Case 2: Normal case.
        jsCodeBuilder.pushOutputVar("output");
        CodeChunk codeChunk = visitChildrenReturningCodeChunk(node);
        jsCodeBuilder.popOutputVar();
        bodyAndReturn = CodeChunk.statements(codeChunk, return_(sanitize(id("output"), kind)));
    }
    return CodeChunk.statements(paramDeclarations, bodyAndReturn);
}
Also used : CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind) CheckReturnValue(javax.annotation.CheckReturnValue)

Example 2 with SanitizedContentKind

use of com.google.template.soy.base.internal.SanitizedContentKind in project closure-templates by google.

the class GenIncrementalDomCodeVisitor method visitCallNode.

@Override
protected void visitCallNode(CallNode node) {
    // expressions, visit them to generate code to define their respective 'param<n>' variables.
    for (CallParamNode child : node.getChildren()) {
        if (child instanceof CallParamContentNode && !isComputableAsJsExprsVisitor.exec(child)) {
            visit(child);
        }
    }
    CodeChunk.WithValue call = genCallCodeUtils.gen(node, templateAliases, templateTranslationContext, errorReporter);
    switch(getJsCodeBuilder().getContentKind()) {
        case ATTRIBUTES:
            getJsCodeBuilder().append(call);
            break;
        case HTML:
            Optional<SanitizedContentKind> kind = templateRegistry.getCallContentKind(node);
            // such as dynamic recompilation.
            if (!kind.isPresent()) {
                call = SOY_IDOM_RENDER_DYNAMIC_CONTENT.call(call);
            } else if (isTextContent(kind.get())) {
                call = generateTextCall(call);
            }
            getJsCodeBuilder().append(call);
            break;
        case JS:
        case URI:
        case TRUSTED_RESOURCE_URI:
        case CSS:
        case TEXT:
            // If the current content kind (due to a let, param or template) is a text-like, simply
            // concatentate the result of the call to the current output variable.
            getJsCodeBuilder().addChunkToOutputVar(call);
            break;
    }
}
Also used : CallParamContentNode(com.google.template.soy.soytree.CallParamContentNode) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) CallParamNode(com.google.template.soy.soytree.CallParamNode) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind)

Example 3 with SanitizedContentKind

use of com.google.template.soy.base.internal.SanitizedContentKind in project closure-templates by google.

the class GenIncrementalDomCodeVisitor method visitLetParamContentNode.

/**
 * Generates the content of a {@code let} or {@code param} statement. For HTML and attribute
 * let/param statements, the generated instructions inside the node are wrapped in a function
 * which will be optionally passed to another template and invoked in the correct location. All
 * other kinds of let statements are generated as a simple variable.
 */
private void visitLetParamContentNode(RenderUnitNode node, String generatedVarName) {
    // The html transform step, performed by HTMLTransformVisitor, ensures that
    // we always have a content kind specified.
    checkState(node.getContentKind() != null);
    IncrementalDomCodeBuilder jsCodeBuilder = getJsCodeBuilder();
    SanitizedContentKind prevContentKind = jsCodeBuilder.getContentKind();
    jsCodeBuilder.setContentKind(node.getContentKind());
    CodeChunk definition;
    switch(node.getContentKind()) {
        case HTML:
        case ATTRIBUTES:
            definition = VariableDeclaration.builder(generatedVarName).setRhs(CodeChunk.function(ImmutableList.<String>of(), visitChildrenReturningCodeChunk(node))).build();
            break;
        default:
            // We do our own initialization, so mark it as such.
            String outputVarName = generatedVarName + "_output";
            jsCodeBuilder.pushOutputVar(outputVarName).setOutputVarInited();
            definition = CodeChunk.statements(VariableDeclaration.builder(outputVarName).setRhs(LITERAL_EMPTY_STRING).build(), visitChildrenReturningCodeChunk(node), VariableDeclaration.builder(generatedVarName).setRhs(JsRuntime.sanitizedContentOrdainerFunctionForInternalBlocks(node.getContentKind()).call(id(outputVarName))).build());
            jsCodeBuilder.popOutputVar();
            break;
    }
    jsCodeBuilder.setContentKind(prevContentKind);
    jsCodeBuilder.append(definition);
}
Also used : CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind)

Example 4 with SanitizedContentKind

use of com.google.template.soy.base.internal.SanitizedContentKind 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 SanitizedContentKind

use of com.google.template.soy.base.internal.SanitizedContentKind in project closure-templates by google.

the class TemplateNodeBuilder method setCommonCommandValues.

protected void setCommonCommandValues(List<CommandTagAttribute> attrs) {
    AutoescapeMode autoescapeMode = soyFileHeaderInfo.defaultAutoescapeMode;
    SanitizedContentKind kind = null;
    SourceLocation kindLocation = null;
    for (CommandTagAttribute attribute : attrs) {
        Identifier name = attribute.getName();
        switch(name.identifier()) {
            case "autoescape":
                autoescapeMode = attribute.valueAsAutoescapeMode(errorReporter);
                break;
            case "kind":
                kind = attribute.valueAsContentKind(errorReporter);
                kindLocation = attribute.getValueLocation();
                if (kind == SanitizedContentKind.HTML) {
                    errorReporter.report(kindLocation, CommandTagAttribute.EXPLICIT_DEFAULT_ATTRIBUTE, "kind", "html");
                }
                break;
            case "requirecss":
                setRequiredCssNamespaces(attribute.valueAsRequireCss(errorReporter));
                break;
            case "cssbase":
                setCssBaseNamespace(attribute.valueAsCssBase(errorReporter));
                break;
            case "deprecatedV1":
                markDeprecatedV1(attribute.valueAsEnabled(errorReporter));
                break;
            case "stricthtml":
                strictHtmlDisabled = attribute.valueAsDisabled(errorReporter);
                break;
            default:
                break;
        }
    }
    setAutoescapeInfo(autoescapeMode, kind, kindLocation);
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) Identifier(com.google.template.soy.base.internal.Identifier) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind)

Aggregations

SanitizedContentKind (com.google.template.soy.base.internal.SanitizedContentKind)12 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)4 TemplateDelegateNode (com.google.template.soy.soytree.TemplateDelegateNode)2 SourceLocation (com.google.template.soy.base.SourceLocation)1 Identifier (com.google.template.soy.base.internal.Identifier)1 VarRefNode (com.google.template.soy.exprtree.VarRefNode)1 Expression (com.google.template.soy.jbcsrc.restricted.Expression)1 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)1 Statement.returnExpression (com.google.template.soy.jbcsrc.restricted.Statement.returnExpression)1 TemplateMetadata (com.google.template.soy.jbcsrc.shared.TemplateMetadata)1 AutoescapeMode (com.google.template.soy.soytree.AutoescapeMode)1 CallBasicNode (com.google.template.soy.soytree.CallBasicNode)1 CallDelegateNode (com.google.template.soy.soytree.CallDelegateNode)1 CallParamContentNode (com.google.template.soy.soytree.CallParamContentNode)1 CallParamNode (com.google.template.soy.soytree.CallParamNode)1 HtmlAttributeValueNode (com.google.template.soy.soytree.HtmlAttributeValueNode)1 RawTextNode (com.google.template.soy.soytree.RawTextNode)1 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)1 LinkedHashSet (java.util.LinkedHashSet)1 CheckReturnValue (javax.annotation.CheckReturnValue)1