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);
}
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;
}
}
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);
}
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);
}
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);
}
Aggregations