From b6274273aeb64b3c57ed5fe2009d633367766637 Mon Sep 17 00:00:00 2001 From: Alfonso Garcia-Caro Date: Thu, 16 Dec 2021 16:10:20 +0900 Subject: [PATCH] Fix #2649 Backslash not escaped in interpolated --- src/Fable.Transforms/BabelPrinter.fs | 26 ++++++++++------- src/Fable.Transforms/Replacements.fs | 2 +- tests/Main/StringTests.fs | 43 ++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/Fable.Transforms/BabelPrinter.fs b/src/Fable.Transforms/BabelPrinter.fs index 35aae6cc0f..192a881f8f 100644 --- a/src/Fable.Transforms/BabelPrinter.fs +++ b/src/Fable.Transforms/BabelPrinter.fs @@ -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 diff --git a/src/Fable.Transforms/Replacements.fs b/src/Fable.Transforms/Replacements.fs index 657ae789ed..8df541a220 100644 --- a/src/Fable.Transforms/Replacements.fs +++ b/src/Fable.Transforms/Replacements.fs @@ -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, @"(? 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" @@ -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"]