Search in sources :

Example 6 with SoyFileNode

use of com.google.template.soy.soytree.SoyFileNode in project closure-templates by google.

the class HtmlRewritePassTest method assertThatSourceString.

private static StringSubject assertThatSourceString(TemplateNode node) {
    SoyFileNode parent = node.getParent().copy(new CopyState());
    new DesugarHtmlNodesPass().run(parent, new IncrementingIdGenerator());
    StringBuilder sb = new StringBuilder();
    parent.getChild(0).appendSourceStringForChildren(sb);
    return assertThat(sb.toString());
}
Also used : CopyState(com.google.template.soy.basetree.CopyState) IncrementingIdGenerator(com.google.template.soy.base.internal.IncrementingIdGenerator) SoyFileNode(com.google.template.soy.soytree.SoyFileNode)

Example 7 with SoyFileNode

use of com.google.template.soy.soytree.SoyFileNode in project closure-templates by google.

the class DesugarHtmlNodesPassTest method runPass.

/**
 * Parses the given input as a template content, runs the HtmlRewrite pass and the Desugar Passes
 * and returns the resulting source string of the template body
 */
private static String runPass(String input) {
    String soyFile = Joiner.on('\n').join("{namespace ns}", "{template .t}", input, "{/template}");
    SoyFileNode node = SoyFileSetParserBuilder.forFileContents(soyFile).desugarHtmlNodes(true).parse().fileSet().getChild(0);
    assertThat(SoyTreeUtils.hasHtmlNodes(node)).isFalse();
    StringBuilder sb = new StringBuilder();
    node.getChild(0).appendSourceStringForChildren(sb);
    return sb.toString();
}
Also used : SoyFileNode(com.google.template.soy.soytree.SoyFileNode)

Example 8 with SoyFileNode

use of com.google.template.soy.soytree.SoyFileNode in project closure-templates by google.

the class FindIndirectParamsVisitorTest method testFindIndirectParams.

