brandonbloom / fipp

Fast Idiomatic Pretty Printer for Clojure
525 stars 44 forks source link

a strange case in generating regex with slashes, related to ClojureScript #77

Closed tiye closed 3 years ago

tiye commented 3 years ago

I had some code generated with fipp, there was a regular expression:

#"\w+\/\w+"

which later generated js code, but I got an error running the regex:

clojure.string.replace(k,/\w+\\/\w+/,"~/")
//                             ^ this slash causes error
=>> node
Welcome to Node.js v14.7.0.
Type ".help" for more information.
> /\w+\\/\w+/
/\w+\\/\w+/
^

Uncaught SyntaxError: Invalid regular expression flags
>

I looked into my own code and tried. Turn out I have expression:

[["println" "#\"\\w+/\\w+"]]

which used a regex like this:

(println #"\w+\/\w+")

it turned out to be a valid Clojure regex, no matter if I use \/ or /:

user=> (re-matches #"\w+\/\w+" "a/a")
;                       ^^
"a/a"
user=> (re-matches #"\w+/\w+" "a/a")
;                       ^
"a/a"

However it brings syntax error in generated js. I'm not sure whether this is a fipp issue of a ClojureScript issue? Will FIPP handle this for ClojureScript?

brandonbloom commented 3 years ago

Fipp delegates to pr-str for printing regexes. See https://github.com/brandonbloom/fipp/blob/3e29a69cd7b93310441efa1de66c98459384ee9c/src/fipp/edn.cljc#L88

I'm not sure I understand the details of your bug report. Could you please clarify? For instance, here's what I see in Planck:

cljs.user=> (.toString (fn [] #"\/"))
"function (){\nreturn /\\//;\n}"
cljs.user=> (.toString (fn [] #"/"))
"function (){\nreturn /\\//;\n}"

That seems right to me...

When exactly does the broken code get generated? In the printed output of Fipp? Could you please provide a minimal reproduction of that?

tiye commented 3 years ago
> (fipp/pprint (re-pattern "\\w+/\\w+"))
#"\w+\/\w+"
;    ^^
nil
> (fipp/pprint #"\w+/\w+")
#"\w+\/\w+"
;    ^^
nil

however #"\w+/\w+" was expected.

> (re-matches #"\w+\/\w+" "a/a")
#object[SyntaxError SyntaxError: Invalid regular expression flags]
> (re-matches #"\w+/\w+" "a/a")
"a/a"

I was trying with shadow-cljs' cljs-repl.

tiye commented 3 years ago

barely pr-str behavoir?

> (println (pr-str #"\w+/\w+"))
#"\w+\/\w+"

😅

brandonbloom commented 3 years ago

This looks like a ClojureScript issue on V8 (or maybe just Node, I haven't tried in a browser).

shadow cljs Node repl:

cljs.user=> (re-matches #"\w+\/\w+" "a/a")
#object[SyntaxError SyntaxError: Invalid regular expression flags]

planck repl (which uses JavaScript Core, I believe):

cljs.user=> (re-matches #"\w+\/\w+" "a/a")
"a/a"

Feel free to re-open if I've missed something, but I think this needs to be fixed upstream.

tiye commented 3 years ago

the code generated by shadow-cljs is/^\\/\w+\\/\w+\\//, which throws syntax error in Safari as well. Planck is using Bootstrapped cljs, that might make differences.