From 089a9dfcb5a43f7ac7626c97cfc7f6a513cca784 Mon Sep 17 00:00:00 2001 From: Jesse Costello-Good Date: Sat, 21 Dec 2024 12:04:26 -0800 Subject: [PATCH] Convert internal print directives to using the JS DSL, which is more modern and correct, and necessary for sourcemaps/kythe support inside such expressions. PiperOrigin-RevId: 708641155 --- .../template/soy/basicdirectives/BUILD.bazel | 3 +- .../basicdirectives/BasicEscapeDirective.java | 21 ++++------ .../ChangeNewlineToBrDirective.java | 20 ++++----- .../basicdirectives/CleanHtmlDirective.java | 39 +++++++++++------ .../FilterImageDataUriDirective.java | 15 +++---- .../FilterSipUriDirective.java | 15 +++---- .../FilterTelUriDirective.java | 15 +++---- .../InsertWordBreaksDirective.java | 19 +++------ .../soy/basicdirectives/TextDirective.java | 16 ++++--- .../basicdirectives/TruncateDirective.java | 29 ++++--------- .../template/soy/bididirectives/BUILD.bazel | 2 + .../bididirectives/BidiSpanWrapDirective.java | 27 ++++++------ .../BidiUnicodeWrapDirective.java | 23 +++++----- .../template/soy/coredirectives/BUILD.bazel | 5 ++- .../coredirectives/EscapeHtmlDirective.java | 16 +++---- .../soy/incrementaldomsrc/BUILD.bazel | 1 + .../BidiUnicodeWrapDirective.java | 32 +++++++------- .../EscapeHtmlDirective.java | 23 +++------- .../FilterHtmlAttributesDirective.java | 19 +++------ .../RemoveUnnecessaryEscapingDirectives.java | 3 +- .../soy/internal/i18n/BidiGlobalDir.java | 1 + .../template/soy/jssrc/internal/BUILD.bazel | 1 + .../soy/jssrc/internal/GenCallCodeUtils.java | 41 ++++++++++-------- .../GenJsCodeVisitorAssistantForMsgs.java | 20 +++++---- .../soy/jssrc/internal/GenJsExprsVisitor.java | 24 +++++++---- .../template/soy/jssrc/restricted/BUILD.bazel | 18 +++++++- .../ModernSoyJsSrcPrintDirective.java | 31 ++++++++++++++ .../template/soy/basicdirectives/BUILD.bazel | 2 +- .../ChangeNewlineToBrDirectiveTest.java | 16 +++---- .../CleanHtmlDirectiveTest.java | 42 ++++++++++--------- .../FilterImageDataUriDirectiveTest.java | 12 ++++-- .../InsertWordBreaksDirectiveTest.java | 21 ++++++---- .../basicdirectives/TextDirectiveTest.java | 16 +++---- .../TruncateDirectiveTest.java | 24 ++++++----- .../template/soy/bididirectives/BUILD.bazel | 2 +- .../BidiSpanWrapDirectiveTest.java | 22 +++++----- .../BidiUnicodeWrapDirectiveTest.java | 22 +++++----- .../template/soy/coredirectives/BUILD.bazel | 2 +- .../EscapeHtmlDirectiveTest.java | 15 +++---- .../template/soy/shared/internal/BUILD.bazel | 1 + .../shared/internal/InternalPluginsTest.java | 6 ++- 41 files changed, 360 insertions(+), 322 deletions(-) create mode 100644 java/src/com/google/template/soy/jssrc/restricted/ModernSoyJsSrcPrintDirective.java diff --git a/java/src/com/google/template/soy/basicdirectives/BUILD.bazel b/java/src/com/google/template/soy/basicdirectives/BUILD.bazel index f6aea60e81..520877e27f 100644 --- a/java/src/com/google/template/soy/basicdirectives/BUILD.bazel +++ b/java/src/com/google/template/soy/basicdirectives/BUILD.bazel @@ -26,7 +26,8 @@ java_library( "//java/src/com/google/template/soy/data:unsafesanitizedcontentordainer", "//java/src/com/google/template/soy/internal/targetexpr", "//java/src/com/google/template/soy/jbcsrc/restricted", - "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/dsl", + "//java/src/com/google/template/soy/jssrc/restricted:internal", "//java/src/com/google/template/soy/pysrc/restricted", "//java/src/com/google/template/soy/shared/internal:escaping_library", "//java/src/com/google/template/soy/shared/internal:short_circuitable", diff --git a/java/src/com/google/template/soy/basicdirectives/BasicEscapeDirective.java b/java/src/com/google/template/soy/basicdirectives/BasicEscapeDirective.java index 3d558fb1aa..132de56f36 100644 --- a/java/src/com/google/template/soy/basicdirectives/BasicEscapeDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/BasicEscapeDirective.java @@ -31,8 +31,7 @@ import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective.Streamable.AppendableAndOptions; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.internal.Sanitizers; @@ -53,7 +52,7 @@ */ public abstract class BasicEscapeDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective { @@ -65,7 +64,9 @@ public abstract class BasicEscapeDirective @LazyInit private IdentityHashMap, MethodRef> javaSanitizerByParamType; @LazyInit private MethodRef javaStreamingSanitizer; - /** @param name E.g. {@code |escapeUri}. */ + /** + * @param name E.g. {@code |escapeUri}. + */ public BasicEscapeDirective(String name) { this.name = name; } @@ -99,14 +100,10 @@ public SoyValue applyForJava(SoyValue value, List args) { } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr( - "soy.$$" + name.substring(1) + "(" + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + return SOY.dotAccess("$$" + name.substring(1)).call(value); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirective.java b/java/src/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirective.java index 08b70ceda4..c43667974c 100644 --- a/java/src/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirective.java @@ -26,8 +26,7 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.restricted.SoyJavaPrintDirective; @@ -39,14 +38,12 @@ import java.util.Set; import javax.annotation.Nonnull; -/** - * A directive that replaces newlines (\n, \r, or \r\n) with HTML line breaks (<br>). - */ +/** A directive that replaces newlines (\n, \r, or \r\n) with HTML line breaks (<br>). */ @SoyPurePrintDirective final class ChangeNewlineToBrDirective implements SanitizedContentOperator, SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable { @@ -99,13 +96,10 @@ public AppendableAndOptions applyForJbcSrcStreaming( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr("soy.$$changeNewlineToBr(" + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + return SOY.dotAccess("$$changeNewlineToBr").call(value); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/CleanHtmlDirective.java b/java/src/com/google/template/soy/basicdirectives/CleanHtmlDirective.java index 7e590f60a2..9117e9a9da 100644 --- a/java/src/com/google/template/soy/basicdirectives/CleanHtmlDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/CleanHtmlDirective.java @@ -33,8 +33,10 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; +import com.google.template.soy.jssrc.dsl.StringLiteral; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.internal.Sanitizers; @@ -60,7 +62,7 @@ @SoyPurePrintDirective final class CleanHtmlDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable { @@ -132,15 +134,28 @@ private Expression fromTagNameList(List args) { } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - String optionalSafeTagsArg = generateOptionalSafeTagsArg(args); - return new JsExpr( - "soy.$$cleanHtml(" + value.getText() + optionalSafeTagsArg + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + List callArgs = new ArrayList<>(); + callArgs.add(value); + if (!args.isEmpty()) { + for (com.google.template.soy.jssrc.dsl.Expression tagName : args) { + if (tagName instanceof StringLiteral) { + OptionalSafeTag.fromTagName(((StringLiteral) tagName).literalValue()); + } else { + throw new IllegalArgumentException( + String.format( + "The cleanHtml directive expects arguments to be tag name string " + + "literals, such as 'span'. Encountered: %s", + tagName.getClass().getSimpleName() + + ": " + + tagName.singleExprOrName(FormatOptions.JSSRC).getText())); + } + } + callArgs.add(Expressions.arrayLiteral(args)); + } + return SOY.dotAccess("$$cleanHtml").call(callArgs); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/FilterImageDataUriDirective.java b/java/src/com/google/template/soy/basicdirectives/FilterImageDataUriDirective.java index 75538f35c3..0e3d470253 100644 --- a/java/src/com/google/template/soy/basicdirectives/FilterImageDataUriDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/FilterImageDataUriDirective.java @@ -22,8 +22,8 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.internal.Sanitizers; @@ -43,7 +43,7 @@ @SoyPurePrintDirective final class FilterImageDataUriDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective { @@ -77,13 +77,8 @@ public SoyExpression applyForJbcSrc( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr("soy.$$filterImageDataUri(" + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public Expression applyForJsSrc(Expression value, List args) { + return SOY.dotAccess("$$filterImageDataUri").call(value); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/FilterSipUriDirective.java b/java/src/com/google/template/soy/basicdirectives/FilterSipUriDirective.java index 3ec677d37e..9b9ab06e8c 100644 --- a/java/src/com/google/template/soy/basicdirectives/FilterSipUriDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/FilterSipUriDirective.java @@ -22,8 +22,8 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.internal.Sanitizers; @@ -42,7 +42,7 @@ @SoyPurePrintDirective final class FilterSipUriDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective { @@ -76,13 +76,8 @@ public SoyExpression applyForJbcSrc( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr("soy.$$filterSipUri(" + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public Expression applyForJsSrc(Expression value, List args) { + return SOY.dotAccess("$$filterSipUri").call(value); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/FilterTelUriDirective.java b/java/src/com/google/template/soy/basicdirectives/FilterTelUriDirective.java index b140ca0e16..16681f7b10 100644 --- a/java/src/com/google/template/soy/basicdirectives/FilterTelUriDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/FilterTelUriDirective.java @@ -22,8 +22,8 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.internal.Sanitizers; @@ -42,7 +42,7 @@ @SoyPurePrintDirective final class FilterTelUriDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective { @@ -76,13 +76,8 @@ public SoyExpression applyForJbcSrc( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr("soy.$$filterTelUri(" + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public Expression applyForJsSrc(Expression value, List args) { + return SOY.dotAccess("$$filterTelUri").call(value); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/InsertWordBreaksDirective.java b/java/src/com/google/template/soy/basicdirectives/InsertWordBreaksDirective.java index eb7817e966..4d63399e78 100644 --- a/java/src/com/google/template/soy/basicdirectives/InsertWordBreaksDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/InsertWordBreaksDirective.java @@ -28,8 +28,7 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.restricted.SoyJavaPrintDirective; @@ -52,7 +51,7 @@ final class InsertWordBreaksDirective implements SanitizedContentOperator, SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable { @@ -118,16 +117,10 @@ public AppendableAndOptions applyForJbcSrcStreaming( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - - return new JsExpr( - "soy.$$insertWordBreaks(" + value.getText() + ", " + args.get(0).getText() + ")", - Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + return SOY.dotAccess("$$insertWordBreaks").call(value, args.get(0)); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/TextDirective.java b/java/src/com/google/template/soy/basicdirectives/TextDirective.java index 8378355353..eadf7831ca 100644 --- a/java/src/com/google/template/soy/basicdirectives/TextDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/TextDirective.java @@ -16,16 +16,14 @@ package com.google.template.soy.basicdirectives; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.template.soy.data.SoyValue; import com.google.template.soy.jbcsrc.restricted.Expression; import com.google.template.soy.jbcsrc.restricted.JbcSrcPluginContext; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.JsExprUtils; -import com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.restricted.SoyJavaPrintDirective; @@ -42,7 +40,7 @@ @SoyPurePrintDirective final class TextDirective implements SoyJavaPrintDirective, - SoyJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable { @@ -77,10 +75,10 @@ public AppendableAndOptions applyForJbcSrcStreaming( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - // Coerce to string, since sometimes this will be the root of an expression and will be used as - // a return value or let-block assignment. - return JsExprUtils.concatJsExprs(ImmutableList.of(new JsExpr("''", Integer.MAX_VALUE), value)); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + return Expressions.stringLiteral("").plus(value); } @Override diff --git a/java/src/com/google/template/soy/basicdirectives/TruncateDirective.java b/java/src/com/google/template/soy/basicdirectives/TruncateDirective.java index c0ebdf8bc0..cf8dbc0460 100644 --- a/java/src/com/google/template/soy/basicdirectives/TruncateDirective.java +++ b/java/src/com/google/template/soy/basicdirectives/TruncateDirective.java @@ -27,8 +27,8 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.PyFunctionExprBuilder; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; @@ -45,7 +45,7 @@ @SoyPurePrintDirective final class TruncateDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable { @@ -122,24 +122,11 @@ public AppendableAndOptions applyForJbcSrcStreaming( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - String maxLenExprText = args.get(0).getText(); - String doAddEllipsisExprText = (args.size() == 2) ? args.get(1).getText() : "true" /*default*/; - - return new JsExpr( - "soy.$$truncate(" - + value.getText() - + ", " - + maxLenExprText - + ", " - + doAddEllipsisExprText - + ")", - Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + return SOY.dotAccess("$$truncate") + .call(value, args.get(0), args.size() == 2 ? args.get(1) : Expressions.LITERAL_TRUE); } @Override diff --git a/java/src/com/google/template/soy/bididirectives/BUILD.bazel b/java/src/com/google/template/soy/bididirectives/BUILD.bazel index 3e850e2565..6cffde54cb 100644 --- a/java/src/com/google/template/soy/bididirectives/BUILD.bazel +++ b/java/src/com/google/template/soy/bididirectives/BUILD.bazel @@ -26,7 +26,9 @@ java_library( "//java/src/com/google/template/soy/data:unsafesanitizedcontentordainer", "//java/src/com/google/template/soy/internal/i18n", "//java/src/com/google/template/soy/jbcsrc/restricted", + "//java/src/com/google/template/soy/jssrc/dsl", "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/restricted:internal", "//java/src/com/google/template/soy/pysrc/restricted", "//java/src/com/google/template/soy/shared/restricted", "//java/src/com/google/template/soy/types", diff --git a/java/src/com/google/template/soy/bididirectives/BidiSpanWrapDirective.java b/java/src/com/google/template/soy/bididirectives/BidiSpanWrapDirective.java index 08145bf50d..3ea1dd3580 100644 --- a/java/src/com/google/template/soy/bididirectives/BidiSpanWrapDirective.java +++ b/java/src/com/google/template/soy/bididirectives/BidiSpanWrapDirective.java @@ -16,6 +16,7 @@ package com.google.template.soy.bididirectives; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.template.soy.data.LoggingAdvisingAppendable; import com.google.template.soy.data.SanitizedContent.ContentKind; @@ -28,8 +29,9 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expressions; import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.restricted.SoyJavaPrintDirective; @@ -46,14 +48,16 @@ final class BidiSpanWrapDirective implements SanitizedContentOperator, SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable { /** Supplier for the current bidi global directionality. */ private final Supplier bidiGlobalDirProvider; - /** @param bidiGlobalDirProvider Supplier for the current bidi global directionality. */ + /** + * @param bidiGlobalDirProvider Supplier for the current bidi global directionality. + */ BidiSpanWrapDirective(Supplier bidiGlobalDirProvider) { this.bidiGlobalDirProvider = bidiGlobalDirProvider; } @@ -109,15 +113,14 @@ public AppendableAndOptions applyForJbcSrcStreaming( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - String codeSnippet = bidiGlobalDirProvider.get().getCodeSnippet(); - return new JsExpr( - "soy.$$bidiSpanWrap(" + codeSnippet + ", " + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + com.google.template.soy.jssrc.dsl.Expression dir = + Expressions.fromExpr( + new JsExpr(bidiGlobalDirProvider.get().getCodeSnippet(), Integer.MAX_VALUE), + ImmutableList.of()); + return SOY.dotAccess("$$bidiSpanWrap").call(dir, value); } @Override diff --git a/java/src/com/google/template/soy/bididirectives/BidiUnicodeWrapDirective.java b/java/src/com/google/template/soy/bididirectives/BidiUnicodeWrapDirective.java index 945d11b36a..bd596f28da 100644 --- a/java/src/com/google/template/soy/bididirectives/BidiUnicodeWrapDirective.java +++ b/java/src/com/google/template/soy/bididirectives/BidiUnicodeWrapDirective.java @@ -16,6 +16,7 @@ package com.google.template.soy.bididirectives; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.template.soy.data.LoggingAdvisingAppendable; import com.google.template.soy.data.SoyValue; @@ -25,8 +26,9 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expressions; import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.restricted.SoyJavaPrintDirective; @@ -45,7 +47,7 @@ */ final class BidiUnicodeWrapDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable { @@ -101,15 +103,14 @@ public AppendableAndOptions applyForJbcSrcStreaming( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - String codeSnippet = bidiGlobalDirProvider.get().getCodeSnippet(); - return new JsExpr( - "soy.$$bidiUnicodeWrap(" + codeSnippet + ", " + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + com.google.template.soy.jssrc.dsl.Expression dir = + Expressions.fromExpr( + new JsExpr(bidiGlobalDirProvider.get().getCodeSnippet(), Integer.MAX_VALUE), + ImmutableList.of()); + return SOY.dotAccess("$$bidiUnicodeWrap").call(dir, value); } @Override diff --git a/java/src/com/google/template/soy/coredirectives/BUILD.bazel b/java/src/com/google/template/soy/coredirectives/BUILD.bazel index 247f24976d..3286ed6458 100644 --- a/java/src/com/google/template/soy/coredirectives/BUILD.bazel +++ b/java/src/com/google/template/soy/coredirectives/BUILD.bazel @@ -25,14 +25,15 @@ java_library( "//java/src/com/google/template/soy/data", "//java/src/com/google/template/soy/data:unsafesanitizedcontentordainer", "//java/src/com/google/template/soy/jbcsrc/restricted", - "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/dsl", + "//java/src/com/google/template/soy/jssrc/restricted:internal", "//java/src/com/google/template/soy/pysrc/restricted", "//java/src/com/google/template/soy/shared/internal:escaping_library", "//java/src/com/google/template/soy/shared/internal:short_circuitable", "//java/src/com/google/template/soy/shared/restricted", "//java/src/com/google/template/soy/types", + "@maven//:com_google_code_findbugs_jsr305", "@maven//:com_google_errorprone_error_prone_annotations", "@maven//:com_google_guava_guava", - "@maven//:com_google_code_findbugs_jsr305", ], ) diff --git a/java/src/com/google/template/soy/coredirectives/EscapeHtmlDirective.java b/java/src/com/google/template/soy/coredirectives/EscapeHtmlDirective.java index e514d110be..e086b279c3 100644 --- a/java/src/com/google/template/soy/coredirectives/EscapeHtmlDirective.java +++ b/java/src/com/google/template/soy/coredirectives/EscapeHtmlDirective.java @@ -26,8 +26,7 @@ import com.google.template.soy.jbcsrc.restricted.MethodRef; import com.google.template.soy.jbcsrc.restricted.SoyExpression; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.SoyPySrcPrintDirective; import com.google.template.soy.shared.internal.ShortCircuitable; @@ -41,7 +40,7 @@ @SoyPurePrintDirective public class EscapeHtmlDirective implements SoyJavaPrintDirective, - SoyLibraryAssistedJsSrcPrintDirective, + ModernSoyJsSrcPrintDirective, SoyPySrcPrintDirective, SoyJbcSrcPrintDirective.Streamable, ShortCircuitable { @@ -96,13 +95,10 @@ public AppendableAndOptions applyForJbcSrcStreaming( } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr("soy.$$escapeHtml(" + value.getText() + ")", Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("soy"); + public com.google.template.soy.jssrc.dsl.Expression applyForJsSrc( + com.google.template.soy.jssrc.dsl.Expression value, + List args) { + return SOY.dotAccess("$$escapeHtml").call(value); } @Override diff --git a/java/src/com/google/template/soy/incrementaldomsrc/BUILD.bazel b/java/src/com/google/template/soy/incrementaldomsrc/BUILD.bazel index c75fc59c72..c78abda8aa 100644 --- a/java/src/com/google/template/soy/incrementaldomsrc/BUILD.bazel +++ b/java/src/com/google/template/soy/incrementaldomsrc/BUILD.bazel @@ -52,6 +52,7 @@ java_library( "//java/src/com/google/template/soy/jssrc/dsl", "//java/src/com/google/template/soy/jssrc/internal", "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/restricted:internal", "//java/src/com/google/template/soy/logging:public", "//java/src/com/google/template/soy/passes", "//java/src/com/google/template/soy/shared/internal", diff --git a/java/src/com/google/template/soy/incrementaldomsrc/BidiUnicodeWrapDirective.java b/java/src/com/google/template/soy/incrementaldomsrc/BidiUnicodeWrapDirective.java index 75a0e16b2c..f8b20e9f0f 100644 --- a/java/src/com/google/template/soy/incrementaldomsrc/BidiUnicodeWrapDirective.java +++ b/java/src/com/google/template/soy/incrementaldomsrc/BidiUnicodeWrapDirective.java @@ -15,22 +15,27 @@ */ package com.google.template.soy.incrementaldomsrc; -import static com.google.template.soy.incrementaldomsrc.IncrementalDomRuntime.INCREMENTAL_DOM_PARAM_NAME; +import static com.google.template.soy.incrementaldomsrc.IncrementalDomRuntime.INCREMENTAL_DOM; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.template.soy.internal.i18n.BidiGlobalDir; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import java.util.List; import java.util.Set; /** Implements the |bidiUnicodeWrap directive for incremental dom only. */ -final class BidiUnicodeWrapDirective implements SoyLibraryAssistedJsSrcPrintDirective { +final class BidiUnicodeWrapDirective implements ModernSoyJsSrcPrintDirective { /** Supplier for the current bidi global directionality. */ private final BidiGlobalDir bidiGlobalDir; - /** @param bidiGlobalDir Current bidi global directionality. */ + /** + * @param bidiGlobalDir Current bidi global directionality. + */ BidiUnicodeWrapDirective(BidiGlobalDir bidiGlobalDir) { this.bidiGlobalDir = bidiGlobalDir; } @@ -57,19 +62,10 @@ public Set getValidArgsSizes() { } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr( - String.format( - "goog.module.get('%s').$$bidiUnicodeWrap(%s, %s, %s)", - "google3.javascript.template.soy.soyutils_directives", - bidiGlobalDir.getCodeSnippet(), - value.getText(), - INCREMENTAL_DOM_PARAM_NAME), - Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("google3.javascript.template.soy.soyutils_directives"); + public Expression applyForJsSrc(Expression value, List args) { + Expression dir = + Expressions.fromExpr( + new JsExpr(bidiGlobalDir.getCodeSnippet(), Integer.MAX_VALUE), ImmutableList.of()); + return SOYUTILS_DIRECTIVES.dotAccess("$$bidiUnicodeWrap").call(dir, value, INCREMENTAL_DOM); } } diff --git a/java/src/com/google/template/soy/incrementaldomsrc/EscapeHtmlDirective.java b/java/src/com/google/template/soy/incrementaldomsrc/EscapeHtmlDirective.java index f7f9fd524d..d8124f1cca 100644 --- a/java/src/com/google/template/soy/incrementaldomsrc/EscapeHtmlDirective.java +++ b/java/src/com/google/template/soy/incrementaldomsrc/EscapeHtmlDirective.java @@ -15,16 +15,16 @@ */ package com.google.template.soy.incrementaldomsrc; -import static com.google.template.soy.incrementaldomsrc.IncrementalDomRuntime.INCREMENTAL_DOM_PARAM_NAME; +import static com.google.template.soy.incrementaldomsrc.IncrementalDomRuntime.INCREMENTAL_DOM; import com.google.common.collect.ImmutableSet; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import java.util.List; import java.util.Set; /** Implements the |escapeHtml directive for incremental dom only. */ -final class EscapeHtmlDirective implements SoyLibraryAssistedJsSrcPrintDirective { +final class EscapeHtmlDirective implements ModernSoyJsSrcPrintDirective { /** * Gets the name of the Soy print directive. @@ -48,18 +48,7 @@ public Set getValidArgsSizes() { } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr( - String.format( - "goog.module.get('%s').$$escapeHtml(%s, %s)", - "google3.javascript.template.soy.soyutils_directives", - value.getText(), - INCREMENTAL_DOM_PARAM_NAME), - Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("google3.javascript.template.soy.soyutils_directives"); + public Expression applyForJsSrc(Expression value, List args) { + return SOYUTILS_DIRECTIVES.dotAccess("$$escapeHtml").call(value, INCREMENTAL_DOM); } } diff --git a/java/src/com/google/template/soy/incrementaldomsrc/FilterHtmlAttributesDirective.java b/java/src/com/google/template/soy/incrementaldomsrc/FilterHtmlAttributesDirective.java index 447085b67c..99db406e6e 100644 --- a/java/src/com/google/template/soy/incrementaldomsrc/FilterHtmlAttributesDirective.java +++ b/java/src/com/google/template/soy/incrementaldomsrc/FilterHtmlAttributesDirective.java @@ -16,13 +16,13 @@ package com.google.template.soy.incrementaldomsrc; import com.google.common.collect.ImmutableSet; -import com.google.template.soy.jssrc.restricted.JsExpr; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import java.util.List; import java.util.Set; /** Implements the |filterHtmlAttributes directive for incremental dom only. */ -final class FilterHtmlAttributesDirective implements SoyLibraryAssistedJsSrcPrintDirective { +final class FilterHtmlAttributesDirective implements ModernSoyJsSrcPrintDirective { /** * Gets the name of the Soy print directive. @@ -46,16 +46,7 @@ public Set getValidArgsSizes() { } @Override - public JsExpr applyForJsSrc(JsExpr value, List args) { - return new JsExpr( - String.format( - "goog.module.get('%s').$$filterHtmlAttributes(%s)", - "google3.javascript.template.soy.soyutils_directives", value.getText()), - Integer.MAX_VALUE); - } - - @Override - public ImmutableSet getRequiredJsLibNames() { - return ImmutableSet.of("google3.javascript.template.soy.soyutils_directives"); + public Expression applyForJsSrc(Expression value, List args) { + return SOYUTILS_DIRECTIVES.dotAccess("$$filterHtmlAttributes").call(value); } } diff --git a/java/src/com/google/template/soy/incrementaldomsrc/RemoveUnnecessaryEscapingDirectives.java b/java/src/com/google/template/soy/incrementaldomsrc/RemoveUnnecessaryEscapingDirectives.java index f8de676e0b..585c3ec7b8 100644 --- a/java/src/com/google/template/soy/incrementaldomsrc/RemoveUnnecessaryEscapingDirectives.java +++ b/java/src/com/google/template/soy/incrementaldomsrc/RemoveUnnecessaryEscapingDirectives.java @@ -25,7 +25,6 @@ import com.google.template.soy.data.SanitizedContentOperator; import com.google.template.soy.exprtree.ExprNode; import com.google.template.soy.internal.i18n.BidiGlobalDir; -import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; import com.google.template.soy.shared.restricted.SoyPrintDirective; import com.google.template.soy.soytree.CallNode; import com.google.template.soy.soytree.EscapingMode; @@ -53,7 +52,7 @@ */ final class RemoveUnnecessaryEscapingDirectives { - private final ImmutableMap directives; + private final ImmutableMap directives; private static final String BIDI_UNICODE_WRAP = "|bidiUnicodeWrap"; diff --git a/java/src/com/google/template/soy/internal/i18n/BidiGlobalDir.java b/java/src/com/google/template/soy/internal/i18n/BidiGlobalDir.java index 790a988391..c683ac4b9c 100644 --- a/java/src/com/google/template/soy/internal/i18n/BidiGlobalDir.java +++ b/java/src/com/google/template/soy/internal/i18n/BidiGlobalDir.java @@ -150,6 +150,7 @@ public int getStaticValue() { * or empty. */ public String getCodeSnippet() { + // TODO(jcg): Fork Python from JS and make JS version an Expression rather than a string. return codeSnippet; } diff --git a/java/src/com/google/template/soy/jssrc/internal/BUILD.bazel b/java/src/com/google/template/soy/jssrc/internal/BUILD.bazel index 97117b67b0..7e64debd6f 100644 --- a/java/src/com/google/template/soy/jssrc/internal/BUILD.bazel +++ b/java/src/com/google/template/soy/jssrc/internal/BUILD.bazel @@ -39,6 +39,7 @@ java_library( "//java/src/com/google/template/soy/jssrc", "//java/src/com/google/template/soy/jssrc/dsl", "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/restricted:internal", "//java/src/com/google/template/soy/logging:internal", "//java/src/com/google/template/soy/logging:public", "//java/src/com/google/template/soy/msgs", diff --git a/java/src/com/google/template/soy/jssrc/internal/GenCallCodeUtils.java b/java/src/com/google/template/soy/jssrc/internal/GenCallCodeUtils.java index 21249c8c2e..be8ef1cb69 100644 --- a/java/src/com/google/template/soy/jssrc/internal/GenCallCodeUtils.java +++ b/java/src/com/google/template/soy/jssrc/internal/GenCallCodeUtils.java @@ -42,6 +42,7 @@ import com.google.template.soy.jssrc.internal.GenJsCodeVisitor.ScopedJsTypeRegistry; import com.google.template.soy.jssrc.internal.GenJsExprsVisitor.GenJsExprsVisitorFactory; import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective; import com.google.template.soy.jssrc.restricted.SoyLibraryAssistedJsSrcPrintDirective; import com.google.template.soy.shared.restricted.SoyPrintDirective; @@ -61,9 +62,7 @@ import java.util.Map; import java.util.Optional; -/** - * Generates JS code for {call}s and {delcall}s. - */ +/** Generates JS code for {call}s and {delcall}s. */ public class GenCallCodeUtils { /** * Returns true if the given template has a positional signature where all explicit {@code @param} @@ -266,26 +265,32 @@ public static Expression applyEscapingDirectives(Expression call, CallNode callN // The print directive system continues to use JsExpr, as it is a publicly available API and // migrating it to CodeChunk would be a major change. Therefore, we convert our CodeChunks // to JsExpr and back here. - JsExpr callResult = call.singleExprOrName(FormatOptions.JSSRC); - ImmutableSet.Builder requiresBuilder = ImmutableSet.builder(); - call.collectRequires(requiresBuilder::add); for (SoyPrintDirective directive : callNode.getEscapingDirectives()) { - checkState( - directive instanceof SoyJsSrcPrintDirective, - "Contextual autoescaping produced a bogus directive: %s", - directive.getName()); - callResult = - ((SoyJsSrcPrintDirective) directive).applyForJsSrc(callResult, ImmutableList.of()); - if (directive instanceof SoyLibraryAssistedJsSrcPrintDirective) { - for (String name : - ((SoyLibraryAssistedJsSrcPrintDirective) directive).getRequiredJsLibNames()) { - requiresBuilder.add(GoogRequire.create(name)); + if (directive instanceof ModernSoyJsSrcPrintDirective) { + call = ((ModernSoyJsSrcPrintDirective) directive).applyForJsSrc(call, ImmutableList.of()); + } else if (directive instanceof SoyJsSrcPrintDirective) { + JsExpr callResult = call.singleExprOrName(FormatOptions.JSSRC); + ImmutableSet.Builder requiresBuilder = ImmutableSet.builder(); + call.collectRequires(requiresBuilder::add); + if (directive instanceof SoyLibraryAssistedJsSrcPrintDirective) { + for (String name : + ((SoyLibraryAssistedJsSrcPrintDirective) directive).getRequiredJsLibNames()) { + requiresBuilder.add(GoogRequire.create(name)); + } } + callResult = + ((SoyJsSrcPrintDirective) directive).applyForJsSrc(callResult, ImmutableList.of()); + call = + fromExpr(callResult, requiresBuilder.build()) + .withInitialStatements(call.allInitialStatementsInTopScope()); + } else { + throw new IllegalStateException( + String.format( + "Contextual autoescaping produced a bogus directive: %s", directive.getName())); } } - return fromExpr(callResult, requiresBuilder.build()) - .withInitialStatements(call.allInitialStatementsInTopScope()); + return call; } /** Represents a callable function symbol. */ diff --git a/java/src/com/google/template/soy/jssrc/internal/GenJsCodeVisitorAssistantForMsgs.java b/java/src/com/google/template/soy/jssrc/internal/GenJsCodeVisitorAssistantForMsgs.java index 6da97d310a..befb17d055 100644 --- a/java/src/com/google/template/soy/jssrc/internal/GenJsCodeVisitorAssistantForMsgs.java +++ b/java/src/com/google/template/soy/jssrc/internal/GenJsCodeVisitorAssistantForMsgs.java @@ -38,6 +38,7 @@ import com.google.template.soy.jssrc.dsl.Statement; import com.google.template.soy.jssrc.dsl.Statements; import com.google.template.soy.jssrc.dsl.VariableDeclaration; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective; import com.google.template.soy.msgs.internal.IcuSyntaxUtils; import com.google.template.soy.msgs.internal.MsgUtils; @@ -167,13 +168,18 @@ public Expression generateMsgGroupVariable(MsgFallbackGroupNode node) { } // handle escaping for (SoyPrintDirective printDirective : node.getEscapingDirectives()) { - msg = - SoyJsPluginUtils.applyDirective( - msg, - (SoyJsSrcPrintDirective) printDirective, - /* args= */ ImmutableList.of(), - node.getSourceLocation(), - errorReporter); + if (printDirective instanceof ModernSoyJsSrcPrintDirective) { + msg = + ((ModernSoyJsSrcPrintDirective) printDirective).applyForJsSrc(msg, ImmutableList.of()); + } else { + msg = + SoyJsPluginUtils.applyDirective( + msg, + (SoyJsSrcPrintDirective) printDirective, + /* args= */ ImmutableList.of(), + node.getSourceLocation(), + errorReporter); + } } return msg; } diff --git a/java/src/com/google/template/soy/jssrc/internal/GenJsExprsVisitor.java b/java/src/com/google/template/soy/jssrc/internal/GenJsExprsVisitor.java index 21802be5d4..75849f7e55 100644 --- a/java/src/com/google/template/soy/jssrc/internal/GenJsExprsVisitor.java +++ b/java/src/com/google/template/soy/jssrc/internal/GenJsExprsVisitor.java @@ -29,6 +29,7 @@ import com.google.template.soy.jssrc.dsl.Expressions; import com.google.template.soy.jssrc.dsl.SoyJsPluginUtils; import com.google.template.soy.jssrc.internal.GenJsCodeVisitor.ScopedJsTypeRegistry; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective; import com.google.template.soy.shared.restricted.SoyPrintDirective; import com.google.template.soy.soytree.AbstractSoyNodeVisitor; @@ -248,7 +249,8 @@ protected void visitPrintNode(PrintNode node) { // Get directive. SoyPrintDirective directive = directiveNode.getPrintDirective(); - if (!(directive instanceof SoyJsSrcPrintDirective)) { + if (!(directive instanceof SoyJsSrcPrintDirective + || directive instanceof ModernSoyJsSrcPrintDirective)) { errorReporter.report( node.getSourceLocation(), UNKNOWN_SOY_JS_SRC_PRINT_DIRECTIVE, directiveNode.getName()); return; @@ -263,14 +265,18 @@ protected void visitPrintNode(PrintNode node) { argChunks.add(translateExpr(argNode)); } - // Apply directive. - expr = - SoyJsPluginUtils.applyDirective( - expr, - (SoyJsSrcPrintDirective) directive, - argChunks, - node.getSourceLocation(), - errorReporter); + if (directive instanceof ModernSoyJsSrcPrintDirective) { + expr = ((ModernSoyJsSrcPrintDirective) directive).applyForJsSrc(expr, argChunks); + } else { + // Apply directive. + expr = + SoyJsPluginUtils.applyDirective( + expr, + (SoyJsSrcPrintDirective) directive, + argChunks, + node.getSourceLocation(), + errorReporter); + } } chunks.add(expr); diff --git a/java/src/com/google/template/soy/jssrc/restricted/BUILD.bazel b/java/src/com/google/template/soy/jssrc/restricted/BUILD.bazel index 9df0b59814..4d889137ad 100644 --- a/java/src/com/google/template/soy/jssrc/restricted/BUILD.bazel +++ b/java/src/com/google/template/soy/jssrc/restricted/BUILD.bazel @@ -18,9 +18,16 @@ load("@rules_java//java:defs.bzl", "java_library") package(default_visibility = ["//:soy_internal"]) +INTERNAL_SRC = [ + "ModernSoyJsSrcPrintDirective.java", +] + java_library( name = "restricted", - srcs = glob(["*.java"]), + srcs = glob( + ["*.java"], + exclude = INTERNAL_SRC, + ), visibility = ["//visibility:public"], deps = [ "//java/src/com/google/template/soy/base/internal", @@ -34,3 +41,12 @@ java_library( "@maven//:com_google_guava_guava", ], ) + +java_library( + name = "internal", + srcs = INTERNAL_SRC, + deps = [ + "//java/src/com/google/template/soy/jssrc/dsl", + "//java/src/com/google/template/soy/shared/restricted", + ], +) diff --git a/java/src/com/google/template/soy/jssrc/restricted/ModernSoyJsSrcPrintDirective.java b/java/src/com/google/template/soy/jssrc/restricted/ModernSoyJsSrcPrintDirective.java new file mode 100644 index 0000000000..897d24e30a --- /dev/null +++ b/java/src/com/google/template/soy/jssrc/restricted/ModernSoyJsSrcPrintDirective.java @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.template.soy.jssrc.restricted; + +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.GoogRequire; +import com.google.template.soy.shared.restricted.SoyPrintDirective; +import java.util.List; + +/** Internal version of {@link SoyJsSrcPrintDirective} that avoids {@link JsExpr}. */ +public interface ModernSoyJsSrcPrintDirective extends SoyPrintDirective { + GoogRequire SOY = GoogRequire.create("soy"); + + Expression SOYUTILS_DIRECTIVES = + GoogRequire.create("google3.javascript.template.soy.soyutils_directives").googModuleGet(); + + Expression applyForJsSrc(Expression value, List args); +} diff --git a/java/tests/com/google/template/soy/basicdirectives/BUILD.bazel b/java/tests/com/google/template/soy/basicdirectives/BUILD.bazel index 74dcb71cd4..fbbcb1dff1 100644 --- a/java/tests/com/google/template/soy/basicdirectives/BUILD.bazel +++ b/java/tests/com/google/template/soy/basicdirectives/BUILD.bazel @@ -30,7 +30,7 @@ java_library( "//java/src/com/google/template/soy/coredirectives", "//java/src/com/google/template/soy/data", "//java/src/com/google/template/soy/data:unsafesanitizedcontentordainer_testonly", - "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/dsl", "//java/src/com/google/template/soy/pysrc/restricted", "//java/src/com/google/template/soy/shared/internal:escaping_library", "//java/src/com/google/template/soy/shared/restricted:restricted_internal", diff --git a/java/tests/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirectiveTest.java b/java/tests/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirectiveTest.java index bb5b7ef250..0ee354a4aa 100644 --- a/java/tests/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirectiveTest.java +++ b/java/tests/com/google/template/soy/basicdirectives/ChangeNewlineToBrDirectiveTest.java @@ -19,16 +19,16 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Unit tests for ChangeNewlineToBrDirective. - */ +/** Unit tests for ChangeNewlineToBrDirective. */ @RunWith(JUnit4.class) public class ChangeNewlineToBrDirectiveTest extends AbstractSoyPrintDirectiveTestCase { @Test @@ -40,13 +40,15 @@ public void testApplyForTofu() { assertTofuOutput("a
b", "a\r\nb", directive); assertTofuOutput("abc
def
xyz", "abc\rdef\nxyz", directive); } + @Test public void testApplyForJsSrc() { ChangeNewlineToBrDirective directive = new ChangeNewlineToBrDirective(); - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); - assertThat(directive.applyForJsSrc(dataRef, ImmutableList.of()).getText()) - .isEqualTo("soy.$$changeNewlineToBr(opt_data.myKey)"); + Expression dataRef = Expressions.dottedIdNoRequire("opt_data.myKey"); + assertThat(directive.applyForJsSrc(dataRef, ImmutableList.of()).getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$changeNewlineToBr(opt_data.myKey);"); } + @Test public void testApplyForPySrc() { ChangeNewlineToBrDirective directive = new ChangeNewlineToBrDirective(); diff --git a/java/tests/com/google/template/soy/basicdirectives/CleanHtmlDirectiveTest.java b/java/tests/com/google/template/soy/basicdirectives/CleanHtmlDirectiveTest.java index ee3c7d850b..397fd73bdd 100644 --- a/java/tests/com/google/template/soy/basicdirectives/CleanHtmlDirectiveTest.java +++ b/java/tests/com/google/template/soy/basicdirectives/CleanHtmlDirectiveTest.java @@ -26,7 +26,9 @@ import com.google.template.soy.data.SanitizedContent.ContentKind; import com.google.template.soy.data.UnsafeSanitizedContentOrdainer; import com.google.template.soy.data.restricted.StringData; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.shared.internal.TagWhitelist.OptionalSafeTag; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; @@ -94,43 +96,45 @@ public void testApplyForTofu_optionalSafeTags() { @Test public void testApplyForJsSrc() { CleanHtmlDirective cleanHtml = new CleanHtmlDirective(); - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); - assertThat(cleanHtml.applyForJsSrc(dataRef, ImmutableList.of()).getText()) - .isEqualTo("soy.$$cleanHtml(opt_data.myKey)"); + Expression dataRef = Expressions.dottedIdNoRequire("opt_data.myKey"); + assertThat(cleanHtml.applyForJsSrc(dataRef, ImmutableList.of()).getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$cleanHtml(opt_data.myKey);"); } @Test public void testApplyForJsSrc_optionalSafeTags() { CleanHtmlDirective cleanHtml = new CleanHtmlDirective(); - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); + Expression dataRef = Expressions.dottedIdNoRequire("opt_data.myKey"); // All possible OptionalSafeTags. - ImmutableList optionalSafeTagsAsJsExprs = + ImmutableList optionalSafeTagsAsJsExprs = Arrays.stream(OptionalSafeTag.values()) .map(OptionalSafeTag::getTagName) - .map(input -> new JsExpr(String.format("'%s'", input), Integer.MAX_VALUE)) + .map(Expressions::stringLiteral) .collect(toImmutableList()); - assertThat(cleanHtml.applyForJsSrc(dataRef, optionalSafeTagsAsJsExprs).getText()) - .isEqualTo("soy.$$cleanHtml(opt_data.myKey, ['hr', 'li', 'ol', 'span', 'ul'])"); + assertThat( + cleanHtml + .applyForJsSrc(dataRef, optionalSafeTagsAsJsExprs) + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$cleanHtml(opt_data.myKey, ['hr', 'li', 'ol', 'span', 'ul']);"); // Only the specified optional safe tags are passed to $$cleanHtml. assertThat( cleanHtml - .applyForJsSrc(dataRef, ImmutableList.of(new JsExpr("'span'", Integer.MAX_VALUE))) - .getText()) - .isEqualTo("soy.$$cleanHtml(opt_data.myKey, ['span'])"); + .applyForJsSrc(dataRef, ImmutableList.of(Expressions.stringLiteral("span"))) + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$cleanHtml(opt_data.myKey, ['span']);"); // Invalid optional safe tags. try { - cleanHtml.applyForJsSrc( - dataRef, ImmutableList.of(new JsExpr("'unsupported'", Integer.MAX_VALUE))); + cleanHtml.applyForJsSrc(dataRef, ImmutableList.of(Expressions.stringLiteral("unsupported"))); fail(); } catch (IllegalArgumentException e) { // Test passes. } try { - cleanHtml.applyForJsSrc(dataRef, ImmutableList.of(new JsExpr("'li, ul'", Integer.MAX_VALUE))); + cleanHtml.applyForJsSrc(dataRef, ImmutableList.of(Expressions.stringLiteral("li, ul"))); fail(); } catch (IllegalArgumentException e) { // Test passes. @@ -139,16 +143,15 @@ public void testApplyForJsSrc_optionalSafeTags() { // Invalid parameter syntax. try { cleanHtml.applyForJsSrc( - dataRef, ImmutableList.of(new JsExpr("$myExtraSafeTags", Integer.MAX_VALUE))); + dataRef, ImmutableList.of(Expressions.stringLiteral("$myExtraSafeTags"))); fail(); } catch (IllegalArgumentException e) { assertThat(e) .hasMessageThat() - .isEqualTo( - "The cleanHtml directive expects arguments to be tag name string " - + "literals, such as 'span'. Encountered: $myExtraSafeTags"); + .isEqualTo("$myExtraSafeTags is not a valid optional safe tag."); } } + @Test public void testApplyForPySrc() { CleanHtmlDirective cleanHtml = new CleanHtmlDirective(); @@ -157,6 +160,7 @@ public void testApplyForPySrc() { assertThat(cleanHtml.applyForPySrc(data, ImmutableList.of()).getText()) .isEqualTo("sanitize.clean_html('data')"); } + @Test public void testApplyForPySrc_optionalSafeTags() { CleanHtmlDirective cleanHtml = new CleanHtmlDirective(); diff --git a/java/tests/com/google/template/soy/basicdirectives/FilterImageDataUriDirectiveTest.java b/java/tests/com/google/template/soy/basicdirectives/FilterImageDataUriDirectiveTest.java index d999d37fc1..7a8679a9be 100644 --- a/java/tests/com/google/template/soy/basicdirectives/FilterImageDataUriDirectiveTest.java +++ b/java/tests/com/google/template/soy/basicdirectives/FilterImageDataUriDirectiveTest.java @@ -22,7 +22,9 @@ import com.google.template.soy.data.SanitizedContent; import com.google.template.soy.data.SanitizedContent.ContentKind; import com.google.template.soy.data.UnsafeSanitizedContentOrdainer; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; import org.junit.Test; @@ -40,13 +42,15 @@ public void testApplyForTofu() { sanitizedUri("data:image/png;base64,abc="), "data:image/png;base64,abc=", directive); assertTofuOutput(sanitizedUri("data:image/gif;base64,zSoyz"), "not really valid", directive); } + @Test public void testApplyForJsSrc() { FilterImageDataUriDirective cleanHtml = new FilterImageDataUriDirective(); - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); - assertThat(cleanHtml.applyForJsSrc(dataRef, ImmutableList.of()).getText()) - .isEqualTo("soy.$$filterImageDataUri(opt_data.myKey)"); + Expression dataRef = Expressions.dottedIdNoRequire("opt_data.myKey"); + assertThat(cleanHtml.applyForJsSrc(dataRef, ImmutableList.of()).getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$filterImageDataUri(opt_data.myKey);"); } + @Test public void testApplyForPySrc() { FilterImageDataUriDirective cleanHtml = new FilterImageDataUriDirective(); diff --git a/java/tests/com/google/template/soy/basicdirectives/InsertWordBreaksDirectiveTest.java b/java/tests/com/google/template/soy/basicdirectives/InsertWordBreaksDirectiveTest.java index a59d2f8579..bc5fd5fe0e 100644 --- a/java/tests/com/google/template/soy/basicdirectives/InsertWordBreaksDirectiveTest.java +++ b/java/tests/com/google/template/soy/basicdirectives/InsertWordBreaksDirectiveTest.java @@ -19,15 +19,15 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Unit tests for InsertWordBreaksDirective. - */ +/** Unit tests for InsertWordBreaksDirective. */ @RunWith(JUnit4.class) public class InsertWordBreaksDirectiveTest extends AbstractSoyPrintDirectiveTestCase { @Test @@ -47,13 +47,16 @@ public void testApplyForTofu() { insertWordBreaksDirective, maxCharsBetweenBreaks); } + @Test public void testApplyForJsSrc() { - InsertWordBreaksDirective insertWordBreaksDirective = new InsertWordBreaksDirective(); - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); - JsExpr arg = new JsExpr("8", Integer.MAX_VALUE); - assertThat(insertWordBreaksDirective.applyForJsSrc(dataRef, ImmutableList.of(arg)).getText()) - .isEqualTo("soy.$$insertWordBreaks(opt_data.myKey, 8)"); + Expression dataRef = Expressions.dottedIdNoRequire("opt_data.myKey"); + Expression arg = Expressions.number(8); + assertThat( + insertWordBreaksDirective + .applyForJsSrc(dataRef, ImmutableList.of(arg)) + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$insertWordBreaks(opt_data.myKey, 8);"); } } diff --git a/java/tests/com/google/template/soy/basicdirectives/TextDirectiveTest.java b/java/tests/com/google/template/soy/basicdirectives/TextDirectiveTest.java index 697088d924..cc8d55866a 100644 --- a/java/tests/com/google/template/soy/basicdirectives/TextDirectiveTest.java +++ b/java/tests/com/google/template/soy/basicdirectives/TextDirectiveTest.java @@ -22,7 +22,9 @@ import com.google.template.soy.data.SanitizedContent; import com.google.template.soy.data.UnsafeSanitizedContentOrdainer; import com.google.template.soy.data.restricted.IntegerData; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.PyStringExpr; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; @@ -30,9 +32,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Unit tests for TextDirective. - */ +/** Unit tests for TextDirective. */ @RunWith(JUnit4.class) public class TextDirectiveTest extends AbstractSoyPrintDirectiveTestCase { @Test @@ -49,13 +49,15 @@ public void testApplyForTofu() { textDirective); assertTofuOutput(IntegerData.forValue(123), IntegerData.forValue(123), textDirective); } + @Test public void testApplyForJsSrc() { TextDirective textDirective = new TextDirective(); - JsExpr jsExpr = new JsExpr("whatever", Integer.MAX_VALUE); - assertThat(textDirective.applyForJsSrc(jsExpr, ImmutableList.of()).getText()) - .isEqualTo("'' + whatever"); + Expression jsExpr = Expressions.id("whatever"); + assertThat(textDirective.applyForJsSrc(jsExpr, ImmutableList.of()).getCode(FormatOptions.JSSRC)) + .isEqualTo("String(whatever);"); } + @Test public void testApplyForPySrc() { TextDirective textDirective = new TextDirective(); diff --git a/java/tests/com/google/template/soy/basicdirectives/TruncateDirectiveTest.java b/java/tests/com/google/template/soy/basicdirectives/TruncateDirectiveTest.java index de6cbfeff3..095916a29c 100644 --- a/java/tests/com/google/template/soy/basicdirectives/TruncateDirectiveTest.java +++ b/java/tests/com/google/template/soy/basicdirectives/TruncateDirectiveTest.java @@ -19,7 +19,9 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.collect.ImmutableList; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.PyStringExpr; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; @@ -58,25 +60,25 @@ public void testApplyForTofu() { public void testApplyForJsSrc() { TruncateDirective truncateDirective = new TruncateDirective(); - JsExpr dataRefJsExpr = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); - JsExpr maxLenJsExpr = new JsExpr("8", Integer.MAX_VALUE); - JsExpr trueJsExpr = new JsExpr("true", Integer.MAX_VALUE); - JsExpr falseJsExpr = new JsExpr("false", Integer.MAX_VALUE); + Expression dataRefJsExpr = Expressions.dottedIdNoRequire("opt_data.myKey"); + Expression maxLenJsExpr = Expressions.number(8); + Expression trueJsExpr = Expressions.LITERAL_TRUE; + Expression falseJsExpr = Expressions.LITERAL_FALSE; assertThat( truncateDirective .applyForJsSrc(dataRefJsExpr, ImmutableList.of(maxLenJsExpr)) - .getText()) - .isEqualTo("soy.$$truncate(opt_data.myKey, 8, true)"); + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$truncate(opt_data.myKey, 8, true);"); assertThat( truncateDirective .applyForJsSrc(dataRefJsExpr, ImmutableList.of(maxLenJsExpr, trueJsExpr)) - .getText()) - .isEqualTo("soy.$$truncate(opt_data.myKey, 8, true)"); + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$truncate(opt_data.myKey, 8, true);"); assertThat( truncateDirective .applyForJsSrc(dataRefJsExpr, ImmutableList.of(maxLenJsExpr, falseJsExpr)) - .getText()) - .isEqualTo("soy.$$truncate(opt_data.myKey, 8, false)"); + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$truncate(opt_data.myKey, 8, false);"); } @Test public void testApplyForPySrc() { diff --git a/java/tests/com/google/template/soy/bididirectives/BUILD.bazel b/java/tests/com/google/template/soy/bididirectives/BUILD.bazel index 855fcca88a..2a841d2768 100644 --- a/java/tests/com/google/template/soy/bididirectives/BUILD.bazel +++ b/java/tests/com/google/template/soy/bididirectives/BUILD.bazel @@ -31,7 +31,7 @@ java_library( "//java/src/com/google/template/soy/data", "//java/src/com/google/template/soy/data:unsafesanitizedcontentordainer", "//java/src/com/google/template/soy/internal/i18n", - "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/dsl", "//java/src/com/google/template/soy/pysrc/restricted", "//java/src/com/google/template/soy/testing:abstract_soy_print_directive_test_case", "@maven//:com_google_guava_guava", diff --git a/java/tests/com/google/template/soy/bididirectives/BidiSpanWrapDirectiveTest.java b/java/tests/com/google/template/soy/bididirectives/BidiSpanWrapDirectiveTest.java index 976712eba2..c448f33cec 100644 --- a/java/tests/com/google/template/soy/bididirectives/BidiSpanWrapDirectiveTest.java +++ b/java/tests/com/google/template/soy/bididirectives/BidiSpanWrapDirectiveTest.java @@ -25,7 +25,9 @@ import com.google.template.soy.data.UnsafeSanitizedContentOrdainer; import com.google.template.soy.data.restricted.StringData; import com.google.template.soy.internal.i18n.BidiGlobalDir; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.PyStringExpr; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; @@ -33,9 +35,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Unit tests for BidiSpanWrapDirective. - */ +/** Unit tests for BidiSpanWrapDirective. */ @RunWith(JUnit4.class) public class BidiSpanWrapDirectiveTest extends AbstractSoyPrintDirectiveTestCase { @@ -102,22 +102,22 @@ public void testApplyForTofu() { @Test public void testApplyForJsSrc() { - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); + Expression dataRef = Expressions.dottedIdNoRequire("opt_data.myKey"); assertThat( BIDI_SPAN_WRAP_DIRECTIVE_FOR_STATIC_LTR .applyForJsSrc(dataRef, ImmutableList.of()) - .getText()) - .isEqualTo("soy.$$bidiSpanWrap(1, opt_data.myKey)"); + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$bidiSpanWrap(1, opt_data.myKey);"); assertThat( BIDI_SPAN_WRAP_DIRECTIVE_FOR_STATIC_RTL .applyForJsSrc(dataRef, ImmutableList.of()) - .getText()) - .isEqualTo("soy.$$bidiSpanWrap(-1, opt_data.myKey)"); + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$bidiSpanWrap(-1, opt_data.myKey);"); BidiSpanWrapDirective codeSnippet = new BidiSpanWrapDirective(BidiTestUtils.BIDI_GLOBAL_DIR_FOR_JS_ISRTL_CODE_SNIPPET_SUPPLIER); - assertThat(codeSnippet.applyForJsSrc(dataRef, ImmutableList.of()).getText()) - .isEqualTo("soy.$$bidiSpanWrap(IS_RTL?-1:1, opt_data.myKey)"); + assertThat(codeSnippet.applyForJsSrc(dataRef, ImmutableList.of()).getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$bidiSpanWrap(IS_RTL?-1:1, opt_data.myKey);"); } @Test diff --git a/java/tests/com/google/template/soy/bididirectives/BidiUnicodeWrapDirectiveTest.java b/java/tests/com/google/template/soy/bididirectives/BidiUnicodeWrapDirectiveTest.java index 21aa46bdaa..e40024eee7 100644 --- a/java/tests/com/google/template/soy/bididirectives/BidiUnicodeWrapDirectiveTest.java +++ b/java/tests/com/google/template/soy/bididirectives/BidiUnicodeWrapDirectiveTest.java @@ -25,7 +25,9 @@ import com.google.template.soy.data.UnsafeSanitizedContentOrdainer; import com.google.template.soy.data.restricted.StringData; import com.google.template.soy.internal.i18n.BidiGlobalDir; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expression; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.pysrc.restricted.PyStringExpr; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; @@ -33,9 +35,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Unit tests for BidiUnicodeWrapDirective. - */ +/** Unit tests for BidiUnicodeWrapDirective. */ @RunWith(JUnit4.class) public class BidiUnicodeWrapDirectiveTest extends AbstractSoyPrintDirectiveTestCase { @@ -101,23 +101,23 @@ public void testApplyForTofu() { @Test public void testApplyForJsSrc() { - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); + Expression dataRef = Expressions.dottedIdNoRequire("opt_data.myKey"); assertThat( BIDI_UNICODE_WRAP_DIRECTIVE_FOR_STATIC_LTR .applyForJsSrc(dataRef, ImmutableList.of()) - .getText()) - .isEqualTo("soy.$$bidiUnicodeWrap(1, opt_data.myKey)"); + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$bidiUnicodeWrap(1, opt_data.myKey);"); assertThat( BIDI_UNICODE_WRAP_DIRECTIVE_FOR_STATIC_RTL .applyForJsSrc(dataRef, ImmutableList.of()) - .getText()) - .isEqualTo("soy.$$bidiUnicodeWrap(-1, opt_data.myKey)"); + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$bidiUnicodeWrap(-1, opt_data.myKey);"); BidiUnicodeWrapDirective codeSnippet = new BidiUnicodeWrapDirective( BidiTestUtils.BIDI_GLOBAL_DIR_FOR_JS_ISRTL_CODE_SNIPPET_SUPPLIER); - assertThat(codeSnippet.applyForJsSrc(dataRef, ImmutableList.of()).getText()) - .isEqualTo("soy.$$bidiUnicodeWrap(IS_RTL?-1:1, opt_data.myKey)"); + assertThat(codeSnippet.applyForJsSrc(dataRef, ImmutableList.of()).getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$bidiUnicodeWrap(IS_RTL?-1:1, opt_data.myKey);"); } @Test diff --git a/java/tests/com/google/template/soy/coredirectives/BUILD.bazel b/java/tests/com/google/template/soy/coredirectives/BUILD.bazel index 1dd541096f..c37952f0a0 100644 --- a/java/tests/com/google/template/soy/coredirectives/BUILD.bazel +++ b/java/tests/com/google/template/soy/coredirectives/BUILD.bazel @@ -29,7 +29,7 @@ java_library( "//java/src/com/google/template/soy/coredirectives", "//java/src/com/google/template/soy/data", "//java/src/com/google/template/soy/data:unsafesanitizedcontentordainer_testonly", - "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/dsl", "//java/src/com/google/template/soy/pysrc/restricted", "//java/src/com/google/template/soy/testing:abstract_soy_print_directive_test_case", "@maven//:com_google_guava_guava", diff --git a/java/tests/com/google/template/soy/coredirectives/EscapeHtmlDirectiveTest.java b/java/tests/com/google/template/soy/coredirectives/EscapeHtmlDirectiveTest.java index 76f1d87da9..5022d959a1 100644 --- a/java/tests/com/google/template/soy/coredirectives/EscapeHtmlDirectiveTest.java +++ b/java/tests/com/google/template/soy/coredirectives/EscapeHtmlDirectiveTest.java @@ -21,16 +21,15 @@ import com.google.common.collect.ImmutableList; import com.google.template.soy.data.SanitizedContent; import com.google.template.soy.data.UnsafeSanitizedContentOrdainer; -import com.google.template.soy.jssrc.restricted.JsExpr; +import com.google.template.soy.jssrc.dsl.Expressions; +import com.google.template.soy.jssrc.dsl.FormatOptions; import com.google.template.soy.pysrc.restricted.PyExpr; import com.google.template.soy.testing.AbstractSoyPrintDirectiveTestCase; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Unit tests for EscapeHtmlDirective. - */ +/** Unit tests for EscapeHtmlDirective. */ @RunWith(JUnit4.class) public class EscapeHtmlDirectiveTest extends AbstractSoyPrintDirectiveTestCase { @@ -66,9 +65,11 @@ public void testApplyForTofu() { @Test public void testApplyForJsSrc() { EscapeHtmlDirective escapeHtmlDirective = new EscapeHtmlDirective(); - JsExpr dataRef = new JsExpr("opt_data.myKey", Integer.MAX_VALUE); - assertThat(escapeHtmlDirective.applyForJsSrc(dataRef, ImmutableList.of()).getText()) - .isEqualTo("soy.$$escapeHtml(opt_data.myKey)"); + assertThat( + escapeHtmlDirective + .applyForJsSrc(Expressions.dottedIdNoRequire("opt_data.myKey"), ImmutableList.of()) + .getCode(FormatOptions.JSSRC)) + .isEqualTo("soy.$$escapeHtml(opt_data.myKey);"); } @Test diff --git a/java/tests/com/google/template/soy/shared/internal/BUILD.bazel b/java/tests/com/google/template/soy/shared/internal/BUILD.bazel index 6d607877db..a8c691dce6 100644 --- a/java/tests/com/google/template/soy/shared/internal/BUILD.bazel +++ b/java/tests/com/google/template/soy/shared/internal/BUILD.bazel @@ -34,6 +34,7 @@ java_library( "//java/src/com/google/template/soy/exprtree", "//java/src/com/google/template/soy/jbcsrc/restricted", "//java/src/com/google/template/soy/jssrc/restricted", + "//java/src/com/google/template/soy/jssrc/restricted:internal", "//java/src/com/google/template/soy/plugin/java/restricted", "//java/src/com/google/template/soy/plugin/javascript/restricted", "//java/src/com/google/template/soy/plugin/python/restricted", diff --git a/java/tests/com/google/template/soy/shared/internal/InternalPluginsTest.java b/java/tests/com/google/template/soy/shared/internal/InternalPluginsTest.java index 47d2d35592..c370177380 100644 --- a/java/tests/com/google/template/soy/shared/internal/InternalPluginsTest.java +++ b/java/tests/com/google/template/soy/shared/internal/InternalPluginsTest.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableSet; import com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective; +import com.google.template.soy.jssrc.restricted.ModernSoyJsSrcPrintDirective; import com.google.template.soy.jssrc.restricted.SoyJsSrcFunction; import com.google.template.soy.jssrc.restricted.SoyJsSrcPrintDirective; import com.google.template.soy.plugin.java.restricted.SoyJavaSourceFunction; @@ -43,7 +44,10 @@ public final class InternalPluginsTest { public void testBuiltinPluginsSupportAllBackends() throws Exception { for (SoyPrintDirective directive : InternalPlugins.internalDirectives(NoOpScopedData.INSTANCE)) { - assertThat(directive).isInstanceOf(SoyJsSrcPrintDirective.class); + assertThat( + directive instanceof SoyJsSrcPrintDirective + || directive instanceof ModernSoyJsSrcPrintDirective) + .isTrue(); assertThat(directive).isInstanceOf(SoyJavaPrintDirective.class); assertThat(directive).isInstanceOf(SoyJbcSrcPrintDirective.class); assertThat(directive).isInstanceOf(SoyPySrcPrintDirective.class);