Skip to content

Commit 17c486d

Browse files
fixes purescript#2172: allow escape seqs in JS FFI exported using strings
1 parent de8ab59 commit 17c486d

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

examples/passing/2172.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
exports['a\''] = 0;
2+
exports["\x62\x27"] = 1;
3+
// NOTE: I wanted to use "\c'" here, but langauge-javascript doesn't support it...
4+
exports["c'"] = 2;
5+
exports["\u0064\u0027"] = 3;

examples/passing/2172.purs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Main where
2+
3+
import Control.Monad.Eff.Console (log)
4+
5+
foreign import a' :: Number
6+
foreign import b' :: Number
7+
foreign import c' :: Number
8+
foreign import d' :: Number
9+
10+
main = log "Done"

purescript.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ author: Phil Freeman <paf31@cantab.net>,
2020
tested-with: GHC==7.10.3
2121

2222
extra-source-files: examples/passing/*.purs
23+
, examples/passing/*.js
2324
, examples/passing/2018/*.purs
2425
, examples/passing/2138/*.purs
2526
, examples/passing/ClassRefSyntax/*.purs

src/Language/PureScript/Bundle.hs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Prelude.Compat
1919
import Control.Monad
2020
import Control.Monad.Error.Class
2121

22+
import Data.Char (chr, digitToInt)
2223
import Data.Generics (everything, everywhere, mkQ, mkT)
2324
import Data.Graph
2425
import Data.List (nub, stripPrefix)
@@ -186,11 +187,34 @@ withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
186187

187188
-- String literals include the quote chars
188189
fromStringLiteral :: JSExpression -> Maybe String
189-
fromStringLiteral (JSStringLiteral _ str) = Just $ trimStringQuotes str
190+
fromStringLiteral (JSStringLiteral _ str) = Just $ strValue str
190191
fromStringLiteral _ = Nothing
191192

192-
trimStringQuotes :: String -> String
193-
trimStringQuotes str = reverse $ drop 1 $ reverse $ drop 1 $ str
193+
strValue :: String -> String
194+
strValue str = go $ drop 1 str
195+
where
196+
go ('\\' : 'b' : xs) = '\b' : go xs
197+
go ('\\' : 'f' : xs) = '\f' : go xs
198+
go ('\\' : 'n' : xs) = '\n' : go xs
199+
go ('\\' : 'r' : xs) = '\r' : go xs
200+
go ('\\' : 't' : xs) = '\t' : go xs
201+
go ('\\' : 'v' : xs) = '\v' : go xs
202+
go ('\\' : '0' : xs) = '\0' : go xs
203+
go ('\\' : 'x' : a : b : xs) = chr (a' + b') : go xs
204+
where
205+
a' = 16 * digitToInt a
206+
b' = digitToInt b
207+
go ('\\' : 'u' : a : b : c : d : xs) = chr (a' + b' + c' + d') : go xs
208+
where
209+
a' = 16 * 16 * 16 * digitToInt a
210+
b' = 16 * 16 * digitToInt b
211+
c' = 16 * digitToInt c
212+
d' = digitToInt d
213+
go ('\\' : x : xs) = x : go xs
214+
go "\"" = ""
215+
go "'" = ""
216+
go (x : xs) = x : go xs
217+
go "" = ""
194218

195219
commaList :: JSCommaList a -> [a]
196220
commaList JSLNil = []
@@ -332,7 +356,7 @@ matchExportsAssignment stmt
332356
= Nothing
333357

334358
extractLabel :: JSPropertyName -> Maybe String
335-
extractLabel (JSPropertyString _ nm) = Just (trimStringQuotes nm)
359+
extractLabel (JSPropertyString _ nm) = Just $ strValue nm
336360
extractLabel (JSPropertyIdent _ nm) = Just nm
337361
extractLabel _ = Nothing
338362

0 commit comments

Comments
 (0)