Search in sources :

Example 1 with FindIndirectParamsVisitor

use of com.google.template.soy.passes.FindIndirectParamsVisitor in project closure-templates by google.

the class GenJsCodeVisitor method genParamsRecordType.

// -----------------------------------------------------------------------------------------------
// Helpers
/**
 * Generate the JSDoc for the opt_data parameter.
 */
private String genParamsRecordType(TemplateNode node) {
    Set<String> paramNames = new HashSet<>();
    // Generate members for explicit params.
    Map<String, String> record = new LinkedHashMap<>();
    for (TemplateParam param : node.getParams()) {
        JsType jsType = getJsType(param.type());
        record.put(genParamAlias(param.name()), jsType.typeExprForRecordMember(/* isOptional= */
        !param.isRequired()));
        for (GoogRequire require : jsType.getGoogRequires()) {
            jsCodeBuilder.addGoogRequire(require);
        }
        paramNames.add(param.name());
    }
    // Do the same for indirect params, if we can find them.
    // If there's a conflict between the explicitly-declared type, and the type
    // inferred from the indirect params, then the explicit type wins.
    // Also note that indirect param types may not be inferrable if the target
    // is not in the current compilation file set.
    IndirectParamsInfo ipi = new FindIndirectParamsVisitor(templateRegistry).exec(node);
    // types in JS allow additional undeclared fields to be present.
    if (!ipi.mayHaveIndirectParamsInExternalCalls && !ipi.mayHaveIndirectParamsInExternalDelCalls) {
        for (String indirectParamName : ipi.indirectParamTypes.keySet()) {
            if (paramNames.contains(indirectParamName)) {
                continue;
            }
            Collection<SoyType> paramTypes = ipi.indirectParamTypes.get(indirectParamName);
            SoyType combinedType = SoyTypes.computeLowestCommonType(typeRegistry, paramTypes);
            // Note that Union folds duplicate types and flattens unions, so if
            // the combinedType is already a union this will do the right thing.
            // TODO: detect cases where nullable is not needed (requires flow
            // analysis to determine if the template is always called.)
            SoyType indirectParamType = typeRegistry.getOrCreateUnionType(combinedType, NullType.getInstance());
            JsType jsType = getJsType(indirectParamType);
            // NOTE: we do not add goog.requires for indirect types.  This is because it might introduce
            // strict deps errors.  This should be fine though since the transitive soy template that
            // actually has the param will add them.
            record.put(genParamAlias(indirectParamName), jsType.typeExprForRecordMember(/* isOptional= */
            true));
        }
    }
    StringBuilder sb = new StringBuilder();
    sb.append("{\n *  ");
    Joiner.on(",\n *  ").withKeyValueSeparator(": ").appendTo(sb, record);
    // trailing comma in record is important in case the last record member is the
    // unknown type
    sb.append(",\n * }");
    return sb.toString();
}
Also used : LinkedHashMap(java.util.LinkedHashMap) IndirectParamsInfo(com.google.template.soy.passes.FindIndirectParamsVisitor.IndirectParamsInfo) GoogRequire(com.google.template.soy.jssrc.dsl.GoogRequire) SoyType(com.google.template.soy.types.SoyType) TemplateParam(com.google.template.soy.soytree.defn.TemplateParam) HashSet(java.util.HashSet) FindIndirectParamsVisitor(com.google.template.soy.passes.FindIndirectParamsVisitor)

Example 2 with FindIndirectParamsVisitor

use of com.google.template.soy.passes.FindIndirectParamsVisitor in project closure-templates by google.

the class GenerateParseInfoVisitor method visitTemplateNode.