@Test
public void testFindIndirectParams() {
    String fileContent1 = "{namespace alpha}\n" + "\n" + "/** @param? a0 @param? b3 */\n" + // 'b3' listed by alpha.zero
    "{template .zero}\n" + "  {call .zero data=\"all\" /}\n" + // recursive call should not cause 'a0' to be added
    "  {call .one data=\"all\" /}\n" + "  {call .two /}\n" + "  {call beta.zero /}\n" + "  {call .five data=\"all\"}\n" + "    {param a5: $a0 /}\n" + "    {param b2: 88 /}\n" + "  {/call}\n" + "{/template}\n" + "\n" + "/** @param? a1 */\n" + "{template .one}\n" + "  {call .three data=\"all\" /}\n" + "  {call .four /}\n" + "  {$a1}\n" + "{/template}\n" + "\n" + "/** @param? a2 */\n" + "{template .two}\n" + "  {$a2}\n" + "{/template}\n" + "\n" + "/** @param? a3 */\n" + "{template .three}\n" + "  {call beta.one data=\"all\" /}\n" + "  {$a3}\n" + "{/template}\n" + "\n" + "/** @param? a4 */\n" + "{template .four}\n" + "  {call external.one /}\n" + "  {$a4}\n" + "{/template}\n" + "\n" + "/** @param? a5 @param? b4 */\n" + // 'b4' listed by alpha.five
    "{template .five}\n" + "  {call beta.two data=\"all\" /}\n" + "  {call beta.three data=\"all\" /}\n" + "  {call beta.four data=\"all\" /}\n" + "  {$b4}\n" + "  {$a5}\n" + "{/template}\n" + "\n" + "/** @param? a6 */\n" + "{template .six}\n" + "  {$a6}\n" + "{/template}\n";
    String fileContent2 = "{namespace beta}\n" + "\n" + "/** @param? b0 */\n" + "{template .zero}\n" + "  {$b0}\n" + "{/template}\n" + "\n" + "/** @param? b1 */\n" + "{template .one}\n" + "  {call alpha.six data=\"all\" /}\n" + "  {$b1}\n" + "{/template}\n" + "\n" + "/** @param? b2 */\n" + "{template .two}\n" + "  {$b2}\n" + "{/template}\n" + "\n" + "/** @param? b3 */\n" + "{template .three}\n" + "  {$b3}\n" + "{/template}\n" + "\n" + "/** @param? b4 */\n" + "{template .four}\n" + "  {$b4}\n" + "{/template}\n";
    ErrorReporter boom = ErrorReporter.exploding();
    SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(fileContent1, fileContent2).errorReporter(boom).parse().fileSet();
    TemplateRegistry registry = new TemplateRegistry(soyTree, boom);
    SoyFileNode a = soyTree.getChild(0);
    TemplateNode a0 = a.getChild(0);
    TemplateNode a1 = a.getChild(1);
    // TemplateNode a2 = a.getChild(2);
    TemplateNode a3 = a.getChild(3);
    // TemplateNode a4 = a.getChild(4);
    TemplateNode a5 = a.getChild(5);
    TemplateNode a6 = a.getChild(6);
    SoyFileNode b = soyTree.getChild(1);
    // TemplateNode b0 = b.getChild(0);
    TemplateNode b1 = b.getChild(1);
    // TemplateNode b2 = b.getChild(2);
    TemplateNode b3 = b.getChild(3);
    TemplateNode b4 = b.getChild(4);
    IndirectParamsInfo ipi = new FindIndirectParamsVisitor(registry).exec(a0);
    assertThat(ipi.mayHaveIndirectParamsInExternalCalls).isFalse();
    assertThat(ipi.mayHaveIndirectParamsInExternalDelCalls).isFalse();
    Map<String, TemplateParam> ipMap = ipi.indirectParams;
    assertThat(ipMap).hasSize(6);
    assertThat(ipMap).doesNotContainKey("a0");
    assertThat(ipMap).containsKey("a1");
    assertThat(ipMap).doesNotContainKey("a2");
    assertThat(ipMap).containsKey("a3");
    assertThat(ipMap).doesNotContainKey("a4");
    assertThat(ipMap).doesNotContainKey("a5");
    assertThat(ipMap).containsKey("a6");
    assertThat(ipMap).doesNotContainKey("b0");
    assertThat(ipMap).containsKey("b1");
    assertThat(ipMap).doesNotContainKey("b2");
    assertThat(ipMap).containsKey("b3");
    assertThat(ipMap).containsKey("b4");
    Multimap<String, TemplateNode> pktcm = ipi.paramKeyToCalleesMultimap;
    assertThat(pktcm).valuesForKey("a1").isEqualTo(ImmutableSet.of(a1));
    assertThat(pktcm).valuesForKey("a3").isEqualTo(ImmutableSet.of(a3));
    assertThat(pktcm).valuesForKey("a6").isEqualTo(ImmutableSet.of(a6));
    assertThat(pktcm).valuesForKey("b1").isEqualTo(ImmutableSet.of(b1));
    assertThat(pktcm).valuesForKey("b3").isEqualTo(ImmutableSet.of(b3));
    // 'b4' listed by alpha.five
    assertThat(pktcm).valuesForKey("b4").isEqualTo(ImmutableSet.of(a5, b4));
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) TemplateRegistry(com.google.template.soy.soytree.TemplateRegistry) ErrorReporter(com.google.template.soy.error.ErrorReporter) IndirectParamsInfo(com.google.template.soy.passes.FindIndirectParamsVisitor.IndirectParamsInfo) SoyFileSetNode(com.google.template.soy.soytree.SoyFileSetNode) TemplateParam(com.google.template.soy.soytree.defn.TemplateParam) SoyFileNode(com.google.template.soy.soytree.SoyFileNode) Test(org.junit.Test)

Example 9 with SoyFileNode

use of com.google.template.soy.soytree.SoyFileNode in project closure-templates by google.

the class GenerateParseInfoVisitor method visitSoyFileSetNode.

// -----------------------------------------------------------------------------------------------
// Implementations for specific nodes.
@Override
protected void visitSoyFileSetNode(SoyFileSetNode node) {
    // Figure out the generated class name for each Soy file, including adding number suffixes
    // to resolve collisions, and then adding the common suffix "SoyInfo".
    Multimap<String, SoyFileNode> baseGeneratedClassNameToSoyFilesMap = HashMultimap.create();
    for (SoyFileNode soyFile : node.getChildren()) {
        if (soyFile.getSoyFileKind() == SoyFileKind.SRC) {
            baseGeneratedClassNameToSoyFilesMap.put(javaClassNameSource.generateBaseClassName(soyFile), soyFile);
        }
    }
    soyFileToJavaClassNameMap = Maps.newHashMap();
    for (String baseClassName : baseGeneratedClassNameToSoyFilesMap.keySet()) {
        Collection<SoyFileNode> soyFiles = baseGeneratedClassNameToSoyFilesMap.get(baseClassName);
        if (soyFiles.size() == 1) {
            for (SoyFileNode soyFile : soyFiles) {
                soyFileToJavaClassNameMap.put(soyFile, baseClassName + "SoyInfo");
            }
        } else {
            int numberSuffix = 1;
            for (SoyFileNode soyFile : soyFiles) {
                soyFileToJavaClassNameMap.put(soyFile, baseClassName + numberSuffix + "SoyInfo");
                numberSuffix++;
            }
        }
    }
    // Run the pass.
    for (SoyFileNode soyFile : node.getChildren()) {
        visit(soyFile);
    }
}
Also used : SoyFileNode(com.google.template.soy.soytree.SoyFileNode)

Example 10 with SoyFileNode

