Skip to content

Commit aa1d1ce

Browse files
authored
Revert "Fix parsing interpolated strings with unmatched braces (#14182)" (#14759)
This reverts commit 947f2bb.
1 parent 91af626 commit aa1d1ce

File tree

2 files changed

+69
-90
lines changed

2 files changed

+69
-90
lines changed

src/Compiler/lex.fsl

+6-18
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,7 @@ rule token args skip = parse
601601
// Single quote in triple quote ok, others disallowed
602602
match args.stringNest with
603603
| (_, LexerStringStyle.TripleQuote, _) :: _ -> ()
604-
| _ :: rest ->
605-
args.stringNest <- rest
606-
errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
604+
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
607605
| [] -> ()
608606

609607
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, LexerStringKind.String, m))
@@ -614,9 +612,7 @@ rule token args skip = parse
614612

615613
// Single quote in triple quote ok, others disallowed
616614
match args.stringNest with
617-
| _ :: rest ->
618-
args.stringNest <- rest
619-
errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m))
615+
| _ :: _ -> errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m))
620616
| [] -> ()
621617

622618
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, LexerStringKind.InterpolatedStringFirst, m))
@@ -628,9 +624,7 @@ rule token args skip = parse
628624
// Single quote in triple quote ok, others disallowed
629625
match args.stringNest with
630626
| (_, LexerStringStyle.TripleQuote, _) :: _ -> ()
631-
| _ :: rest ->
632-
args.stringNest <- rest
633-
errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
627+
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
634628
| _ -> ()
635629

636630
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, LexerStringKind.InterpolatedStringFirst, m))
@@ -641,9 +635,7 @@ rule token args skip = parse
641635

642636
// Single quote in triple quote ok, others disallowed
643637
match args.stringNest with
644-
| _ :: rest ->
645-
args.stringNest <- rest
646-
errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m))
638+
| _ :: _ -> errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m))
647639
| _ -> ()
648640

649641
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.TripleQuote, LexerStringKind.String, m))
@@ -655,9 +647,7 @@ rule token args skip = parse
655647
// Single quote in triple quote ok, others disallowed
656648
match args.stringNest with
657649
| (_, LexerStringStyle.TripleQuote, _) :: _ -> ()
658-
| _ :: rest ->
659-
args.stringNest <- rest
660-
errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
650+
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
661651
| _ -> ()
662652

663653
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, LexerStringKind.String, m))
@@ -669,9 +659,7 @@ rule token args skip = parse
669659
// Single quote in triple quote ok, others disallowed
670660
match args.stringNest with
671661
| (_, LexerStringStyle.TripleQuote, _) :: _ -> ()
672-
| _ :: rest ->
673-
args.stringNest <- rest
674-
errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
662+
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
675663
| _ -> ()
676664

677665
if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, LexerStringKind.InterpolatedStringFirst, m))

tests/fsharp/Compiler/Language/StringInterpolation.fs

+63-72
Original file line numberDiff line numberDiff line change
@@ -730,50 +730,70 @@ let x3 : FormattableString = $"one %10s{String.Empty}" // no %10s in Formattable
730730
(FSharpDiagnosticSeverity.Error, 3376, (6, 30, 6, 55),
731731
"Invalid interpolated string. Interpolated strings used as type IFormattable or type FormattableString may not use '%' specifiers, only .NET-style interpolands such as '{expr}', '{expr,3}' or '{expr:N5}' may be used.")|]
732732