@Override
protected void visitTemplateNode(TemplateNode node) {
    // Don't generate anything for private or delegate templates.
    if (node.getVisibility() != Visibility.PUBLIC || node instanceof TemplateDelegateNode) {
        return;
    }
    // First build list of all transitive params (direct and indirect).
    LinkedHashMap<String, TemplateParam> transitiveParamMap = Maps.newLinkedHashMap();
    // Direct params.
    for (TemplateParam param : node.getParams()) {
        transitiveParamMap.put(param.name(), param);
    }
    // Indirect params.
    IndirectParamsInfo indirectParamsInfo = new FindIndirectParamsVisitor(templateRegistry).exec(node);
    for (TemplateParam param : indirectParamsInfo.indirectParams.values()) {
        TemplateParam existingParam = transitiveParamMap.get(param.name());
        if (existingParam == null) {
            // Note: We don't list the description for indirect params.
            transitiveParamMap.put(param.name(), param.copyEssential());
        }
    }
    // Get info on injected params.
    IjParamsInfo ijParamsInfo = new FindIjParamsVisitor(templateRegistry).exec(node);
    // for IntelliJ
    @SuppressWarnings("ConstantConditions") String upperUnderscoreName = convertToUpperUnderscore(node.getPartialTemplateName().substring(1));
    String templateInfoClassName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, upperUnderscoreName) + "SoyTemplateInfo";
    // ------ *SoyTemplateInfo class start. ------
    ilb.appendLine();
    ilb.appendLine();
    appendJavadoc(ilb, Optional.fromNullable(node.getSoyDocDesc()).or(""), true, false);
    ilb.appendLine("public static final class ", templateInfoClassName, " extends SoyTemplateInfo {");
    ilb.increaseIndent();
    // ------ Constants for template name. ------
    ilb.appendLine();
    ilb.appendLine("/** This template's full name. */");
    ilb.appendLine("public static final String __NAME__ = \"", node.getTemplateName(), "\";");
    ilb.appendLine("/** This template's partial name. */");
    ilb.appendLine("public static final String __PARTIAL_NAME__ = \"", node.getPartialTemplateName(), "\";");
    // ------ Param constants. ------
    boolean hasSeenFirstDirectParam = false;
    boolean hasSwitchedToIndirectParams = false;
    for (TemplateParam param : transitiveParamMap.values()) {
        if (param.desc() != null) {
            // Direct param.
            if (!hasSeenFirstDirectParam) {
                ilb.appendLine();
                hasSeenFirstDirectParam = true;
            }
            appendJavadoc(ilb, param.desc(), false, false);
        } else {
            // Indirect param.
            if (!hasSwitchedToIndirectParams) {
                ilb.appendLine();
                ilb.appendLine("// Indirect params.");
                hasSwitchedToIndirectParams = true;
            }
            // Get the list of all transitive callee names as they will appear in the generated
            // Javadoc (possibly containing both partial and full names) and sort them before
            // generating the Javadoc.
            SortedSet<String> sortedJavadocCalleeNames = Sets.newTreeSet();
            for (TemplateNode transitiveCallee : indirectParamsInfo.paramKeyToCalleesMultimap.get(param.name())) {
                String javadocCalleeName = buildTemplateNameForJavadoc(node.getParent(), transitiveCallee);
                sortedJavadocCalleeNames.add(javadocCalleeName);
            }
            // Generate the Javadoc.
            StringBuilder javadocSb = new StringBuilder();
            javadocSb.append("Listed by ");
            boolean isFirst = true;
            for (String javadocCalleeName : sortedJavadocCalleeNames) {
                if (isFirst) {
                    isFirst = false;
                } else {
                    javadocSb.append(", ");
                }
                javadocSb.append(javadocCalleeName);
            }
            javadocSb.append('.');
            appendJavadoc(ilb, javadocSb.toString(), false, true);
        }
        // The actual param field.
        ilb.appendLine("public static final String ", convertToUpperUnderscore(param.name()), " = \"", param.name(), "\";");
    }
    // ------ Constructor. ------
    ilb.appendLine();
    ilb.appendLine("private ", templateInfoClassName, "() {");
    ilb.increaseIndent();
    ilb.appendLine("super(");
    ilb.increaseIndent(2);
    ilb.appendLine("\"", node.getTemplateName(), "\",");
    if (!transitiveParamMap.isEmpty()) {
        ImmutableMap.Builder<String, String> entrySnippetPairs = ImmutableMap.builder();
        for (TemplateParam param : transitiveParamMap.values()) {
            entrySnippetPairs.put("\"" + param.name() + "\"", param.isRequired() ? "ParamRequisiteness.REQUIRED" : "ParamRequisiteness.OPTIONAL");
        }
        appendImmutableMap(ilb, "<String, ParamRequisiteness>", entrySnippetPairs.build());
        ilb.appendLineEnd(",");
    } else {
        ilb.appendLine("ImmutableMap.<String, ParamRequisiteness>of(),");
    }
    appendIjParamSet(ilb, ijParamsInfo);
    ilb.appendLineEnd(",");
    ilb.appendLine("\"", node.getAutoescapeMode().getAttributeValue(), "\");");
    ilb.decreaseIndent(2);
    ilb.decreaseIndent();
    ilb.appendLine("}");
    // ------ Singleton instance and its getter. ------
    ilb.appendLine();
    ilb.appendLine("private static final ", templateInfoClassName, " __INSTANCE__ =");
    ilb.increaseIndent(2);
    ilb.appendLine("new ", templateInfoClassName, "();");
    ilb.decreaseIndent(2);
    ilb.appendLine();
    ilb.appendLine("public static ", templateInfoClassName, " getInstance() {");
    ilb.increaseIndent();
    ilb.appendLine("return __INSTANCE__;");
    ilb.decreaseIndent();
    ilb.appendLine("}");
    // ------ *SoyTemplateInfo class end. ------
    ilb.decreaseIndent();
    ilb.appendLine("}");
    // ------ Static field with instance of *SoyTemplateInfo class. ------
    ilb.appendLine();
    ilb.appendLine("/** Same as ", templateInfoClassName, ".getInstance(). */");
    ilb.appendLine("public static final ", templateInfoClassName, " ", upperUnderscoreName, " =");
    ilb.increaseIndent(2);
    ilb.appendLine(templateInfoClassName, ".getInstance();");
    ilb.decreaseIndent(2);
}
Also used : TemplateDelegateNode(com.google.template.soy.soytree.TemplateDelegateNode) IjParamsInfo(com.google.template.soy.passes.FindIjParamsVisitor.IjParamsInfo) TemplateNode(com.google.template.soy.soytree.TemplateNode) FindIjParamsVisitor(com.google.template.soy.passes.FindIjParamsVisitor) ImmutableMap(com.google.common.collect.ImmutableMap) IndirectParamsInfo(com.google.template.soy.passes.FindIndirectParamsVisitor.IndirectParamsInfo) TemplateParam(com.google.template.soy.soytree.defn.TemplateParam) FindIndirectParamsVisitor(com.google.template.soy.passes.FindIndirectParamsVisitor)

Aggregations

FindIndirectParamsVisitor (com.google.template.soy.passes.FindIndirectParamsVisitor)2 IndirectParamsInfo (com.google.template.soy.passes.FindIndirectParamsVisitor.IndirectParamsInfo)2 TemplateParam (com.google.template.soy.soytree.defn.TemplateParam)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 GoogRequire (com.google.template.soy.jssrc.dsl.GoogRequire)1 FindIjParamsVisitor (com.google.template.soy.passes.FindIjParamsVisitor)1 IjParamsInfo (com.google.template.soy.passes.FindIjParamsVisitor.IjParamsInfo)1 TemplateDelegateNode (com.google.template.soy.soytree.TemplateDelegateNode)1 TemplateNode (com.google.template.soy.soytree.TemplateNode)1 SoyType (com.google.template.soy.types.SoyType)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1