Skip to content

Commit b627427

Browse files
Fix #2649 Backslash not escaped in interpolated
1 parent f7871e4 commit b627427

File tree

3 files changed

+56
-15
lines changed

3 files changed

+56
-15
lines changed

src/Fable.Transforms/BabelPrinter.fs

+15-11
Original file line numberDiff line numberDiff line change
@@ -489,17 +489,21 @@ module PrinterExtensions =
489489
let segmentLength = segmentEnd - segmentStart
490490
if segmentLength > 0 then
491491
let segment = value.Substring(segmentStart, segmentLength)
492-
let subSegments = System.Text.RegularExpressions.Regex.Split(segment, @"\r?\n")
493-
for i = 1 to subSegments.Length do
494-
let subSegment =
495-
// Remove whitespace in front of new lines,
496-
// indent will be automatically applied
497-
if printer.Column = 0 then subSegments.[i - 1].TrimStart()
498-
else subSegments.[i - 1]
499-
if subSegment.Length > 0 then
500-
printer.Print(subSegment)
501-
if i < subSegments.Length then
502-
printer.PrintNewLine()
492+
493+
// TODO: In Fable 3 we're using emit for js template strings, if we give them
494+
// their own AST entry in Fable 4 we can activate the below code to clean up printed code
495+
printer.Print(segment)
496+
// let subSegments = System.Text.RegularExpressions.Regex.Split(segment, @"\r?\n")
497+
// for i = 1 to subSegments.Length do
498+
// let subSegment =
499+
// // Remove whitespace in front of new lines,
500+
// // indent will be automatically applied
501+
// if printer.Column = 0 then subSegments.[i - 1].TrimStart()
502+
// else subSegments.[i - 1]
503+
// if subSegment.Length > 0 then
504+
// printer.Print(subSegment)
505+
// if i < subSegments.Length then
506+
// printer.PrintNewLine()
503507

504508
// Macro transformations
505509
// https://fable.io/docs/communicate/js-from-fable.html#Emit-when-F-is-not-enough

src/Fable.Transforms/Replacements.fs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1403,7 +1403,7 @@ let printJsTaggedTemplate (str: string) (holes: {| Index: int; Length: int |}[])
14031403
// Escape ` quotations for JS. Note F# escapes for {, } and % are already replaced by the compiler
14041404
// TODO: Do we need to escape other sequences? See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates_and_escape_sequences
14051405
let escape (str: string) =
1406-
str.Replace("`", "\\`") //.Replace("{{", "{").Replace("}}", "}").Replace("%%", "%")
1406+
Regex.Replace(str, @"(?<!\\)\\", @"\\").Replace("`", @"\`") //.Replace("{{", "{").Replace("}}", "}").Replace("%%", "%")
14071407

14081408
let sb = System.Text.StringBuilder("`")
14091409
let mutable prevIndex = 0

tests/Main/StringTests.fs

+40-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ open System.Globalization
77
#if FABLE_COMPILER
88
open Fable.Core
99
open Fable.Core.JsInterop
10+
#endif
1011

1112
module M =
1213
let f x = nameof x
13-
#endif
1414

1515
// LINE SEPARATOR char doesn't cause an error #1283
1616
let LINE_SEPARATOR = "\u2028"
@@ -213,8 +213,8 @@ let tests =
213213
let o = obj()
214214
o?self <- o
215215
sprintf "%A" o |> ignore
216+
#endif
216217

217-
// TODO!!! Enable these in .NET when CI supports net5.0
218218
testCase "F# nameof works" <| fun () ->
219219
M.f 12 |> equal "x"
220220
nameof M |> equal "M"
@@ -238,7 +238,44 @@ let tests =
238238
Country = "The United Kingdom" |}
239239
$"Hi! My name is %s{person.Name} %s{person.Surname.ToUpper()}. I'm %i{person.Age} years old and I'm from %s{person.Country}!"
240240
|> equal "Hi! My name is John DOE. I'm 32 years old and I'm from The United Kingdom!"
241-
#endif
241+
242+
testCase "Interpolated strings keep empty lines" <| fun () ->
243+
let s1 = $"""1
244+
245+
246+
{1+1}
247+
248+
249+
3"""
250+
let s2 = """1
251+
252+
253+
2
254+
255+
256+
3"""
257+
equal s1 s2
258+
equal s1.Length s2.Length
259+
equal 13 s1.Length
260+
261+
testCase "Can use backslash is interpolated strings" <| fun () ->
262+
$"\n{1+1}\n" |> equal """
263+
2
264+
"""
265+
266+
testCase "Backslash is escaped in interpolated strings" <| fun () -> // See #2649
267+
$"\\" |> equal @"\"
268+
$"\\".Length |> equal 1
269+
$@"\" |> equal @"\"
270+
$@"\".Length |> equal 1
271+
@$"\" |> equal @"\"
272+
@$"\".Length |> equal 1
273+
$"\\{4}" |> equal @"\4"
274+
$"\\{4}".Length |> equal 2
275+
$@"\{4}" |> equal @"\4"
276+
$@"\{4}".Length |> equal 2
277+
@$"\{4}" |> equal @"\4"
278+
@$"\{4}".Length |> equal 2
242279
243280
testCase "sprintf \"%A\" with lists works" <| fun () ->
244281
let xs = ["Hi"; "Hello"; "Hola"]

0 commit comments

Comments
 (0)