20
20
import static com .google .common .base .Preconditions .checkState ;
21
21
22
22
import com .google .common .annotations .VisibleForTesting ;
23
+ import com .google .common .collect .Streams ;
23
24
import com .google .javascript .jscomp .NodeTraversal .AbstractPostOrderCallback ;
24
25
import com .google .javascript .rhino .Node ;
25
26
@@ -107,6 +108,7 @@ public void visit(NodeTraversal traversal, Node node, Node parent) {
107
108
*
108
109
* <ol>
109
110
* <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
110
112
* <li>The argument is an expression that is a string literal, or
111
113
* <li>The argument is a ternary expression choosing between string literals, or
112
114
* <li>The argument is a concatenation of the above.
@@ -118,6 +120,13 @@ public void visit(NodeTraversal traversal, Node node, Node parent) {
118
120
private boolean isSafeValue (Scope scope , Node argument ) {
119
121
if (NodeUtil .isSomeCompileTimeConstStringValue (argument )) {
120
122
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 ));
121
130
} else if (argument .isAdd ()) {
122
131
Node left = argument .getFirstChild ();
123
132
Node right = argument .getLastChild ();
0 commit comments