File tree Expand file tree Collapse file tree 5 files changed +57
-16
lines changed
cljs_build/cljs_3452_str_optimizations Expand file tree Collapse file tree 5 files changed +57
-16
lines changed Original file line number Diff line number Diff line change @@ -3110,7 +3110,7 @@ reduces them without incurring seq initialization"
31103110 ([] " " )
31113111 ([x] (if (nil? x)
31123112 " "
3113- (.join #js [x] " " )))
3113+ (.toString x )))
31143114 ([x & ys]
31153115 (loop [sb (StringBuffer. (str x)) more ys]
31163116 (if more
Original file line number Diff line number Diff line change 866866 (apply core/str))]
867867 (string-expr (list* 'js* (core/str " [" strs " ].join('')" ) x ys)))))
868868
869+ (core/defn- compile-time-constant? [x]
870+ (core/or
871+ (core/string? x)
872+ (core/keyword? x)
873+ (core/boolean? x)
874+ (core/number? x)))
875+
869876; ; TODO: should probably be a compiler pass to avoid the code duplication
870877(core/defmacro str
871- ([] " " )
872- ([x]
873- (if (typed-expr? &env x '#{string})
874- x
875- (string-expr (core/list 'js* " cljs.core.str.cljs$core$IFn$_invoke$arity$1(~{})" x))))
876- ([x & ys]
877- (core/let [interpolate (core/fn [x]
878- (if (typed-expr? &env x '#{string clj-nil})
879- " ~{}"
880- " cljs.core.str.cljs$core$IFn$_invoke$arity$1(~{})" ))
881- strs (core/->> (core/list* x ys)
882- (map interpolate)
883- (interpose " ," )
884- (apply core/str))]
885- (string-expr (list* 'js* (core/str " [" strs " ].join('')" ) x ys)))))
878+ [& xs]
879+ (core/let [interpolate (core/fn [x]
880+ (core/cond
881+ (typed-expr? &env x '#{clj-nil})
882+ nil
883+ (compile-time-constant? x)
884+ [" +~{}" x]
885+ :else
886+ ; ; Note: can't assume non-nil despite tag here, so we go through str 1-arity
887+ [" +cljs.core.str.cljs$core$IFn$_invoke$arity$1(~{})" x]))
888+ strs+args (keep interpolate xs)
889+ strs (string/join (map first strs+args))
890+ args (map second strs+args)]
891+ (string-expr (list* 'js* (core/str " (\"\" " strs " )" ) args))))
886892
887893(core/defn- bool-expr [e]
888894 (vary-meta e assoc :tag 'boolean))
Original file line number Diff line number Diff line change 19571957 (is (= " 1two:threefour#{:five}[:six]#{:seven}{:eight :nine}"
19581958 (apply cljs.core/str_ 1 [" two" :three 'four #{:five } [:six ] #{:seven } {:eight :nine }])))
19591959 (is (= " 1234" (apply cljs.core/str_ 1 2 [3 4 ]))))
1960+
1961+ (deftest test-cljs-3452
1962+ (let [obj #js {:valueOf (fn [] " dude" )
1963+ :toString (fn [] " correct" )}
1964+ str-fn (fn [x y]
1965+ (str x obj y " \" foobar\" " 1 :foo nil ))]
1966+ (testing " object is stringified using toString"
1967+ (is (= " correct6\" foobar\" 1:foo" (str-fn nil (+ 1 2 3 )))))))
Original file line number Diff line number Diff line change 1+ (ns cljs-3452-str-optimizations.core )
2+
3+ (defn my-str-fn [x y]
4+ (str x y nil ::foobar " my
5+
6+ multiline
7+
8+ string with `backticks`"
9+ true false 3.14 ))
Original file line number Diff line number Diff line change 940940 (.delete (io/file " package.json" ))
941941 (test/delete-node-modules )
942942 (test/delete-out-files out))))
943+
944+ (deftest test-cljs-3452-str-optimizations
945+ (testing " Test that uses compile time optimizations from str macro"
946+ (let [out (.getPath (io/file (test/tmp-dir ) " cljs-3452-str-optimizations-out" ))]
947+ (test/delete-out-files out)
948+ (let [{:keys [inputs opts]} {:inputs (str (io/file " src" " test" " cljs_build" ))
949+ :opts {:main 'cljs-3452-str-optimizations.core
950+ :output-dir out
951+ :optimizations :none
952+ :closure-warnings {:check-types :off }}}
953+ cenv (env/default-compiler-env )]
954+ (build/build (build/inputs (io/file inputs " cljs_3452_str_optimizations/core.cljs" )) opts cenv))
955+ (let [source (slurp (io/file out " cljs_3452_str_optimizations/core.js" ))]
956+ (testing " only seven string concats, compile time nil is ignored"
957+ (is (= 7 (count (re-seq #"[\+ ]" source)))))
958+ (testing " only two 1-arity str calls, compile time constants are optimized"
959+ (is (= 2 (count (re-seq #"\$ 1\( .*?\) " source))))))
960+ (test/delete-out-files out))))
You can’t perform that action at this time.
0 commit comments