Search in sources :

Example 51 with TemplateNode

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

the class InsertMsgsVisitorTest method testFallbackMsgsUsingMsgBundle.

@Test
public void testFallbackMsgsUsingMsgBundle() {
    SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(FALLBACK_TEST_FILE_CONTENT).parse().fileSet();
    TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
    // Before.
    assertThat(template.numChildren()).isEqualTo(4);
    assertThat(((MsgFallbackGroupNode) template.getChild(0)).numChildren()).isEqualTo(2);
    assertThat(((MsgFallbackGroupNode) template.getChild(1)).numChildren()).isEqualTo(2);
    assertThat(((MsgFallbackGroupNode) template.getChild(2)).numChildren()).isEqualTo(2);
    assertThat(((MsgFallbackGroupNode) template.getChild(3)).numChildren()).isEqualTo(2);
    // Build the translated message bundle.
    List<SoyMsg> translatedMsgs = Lists.newArrayList();
    MsgNode trans1FirstInstance = ((MsgFallbackGroupNode) template.getChild(1)).getChild(0);
    translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(trans1FirstInstance)).setLocaleString("x-zz").setParts(ImmutableList.<SoyMsgPart>of(SoyMsgRawTextPart.of("ztrans1"))).build());
    MsgNode trans2FirstInstance = ((MsgFallbackGroupNode) template.getChild(2)).getChild(1);
    translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(trans2FirstInstance)).setLocaleString("x-zz").setParts(ImmutableList.<SoyMsgPart>of(SoyMsgRawTextPart.of("ztrans2"))).build());
    SoyMsgBundle msgBundle = new SoyMsgBundleImpl("x-zz", translatedMsgs);
    // Execute the visitor.
    new InsertMsgsVisitor(msgBundle, FAIL).insertMsgs(template);
    // After.
    assertThat(template.numChildren()).isEqualTo(4);
    assertThat(((RawTextNode) template.getChild(0)).getRawText()).isEqualTo("noTrans1");
    assertThat(((RawTextNode) template.getChild(1)).getRawText()).isEqualTo("ztrans1");
    assertThat(((RawTextNode) template.getChild(2)).getRawText()).isEqualTo("ztrans2");
    assertThat(((RawTextNode) template.getChild(3)).getRawText()).isEqualTo("ztrans1");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) SoyMsg(com.google.template.soy.msgs.restricted.SoyMsg) SoyMsgBundleImpl(com.google.template.soy.msgs.restricted.SoyMsgBundleImpl) MsgFallbackGroupNode(com.google.template.soy.soytree.MsgFallbackGroupNode) SoyFileSetNode(com.google.template.soy.soytree.SoyFileSetNode) SoyMsgBundle(com.google.template.soy.msgs.SoyMsgBundle) RawTextNode(com.google.template.soy.soytree.RawTextNode) MsgNode(com.google.template.soy.soytree.MsgNode) Test(org.junit.Test)

Example 52 with TemplateNode

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

the class InsertMsgsVisitorTest method testPlrselMsgsUsingSoySource.

@Test
public void testPlrselMsgsUsingSoySource() {
    SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(PLRSEL_TEST_FILE_CONTENT).parse().fileSet();
    TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
    assertThat(template.numChildren()).isEqualTo(2);
    // Execute the visitor.
    ErrorReporter errorReporter = ErrorReporter.createForTest();
    new InsertMsgsVisitor(null, /* msgBundle */
    errorReporter).insertMsgs(template);
    assertThat(errorReporter.getErrors()).hasSize(2);
    assertThat(errorReporter.getErrors().get(0).toString()).contains("JS code generation currently only supports plural/select messages when " + "shouldGenerateGoogMsgDefs is true.");
    assertThat(errorReporter.getErrors().get(1).toString()).contains("JS code generation currently only supports plural/select messages when " + "shouldGenerateGoogMsgDefs is true.");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) ErrorReporter(com.google.template.soy.error.ErrorReporter) SoyFileSetNode(com.google.template.soy.soytree.SoyFileSetNode) Test(org.junit.Test)

Example 53 with TemplateNode

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

the class InsertMsgsVisitorTest method testBasicMsgsUsingMsgBundle.