use of com.google.template.soy.soytree.SoyFileNode in project closure-templates by google.

the class ContextualAutoescaper method rewrite.

/**
 * Rewrites the given Soy files so that dynamic output is properly escaped according to the
 * context in which it appears.
 *
 * @param fileSet Modified in place.
 * @return Extra templates which were derived from templates under fileSet and which must be
 *     compiled with fileSet to produce a correct output. See {@link DerivedTemplateUtils} for an
 *     explanation of these.
 */
public List<TemplateNode> rewrite(SoyFileSetNode fileSet, ErrorReporter errorReporter) {
    // Defensively copy so our loops below hold.
    List<SoyFileNode> files = ImmutableList.copyOf(fileSet.getChildren());
    ImmutableListMultimap<String, TemplateNode> templatesByName = findTemplates(files);
    // Inferences collects all the typing decisions we make, templates we derive, and escaping modes
    // we choose.
    Inferences inferences = new Inferences(fileSet.getNodeIdGenerator(), templatesByName);
    Collection<TemplateNode> allTemplates = inferences.getAllTemplates();
    TemplateCallGraph callGraph = new TemplateCallGraph(templatesByName);
    // Generate a call graph, creating a dummy root that calls all non-private template in
    // Context.PCDATA, and then type the minimal ancestor set needed to reach all contextual
    // templates whether private or not.
    // This should have the effect of being a NOP when there are no contextual templates, will type
    // all contextual templates, and will not barf on private templates that might be declared
    // autoescape="false" because they do funky things that are provably safe by human reason but
    // not by this algorithm.
    Collection<TemplateNode> thatRequireInference = Collections2.filter(allTemplates, REQUIRES_INFERENCE);
    Set<TemplateNode> templateNodesToType = callGraph.callersOf(thatRequireInference);
    templateNodesToType.addAll(thatRequireInference);
    Set<SourceLocation> errorLocations = new HashSet<>();
    for (TemplateNode templateNode : templateNodesToType) {
        try {
            // In strict mode, the author specifies the kind of SanitizedContent to produce, and thus
            // the context in which to escape.
            Context startContext = (templateNode.getContentKind() != null) ? Context.getStartContextForContentKind(templateNode.getContentKind()) : Context.HTML_PCDATA;
            InferenceEngine.inferTemplateEndContext(templateNode, startContext, inferences, errorReporter);
        } catch (SoyAutoescapeException e) {
            reportError(errorReporter, errorLocations, e);
        }
    }
    if (!errorLocations.isEmpty()) {
        // Bail out early, since future passes won't succeed and may throw precondition errors.
        return ImmutableList.<TemplateNode>of();
    }
    // Store inferences so that after processing, clients can access the output contexts for
    // templates.
    this.inferences = inferences;
    runVisitorOnAllTemplatesIncludingNewOnes(inferences, new NonContextualTypedRenderUnitNodesVisitor(errorReporter));
    // Now that we know we don't fail with exceptions, apply the changes to the given files.
    List<TemplateNode> extraTemplates = new Rewriter(inferences, printDirectives).rewrite(fileSet);
    runVisitorOnAllTemplatesIncludingNewOnes(inferences, new PerformDeprecatedNonContextualAutoescapeVisitor(fileSet.getNodeIdGenerator()));
    return extraTemplates;
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) SourceLocation(com.google.template.soy.base.SourceLocation) SoyFileNode(com.google.template.soy.soytree.SoyFileNode) HashSet(java.util.HashSet)

Aggregations

SoyFileNode (com.google.template.soy.soytree.SoyFileNode)20 TemplateNode (com.google.template.soy.soytree.TemplateNode)7 SoyFileSetNode (com.google.template.soy.soytree.SoyFileSetNode)4 Test (org.junit.Test)4 TemplateRegistry (com.google.template.soy.soytree.TemplateRegistry)3 File (java.io.File)3 Writer (java.io.Writer)3 ImmutableList (com.google.common.collect.ImmutableList)2 IncrementingIdGenerator (com.google.template.soy.base.internal.IncrementingIdGenerator)2 CopyState (com.google.template.soy.basetree.CopyState)2 ErrorReporter (com.google.template.soy.error.ErrorReporter)2 SoyMsgBundle (com.google.template.soy.msgs.SoyMsgBundle)2 SoyMsg (com.google.template.soy.msgs.restricted.SoyMsg)2 SoyMsgBundleImpl (com.google.template.soy.msgs.restricted.SoyMsgBundleImpl)2 HashSet (java.util.HashSet)2 ImmutableListMultimap (com.google.common.collect.ImmutableListMultimap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ParseResult (com.google.template.soy.SoyFileSetParser.ParseResult)1 SourceLocation (com.google.template.soy.base.SourceLocation)1 IdGenerator (com.google.template.soy.base.internal.IdGenerator)1