733-
[<TestCase("""let s1 = $"123{456}789{""", "\"012\"", "}345\"")>]
734-
[<TestCase("""let s2 = $"123{456}789{""", "@\"012\"", "}345\"")>]
735-
[<TestCase("""let s3 = $"123{456}789{""", "$\"012\"", "}345\"")>]
736-
[<TestCase("""let s4 = $@"123{456}789{""", "\"012\"", "}345\"")>]
737-
[<TestCase("""let s5 = @$"123{456}789{""", "\"012\"", "}345\"")>]
738-
[<TestCase("""let s6 = $@"123{456}789{""", "@\"012\"", "}345\"")>]
739-
[<TestCase("""let s7 = @$"123{456}789{""", "$\"012\"", "}345\"")>]
740-
[<TestCase("""let s8 = $@"123{456}789{""", "@$\"012\"", "}345\"")>]
741-
[<TestCase("""let s9 = @$"123{456}789{""", "$@\"012\"", "}345\"")>]
742-
let ``String interpolation negative nested in single`` ((part1: string, expr: string, part2: string)) =
743-
let code = part1 + expr + part2
744-
let exprPosBegin = 1 + part1.Length
745-
let quotePosInExpr = exprPosBegin + (expr |> Seq.findIndex (fun c -> c = '"'))
746-
let closingBracePos = exprPosBegin + expr.Length
747-
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |]
733+
734+
[<Test>]
735+
let ``String interpolation negative nested in single`` () =
736+
let code = """
737+
738+
open System
739+
let s1 = $"123{456}789{"012"}345"
740+
let s2 = $"123{456}789{@"012"}345"
741+
let s3 = $"123{456}789{$"012"}345"
742+
let s4 = $@"123{456}789{"012"}345"
743+
let s5 = @$"123{456}789{"012"}345"
744+
let s6 = $@"123{456}789{@"012"}345"
745+
let s7 = @$"123{456}789{$"012"}345"
746+
let s8 = $@"123{456}789{@$"012"}345"
747+
let s9 = @$"123{456}789{$@"012"}345"
748+
"""
749+
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |]
748750
code
749-
[|(FSharpDiagnosticSeverity.Error, 3373, (1, exprPosBegin, 1, quotePosInExpr + 1),
750-
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. \
751-
Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
752-
(FSharpDiagnosticSeverity.Error, 10, (1, closingBracePos, 1, closingBracePos + 1),
753-
"Unexpected symbol '}' in binding. Expected interpolated string (final part), interpolated string (part) or other token.");
754-
(FSharpDiagnosticSeverity.Error, 514, (1, code.Length, 1, code.Length + 1), "End of file in string begun at or before here")|]
755-
756-
[<TestCase("let TripleInTripleInterpolated = $\"\"\"123{456}789{", "\"\"\"012\"\"\"", "}345\"\"\"")>]
757-
[<TestCase("let TripleInSingleInterpolated = $\"123{456}789{", "\"\"\"012\"\"\"", "}345\"\"\"")>]
758-
[<TestCase("let TripleInVerbatimInterpolated = @$\"123{456}789{", "\"\"\"012\"\"\"", "}345\"\"\"")>]
759-
[<TestCase("let TripleInterpolatedInTripleInterpolated = $\"\"\"123{456}789{", "$\"\"\"012\"\"\"", "}345\"\"\"")>]
760-
[<TestCase("let TripleInterpolatedInSingleInterpolated = $\"123{456}789{", "$\"\"\"012\"\"\"", "}345\"\"\"")>]
761-
[<TestCase("let TripleInterpolatedInVerbatimInterpolated = @$\"123{456}789{", "$\"\"\"012\"\"\"", "}345\"\"\"")>]
762-
let ``String interpolation negative nested in triple`` ((part1: string, expr: string, part2: string)) =
763-
let code = part1 + expr + part2
764-
let exprPosBegin = 1 + part1.Length
765-
let exprOpenQuoteEnd = exprPosBegin + 3 + (expr |> Seq.takeWhile (fun c -> c <> '"') |> Seq.length)
766-
let closingBracePos = exprPosBegin + expr.Length
767-
let closingQuotePos = code.Length + 1 - 3
751+
[|(FSharpDiagnosticSeverity.Error, 3373, (4, 24, 4, 25),
752+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
753+
(FSharpDiagnosticSeverity.Error, 3373, (5, 24, 5, 26),
754+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
755+
(FSharpDiagnosticSeverity.Error, 3373, (6, 24, 6, 26),
756+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
757+
(FSharpDiagnosticSeverity.Error, 3373, (7, 25, 7, 26),
758+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
759+
(FSharpDiagnosticSeverity.Error, 3373, (8, 25, 8, 26),
760+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
761+
(FSharpDiagnosticSeverity.Error, 3373, (9, 25, 9, 27),
762+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
763+
(FSharpDiagnosticSeverity.Error, 3373, (10, 25, 10, 27),
764+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
765+
(FSharpDiagnosticSeverity.Error, 3373, (11, 25, 11, 28),
766+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
767+
(FSharpDiagnosticSeverity.Error, 3373, (12, 25, 12, 28),
768+
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.")|]
769+
770+
[<Test>]
771+
let ``String interpolation negative nested in triple`` () =
772+
let code = "
773+
774+
open System
775+
let TripleInTripleInterpolated = $\"\"\"123{456}789{\"\"\"012\"\"\"}345\"\"\"
776+
let TripleInSingleInterpolated = $\"123{456}789{\"\"\"012\"\"\"}345\"
777+
let TripleInVerbatimInterpolated = $\"123{456}789{\"\"\"012\"\"\"}345\"
778+
let TripleInterpolatedInTripleInterpolated = $\"\"\"123{456}789{$\"\"\"012\"\"\"}345\"\"\"
779+
let TripleInterpolatedInSingleInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}345\"
780+
let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}345\"
781+
"
768782
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |]
769783
code
770-
[|(FSharpDiagnosticSeverity.Error, 3374, (1, exprPosBegin, 1, exprOpenQuoteEnd),
784+
[|(FSharpDiagnosticSeverity.Error, 3374, (4, 52, 4, 55),
771785
"Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.");
772-
(FSharpDiagnosticSeverity.Error, 10, (1, closingBracePos, 1, closingBracePos + 1),
773-
"Unexpected symbol '}' in binding. Expected interpolated string (final part), interpolated string (part) or other token.");
774-
(FSharpDiagnosticSeverity.Error, 1232, (1, closingQuotePos, 1, closingQuotePos + 3),
775-
"End of file in triple-quote string begun at or before here")|]
776-
786+
(FSharpDiagnosticSeverity.Error, 3374, (5, 50, 5, 53),
787+
"Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.");
788+
(FSharpDiagnosticSeverity.Error, 3374, (6, 50, 6, 53),
789+
"Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.");
790+
(FSharpDiagnosticSeverity.Error, 3374, (7, 64, 7, 68),
791+
"Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.");
792+
(FSharpDiagnosticSeverity.Error, 3374, (8, 62, 8, 66),
793+
"Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.");
794+
(FSharpDiagnosticSeverity.Error, 3374, (9, 62, 9, 66),
795+
"Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.")|]
796+
777797
[<Test>]
778798
let ``String interpolation negative incomplete string`` () =
779799
let code = """let x1 = $"one %d{System.String.Empty}"""
@@ -783,46 +803,17 @@ let x3 : FormattableString = $"one %10s{String.Empty}" // no %10s in Formattable
783803
"Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token.");
784804
(FSharpDiagnosticSeverity.Error, 3379, (1, 38, 1, 39),
785805
"Incomplete interpolated string begun at or before here")|]
786-
806+
787807
[<Test>]
788-
let ``String interpolation negative incomplete string with incomplete fill`` () =
808+
let ``String interpolation negative incomplete string fill`` () =
789809
let code = """let x1 = $"one %d{System.String.Empty"""
790810
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |]
791811
code
792812
[|(FSharpDiagnosticSeverity.Error, 10, (1, 1, 1, 38),
793813
"Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token.");
794814
(FSharpDiagnosticSeverity.Error, 3378, (1, 18, 1, 19),
795815
"Incomplete interpolated string expression fill begun at or before here")|]
796-
797-
[<Test>]
798-
let ``String interpolation negative incomplete fill`` () =
799-
let code = "let x1 = $\"one %d{System.String.Empty\""
800-
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |]
801-
code
802-
[|(FSharpDiagnosticSeverity.Error, 3373, (1, 38, 1, 39),
803-
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. \
804-
Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
805-
(FSharpDiagnosticSeverity.Error, 10, (1, 1, 1, 39),
806-
"Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token.");
807-
(FSharpDiagnosticSeverity.Error, 514, (1, 38, 1, 39),
808-
"End of file in string begun at or before here")|]
809-
810-
[<Test>]
811-
let ``String interpolation negative incomplete fill with another valid string`` () =
812-
let code = """
813-
let x1 = $"one %d{System.String.Empty"
814-
let x2 = "any old string"
815-
"""
816-
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |]
817-
code
818-
[|(FSharpDiagnosticSeverity.Error, 3373, (2, 38, 2, 39),
819-
"Invalid interpolated string. Single quote or verbatim string literals may not be used in interpolated expressions in single quote or verbatim strings. \
820-
Consider using an explicit 'let' binding for the interpolation expression or use a triple quote string as the outer string literal.");
821-
(FSharpDiagnosticSeverity.Error, 10, (4, 1, 4, 1),
822-
"Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token.");
823-
(FSharpDiagnosticSeverity.Error, 514, (3, 25, 3, 26),
824-
"End of file in string begun at or before here")|]
825-
816+
826817
[<Test>]
827818
let ``String interpolation negative incomplete verbatim string`` () =
828819
let code = """let x1 = @$"one %d{System.String.Empty} """

0 commit comments

Comments
 (0)