2020import static com .google .common .base .Preconditions .checkState ;
2121
2222import com .google .common .annotations .VisibleForTesting ;
23+ import com .google .common .collect .Streams ;
2324import com .google .javascript .jscomp .NodeTraversal .AbstractPostOrderCallback ;
2425import com .google .javascript .rhino .Node ;
2526
@@ -107,6 +108,7 @@ public void visit(NodeTraversal traversal, Node node, Node parent) {
107108 *
108109 * <ol>
109110 * <li>The argument is a constant variable assigned from a string literal, or
111+ * <li>The argument is a template into which only string literals are inserted, or
110112 * <li>The argument is an expression that is a string literal, or
111113 * <li>The argument is a ternary expression choosing between string literals, or
112114 * <li>The argument is a concatenation of the above.
@@ -118,6 +120,13 @@ public void visit(NodeTraversal traversal, Node node, Node parent) {
118120 private boolean isSafeValue (Scope scope , Node argument ) {
119121 if (NodeUtil .isSomeCompileTimeConstStringValue (argument )) {
120122 return true ;
123+ } else if (argument .isTemplateLit ()) {
124+ // Each templateLit child is either a TemplateLitString, or has children which are substituted
125+ return Streams .stream (argument .children ())
126+ .filter (node -> !node .isTemplateLitString ())
127+ .map (Node ::children )
128+ .flatMap (Streams ::stream )
129+ .allMatch (node -> isSafeValue (scope , node ));
121130 } else if (argument .isAdd ()) {
122131 Node left = argument .getFirstChild ();
123132 Node right = argument .getLastChild ();
0 commit comments