Skip to content

Commit

Permalink
Fix #2649 Backslash not escaped in interpolated
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsogarciacaro committed Dec 16, 2021
1 parent f7871e4 commit b627427
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 15 deletions.
26 changes: 15 additions & 11 deletions src/Fable.Transforms/BabelPrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -489,17 +489,21 @@ module PrinterExtensions =
let segmentLength = segmentEnd - segmentStart
if segmentLength > 0 then
let segment = value.Substring(segmentStart, segmentLength)
let subSegments = System.Text.RegularExpressions.Regex.Split(segment, @"\r?\n")
for i = 1 to subSegments.Length do
let subSegment =
// Remove whitespace in front of new lines,
// indent will be automatically applied
if printer.Column = 0 then subSegments.[i - 1].TrimStart()
else subSegments.[i - 1]
if subSegment.Length > 0 then
printer.Print(subSegment)
if i < subSegments.Length then
printer.PrintNewLine()

// TODO: In Fable 3 we're using emit for js template strings, if we give them
// their own AST entry in Fable 4 we can activate the below code to clean up printed code
printer.Print(segment)
// let subSegments = System.Text.RegularExpressions.Regex.Split(segment, @"\r?\n")
// for i = 1 to subSegments.Length do
// let subSegment =
// // Remove whitespace in front of new lines,
// // indent will be automatically applied
// if printer.Column = 0 then subSegments.[i - 1].TrimStart()
// else subSegments.[i - 1]
// if subSegment.Length > 0 then
// printer.Print(subSegment)
// if i < subSegments.Length then
// printer.PrintNewLine()

// Macro transformations
// https://fable.io/docs/communicate/js-from-fable.html#Emit-when-F-is-not-enough
Expand Down
2 changes: 1 addition & 1 deletion src/Fable.Transforms/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@ let printJsTaggedTemplate (str: string) (holes: {| Index: int; Length: int |}[])
// Escape ` quotations for JS. Note F# escapes for {, } and % are already replaced by the compiler
// 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
let escape (str: string) =
str.Replace("`", "\\`") //.Replace("{{", "{").Replace("}}", "}").Replace("%%", "%")
Regex.Replace(str, @"(?<!\\)\\", @"\\").Replace("`", @"\`") //.Replace("{{", "{").Replace("}}", "}").Replace("%%", "%")

let sb = System.Text.StringBuilder("`")
let mutable prevIndex = 0
Expand Down
43 changes: 40 additions & 3 deletions tests/Main/StringTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ open System.Globalization
#if FABLE_COMPILER
open Fable.Core
open Fable.Core.JsInterop
#endif

module M =
let f x = nameof x
#endif

// LINE SEPARATOR char doesn't cause an error #1283
let LINE_SEPARATOR = "\u2028"
Expand Down Expand Up @@ -213,8 +213,8 @@ let tests =
let o = obj()
o?self <- o
sprintf "%A" o |> ignore
#endif

// TODO!!! Enable these in .NET when CI supports net5.0
testCase "F# nameof works" <| fun () ->
M.f 12 |> equal "x"
nameof M |> equal "M"
Expand All @@ -238,7 +238,44 @@ let tests =
Country = "The United Kingdom" |}
$"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}!"
|> equal "Hi! My name is John DOE. I'm 32 years old and I'm from The United Kingdom!"
#endif

testCase "Interpolated strings keep empty lines" <| fun () ->
let s1 = $"""1
{1+1}
3"""
let s2 = """1
2
3"""
equal s1 s2
equal s1.Length s2.Length
equal 13 s1.Length

testCase "Can use backslash is interpolated strings" <| fun () ->
$"\n{1+1}\n" |> equal """
2
"""

testCase "Backslash is escaped in interpolated strings" <| fun () -> // See #2649
$"\\" |> equal @"\"
$"\\".Length |> equal 1
$@"\" |> equal @"\"
$@"\".Length |> equal 1
@$"\" |> equal @"\"
@$"\".Length |> equal 1
$"\\{4}" |> equal @"\4"
$"\\{4}".Length |> equal 2
$@"\{4}" |> equal @"\4"
$@"\{4}".Length |> equal 2
@$"\{4}" |> equal @"\4"
@$"\{4}".Length |> equal 2
testCase "sprintf \"%A\" with lists works" <| fun () ->
let xs = ["Hi"; "Hello"; "Hola"]
Expand Down

0 comments on commit b627427

Please sign in to comment.