From aa1d1cec8ec1758492ca92a59917f9c436004b58 Mon Sep 17 00:00:00 2001 From: Adam Boniecki <20281641+abonie@users.noreply.github.com> Date: Thu, 16 Feb 2023 16:46:13 +0100 Subject: [PATCH] Revert "Fix parsing interpolated strings with unmatched braces (#14182)" (#14759) This reverts commit 947f2bb58cf8d2e3a1d4d0adc22fb88ad89e7466. --- src/Compiler/lex.fsl | 24 +--- .../Compiler/Language/StringInterpolation.fs | 135 ++++++++---------- 2 files changed, 69 insertions(+), 90 deletions(-) diff --git a/src/Compiler/lex.fsl b/src/Compiler/lex.fsl index ab11625c7d5..45057efa104 100644 --- a/src/Compiler/lex.fsl +++ b/src/Compiler/lex.fsl @@ -601,9 +601,7 @@ rule token args skip = parse // Single quote in triple quote ok, others disallowed match args.stringNest with | (_, LexerStringStyle.TripleQuote, _) :: _ -> () - | _ :: rest -> - args.stringNest <- rest - errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) | [] -> () 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 // Single quote in triple quote ok, others disallowed match args.stringNest with - | _ :: rest -> - args.stringNest <- rest - errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m)) + | _ :: _ -> errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m)) | [] -> () 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 // Single quote in triple quote ok, others disallowed match args.stringNest with | (_, LexerStringStyle.TripleQuote, _) :: _ -> () - | _ :: rest -> - args.stringNest <- rest - errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) | _ -> () 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 // Single quote in triple quote ok, others disallowed match args.stringNest with - | _ :: rest -> - args.stringNest <- rest - errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m)) + | _ :: _ -> errorR(Error(FSComp.SR.lexTripleQuoteInTripleQuote(), m)) | _ -> () 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 // Single quote in triple quote ok, others disallowed match args.stringNest with | (_, LexerStringStyle.TripleQuote, _) :: _ -> () - | _ :: rest -> - args.stringNest <- rest - errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) | _ -> () 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 // Single quote in triple quote ok, others disallowed match args.stringNest with | (_, LexerStringStyle.TripleQuote, _) :: _ -> () - | _ :: rest -> - args.stringNest <- rest - errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) + | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m)) | _ -> () if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.Verbatim, LexerStringKind.InterpolatedStringFirst, m)) diff --git a/tests/fsharp/Compiler/Language/StringInterpolation.fs b/tests/fsharp/Compiler/Language/StringInterpolation.fs index bda3864b4eb..367f4997d85 100644 --- a/tests/fsharp/Compiler/Language/StringInterpolation.fs +++ b/tests/fsharp/Compiler/Language/StringInterpolation.fs @@ -730,50 +730,70 @@ let x3 : FormattableString = $"one %10s{String.Empty}" // no %10s in Formattable (FSharpDiagnosticSeverity.Error, 3376, (6, 30, 6, 55), "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.")|] - [] - [] - [] - [] - [] - [] - [] - [] - [] - let ``String interpolation negative nested in single`` ((part1: string, expr: string, part2: string)) = - let code = part1 + expr + part2 - let exprPosBegin = 1 + part1.Length - let quotePosInExpr = exprPosBegin + (expr |> Seq.findIndex (fun c -> c = '"')) - let closingBracePos = exprPosBegin + expr.Length - CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] + + [] + let ``String interpolation negative nested in single`` () = + let code = """ + +open System +let s1 = $"123{456}789{"012"}345" +let s2 = $"123{456}789{@"012"}345" +let s3 = $"123{456}789{$"012"}345" +let s4 = $@"123{456}789{"012"}345" +let s5 = @$"123{456}789{"012"}345" +let s6 = $@"123{456}789{@"012"}345" +let s7 = @$"123{456}789{$"012"}345" +let s8 = $@"123{456}789{@$"012"}345" +let s9 = @$"123{456}789{$@"012"}345" +""" + CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] code - [|(FSharpDiagnosticSeverity.Error, 3373, (1, exprPosBegin, 1, quotePosInExpr + 1), - "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."); - (FSharpDiagnosticSeverity.Error, 10, (1, closingBracePos, 1, closingBracePos + 1), - "Unexpected symbol '}' in binding. Expected interpolated string (final part), interpolated string (part) or other token."); - (FSharpDiagnosticSeverity.Error, 514, (1, code.Length, 1, code.Length + 1), "End of file in string begun at or before here")|] - - [] - [] - [] - [] - [] - [] - let ``String interpolation negative nested in triple`` ((part1: string, expr: string, part2: string)) = - let code = part1 + expr + part2 - let exprPosBegin = 1 + part1.Length - let exprOpenQuoteEnd = exprPosBegin + 3 + (expr |> Seq.takeWhile (fun c -> c <> '"') |> Seq.length) - let closingBracePos = exprPosBegin + expr.Length - let closingQuotePos = code.Length + 1 - 3 + [|(FSharpDiagnosticSeverity.Error, 3373, (4, 24, 4, 25), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (5, 24, 5, 26), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (6, 24, 6, 26), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (7, 25, 7, 26), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (8, 25, 8, 26), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (9, 25, 9, 27), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (10, 25, 10, 27), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (11, 25, 11, 28), + "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."); + (FSharpDiagnosticSeverity.Error, 3373, (12, 25, 12, 28), + "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.")|] + + [] + let ``String interpolation negative nested in triple`` () = + let code = " + +open System +let TripleInTripleInterpolated = $\"\"\"123{456}789{\"\"\"012\"\"\"}345\"\"\" +let TripleInSingleInterpolated = $\"123{456}789{\"\"\"012\"\"\"}345\" +let TripleInVerbatimInterpolated = $\"123{456}789{\"\"\"012\"\"\"}345\" +let TripleInterpolatedInTripleInterpolated = $\"\"\"123{456}789{$\"\"\"012\"\"\"}345\"\"\" +let TripleInterpolatedInSingleInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}345\" +let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}345\" +" CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] code - [|(FSharpDiagnosticSeverity.Error, 3374, (1, exprPosBegin, 1, exprOpenQuoteEnd), + [|(FSharpDiagnosticSeverity.Error, 3374, (4, 52, 4, 55), "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); - (FSharpDiagnosticSeverity.Error, 10, (1, closingBracePos, 1, closingBracePos + 1), - "Unexpected symbol '}' in binding. Expected interpolated string (final part), interpolated string (part) or other token."); - (FSharpDiagnosticSeverity.Error, 1232, (1, closingQuotePos, 1, closingQuotePos + 3), - "End of file in triple-quote string begun at or before here")|] - + (FSharpDiagnosticSeverity.Error, 3374, (5, 50, 5, 53), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (6, 50, 6, 53), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (7, 64, 7, 68), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (8, 62, 8, 66), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression."); + (FSharpDiagnosticSeverity.Error, 3374, (9, 62, 9, 66), + "Invalid interpolated string. Triple quote string literals may not be used in interpolated expressions. Consider using an explicit 'let' binding for the interpolation expression.")|] + [] let ``String interpolation negative incomplete string`` () = let code = """let x1 = $"one %d{System.String.Empty}""" @@ -783,9 +803,9 @@ let x3 : FormattableString = $"one %10s{String.Empty}" // no %10s in Formattable "Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token."); (FSharpDiagnosticSeverity.Error, 3379, (1, 38, 1, 39), "Incomplete interpolated string begun at or before here")|] - + [] - let ``String interpolation negative incomplete string with incomplete fill`` () = + let ``String interpolation negative incomplete string fill`` () = let code = """let x1 = $"one %d{System.String.Empty""" CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] code @@ -793,36 +813,7 @@ let x3 : FormattableString = $"one %10s{String.Empty}" // no %10s in Formattable "Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token."); (FSharpDiagnosticSeverity.Error, 3378, (1, 18, 1, 19), "Incomplete interpolated string expression fill begun at or before here")|] - - [] - let ``String interpolation negative incomplete fill`` () = - let code = "let x1 = $\"one %d{System.String.Empty\"" - CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] - code - [|(FSharpDiagnosticSeverity.Error, 3373, (1, 38, 1, 39), - "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."); - (FSharpDiagnosticSeverity.Error, 10, (1, 1, 1, 39), - "Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token."); - (FSharpDiagnosticSeverity.Error, 514, (1, 38, 1, 39), - "End of file in string begun at or before here")|] - - [] - let ``String interpolation negative incomplete fill with another valid string`` () = - let code = """ -let x1 = $"one %d{System.String.Empty" -let x2 = "any old string" -""" - CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:5.0" |] - code - [|(FSharpDiagnosticSeverity.Error, 3373, (2, 38, 2, 39), - "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."); - (FSharpDiagnosticSeverity.Error, 10, (4, 1, 4, 1), - "Incomplete structured construct at or before this point in binding. Expected interpolated string (final part), interpolated string (part) or other token."); - (FSharpDiagnosticSeverity.Error, 514, (3, 25, 3, 26), - "End of file in string begun at or before here")|] - + [] let ``String interpolation negative incomplete verbatim string`` () = let code = """let x1 = @$"one %d{System.String.Empty} """