@Test
public void testBasicMsgsUsingMsgBundle() {
    SoyFileSetNode soyTree = SoyFileSetParserBuilder.forFileContents(BASIC_TEST_FILE_CONTENT).parse().fileSet();
    TemplateNode template = (TemplateNode) SharedTestUtils.getNode(soyTree);
    // Before.
    assertThat(template.numChildren()).isEqualTo(5);
    MsgNode msg = ((MsgFallbackGroupNode) template.getChild(2)).getChild(0);
    assertThat(msg.numChildren()).isEqualTo(5);
    MsgHtmlTagNode msgHtmlTag2 = (MsgHtmlTagNode) ((MsgPlaceholderNode) msg.getChild(2)).getChild(0);
    assertThat(msgHtmlTag2.numChildren()).isEqualTo(3);
    MsgHtmlTagNode msgHtmlTag4 = (MsgHtmlTagNode) ((MsgPlaceholderNode) msg.getChild(4)).getChild(0);
    assertThat(msgHtmlTag4.numChildren()).isEqualTo(1);
    assertThat(((RawTextNode) msgHtmlTag4.getChild(0)).getRawText()).isEqualTo("</a>");
    // Build the translated message bundle.
    List<SoyMsg> translatedMsgs = Lists.newArrayList();
    // Original (en): random{{FOO}}{{START_LINK}}slimy{{END_LINK}}
    // Translation (x-zz): {{START_LINK}}zslimy{{END_LINK}}{{FOO}}zrandom
    translatedMsgs.add(SoyMsg.builder().setId(MsgUtils.computeMsgIdForDualFormat(msg)).setLocaleString("x-zz").setParts(ImmutableList.of(new SoyMsgPlaceholderPart("START_LINK", /* placeholderExample= */
    null), SoyMsgRawTextPart.of("zslimy"), new SoyMsgPlaceholderPart("END_LINK", /* placeholderExample= */
    null), new SoyMsgPlaceholderPart("FOO", /* placeholderExample= */
    null), SoyMsgRawTextPart.of("zrandom"))).build());
    // Note: This bundle has no translation for the message "dairy{$moo}".
    SoyMsgBundle msgBundle = new SoyMsgBundleImpl("x-zz", translatedMsgs);
    // Execute the visitor.
    new InsertMsgsVisitor(msgBundle, FAIL).insertMsgs(template);
    // After.
    assertThat(template.numChildren()).isEqualTo(12);
    assertThat(((PrintNode) template.getChild(0)).getExpr().toSourceString()).isEqualTo("$boo");
    assertThat(((RawTextNode) template.getChild(1)).getRawText()).isEqualTo("scary ");
    assertThat(((RawTextNode) template.getChild(2)).getRawText()).isEqualTo("<a href=\"");
    assertThat(((PrintNode) template.getChild(3)).getExpr().toSourceString()).isEqualTo("$goo");
    assertThat(((RawTextNode) template.getChild(4)).getRawText()).isEqualTo("\">");
    assertThat(((RawTextNode) template.getChild(5)).getRawText()).isEqualTo("zslimy");
    assertThat(((RawTextNode) template.getChild(6)).getRawText()).isEqualTo("</a>");
    assertThat(((PrintNode) template.getChild(7)).getExpr().toSourceString()).isEqualTo("$foo");
    assertThat(((RawTextNode) template.getChild(8)).getRawText()).isEqualTo("zrandom");
    assertThat(((RawTextNode) template.getChild(9)).getRawText()).isEqualTo(" ");
    assertThat(((RawTextNode) template.getChild(10)).getRawText()).isEqualTo("dairy");
    assertThat(((PrintNode) template.getChild(11)).getExpr().toSourceString()).isEqualTo("$moo");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) SoyMsg(com.google.template.soy.msgs.restricted.SoyMsg) SoyMsgPlaceholderPart(com.google.template.soy.msgs.restricted.SoyMsgPlaceholderPart) SoyMsgBundleImpl(com.google.template.soy.msgs.restricted.SoyMsgBundleImpl) MsgFallbackGroupNode(com.google.template.soy.soytree.MsgFallbackGroupNode) SoyFileSetNode(com.google.template.soy.soytree.SoyFileSetNode) MsgHtmlTagNode(com.google.template.soy.soytree.MsgHtmlTagNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) SoyMsgBundle(com.google.template.soy.msgs.SoyMsgBundle) MsgNode(com.google.template.soy.soytree.MsgNode) Test(org.junit.Test)

Example 54 with TemplateNode

use of com.google.template.soy.soytree.TemplateNode 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)

Example 55 with TemplateNode

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

the class ContextualAutoescaper method findTemplates.

/**
 * Fills in the {@link Inferences} template name to node map.
 *
 * @param files Modified in place.
 */
private static ImmutableListMultimap<String, TemplateNode> findTemplates(Iterable<? extends SoyFileNode> files) {
    ImmutableListMultimap.Builder<String, TemplateNode> builder = ImmutableListMultimap.builder();
    for (SoyFileNode file : files) {
        for (TemplateNode template : file.getChildren()) {
            String templateName;
            if (template instanceof TemplateBasicNode) {
                templateName = template.getTemplateName();
            } else {
                templateName = ((TemplateDelegateNode) template).getDelTemplateName();
            }
            builder.put(templateName, template);
        }
    }
    return builder.build();
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) TemplateBasicNode(com.google.template.soy.soytree.TemplateBasicNode) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) SoyFileNode(com.google.template.soy.soytree.SoyFileNode)

Aggregations

TemplateNode (com.google.template.soy.soytree.TemplateNode)89 Test (org.junit.Test)59 SoyFileSetNode (com.google.template.soy.soytree.SoyFileSetNode)35 TemplateRegistry (com.google.template.soy.soytree.TemplateRegistry)19 ErrorReporter (com.google.template.soy.error.ErrorReporter)11 ParseResult (com.google.template.soy.SoyFileSetParser.ParseResult)10 TransitiveDepTemplatesInfo (com.google.template.soy.passes.FindTransitiveDepTemplatesVisitor.TransitiveDepTemplatesInfo)9 RawTextNode (com.google.template.soy.soytree.RawTextNode)9 SoyFileNode (com.google.template.soy.soytree.SoyFileNode)8 TemplateParam (com.google.template.soy.soytree.defn.TemplateParam)7 FunctionNode (com.google.template.soy.exprtree.FunctionNode)6 PrintNode (com.google.template.soy.soytree.PrintNode)5 TemplateDelegateNode (com.google.template.soy.soytree.TemplateDelegateNode)5 ImmutableMap (com.google.common.collect.ImmutableMap)4 SourceLocation (com.google.template.soy.base.SourceLocation)4 StringNode (com.google.template.soy.exprtree.StringNode)4 MsgFallbackGroupNode (com.google.template.soy.soytree.MsgFallbackGroupNode)4 ImmutableList (com.google.common.collect.ImmutableList)3 VarRefNode (com.google.template.soy.exprtree.VarRefNode)3 SoyMsgBundle (com.google.template.soy.msgs.SoyMsgBundle)3