Skip to content

Commit

Permalink
pars.fsy: capture empty interpolated string fills and report error (d…
Browse files Browse the repository at this point in the history
…otnet#9849)

* pars.fsy: capture empty interpolated string fills and report error

reduce empty interp fill error range, update tests

update error msg 3382

* StringInterp: update test error code
  • Loading branch information
Yatao Li authored and nosami committed Feb 22, 2021
1 parent 43d2886 commit 9129353
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/fsharp/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1534,5 +1534,6 @@ forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable
3379,parsEofInInterpolatedString,"Incomplete interpolated string begun at or before here"
3380,parsEofInInterpolatedVerbatimString,"Incomplete interpolated verbatim string begun at or before here"
3381,parsEofInInterpolatedTripleQuoteString,"Incomplete interpolated triple-quote string begun at or before here"
3382,lexRBraceInInterpolatedString,"A '}}' character must be escaped (by doubling) in an interpolated string."
3382,parsEmptyFillInInterpolatedString,"Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected."
3383,lexRBraceInInterpolatedString,"A '}}' character must be escaped (by doubling) in an interpolated string."
#3501 "This construct is not supported by your version of the F# compiler" CompilerMessage(ExperimentalAttributeMessages.NotSupportedYet, 3501, IsError=true)
14 changes: 14 additions & 0 deletions src/fsharp/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -5507,6 +5507,13 @@ interpolatedStringParts:
| INTERP_STRING_PART interpolatedStringFill interpolatedStringParts
{ SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3 }

| INTERP_STRING_PART interpolatedStringParts
{
let rbrace = parseState.InputEndPosition 1
let lbrace = parseState.InputStartPosition 2
reportParseErrorAt (mkSynRange rbrace lbrace) (FSComp.SR.parsEmptyFillInInterpolatedString())
SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: $2 }

/* INTERP_STRING_BEGIN_END */
/* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_END */
/* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_PART int32 INTERP_STRING_END */
Expand All @@ -5516,6 +5523,13 @@ interpolatedString:

| INTERP_STRING_BEGIN_END
{ [ SynInterpolatedStringPart.String (fst $1, rhs parseState 1) ] }

| INTERP_STRING_BEGIN_PART interpolatedStringParts
{
let rbrace = parseState.InputEndPosition 1
let lbrace = parseState.InputStartPosition 2
reportParseErrorAt (mkSynRange rbrace lbrace) (FSComp.SR.parsEmptyFillInInterpolatedString())
SynInterpolatedStringPart.String (fst $1, rhs parseState 1) :: $2 }

opt_HIGH_PRECEDENCE_APP:
| HIGH_PRECEDENCE_BRACK_APP { }
Expand Down
21 changes: 15 additions & 6 deletions tests/fsharp/Compiler/Language/StringInterpolation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,17 @@ let xd = $"%A{}" // empty expression
"""
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |]
code
[|(FSharpErrorSeverity.Error, 10, (2, 15, 2, 17),
"Unexpected interpolated string (final part) in binding")
[|(FSharpErrorSeverity.Error, 3382, (2, 15, 2, 15),
"Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.")
|]

let code = """
let xd = $"%A{ }" // empty expression
"""
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |]
code
[|(FSharpErrorSeverity.Error, 3382, (2, 15, 2, 17),
"Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected.")
|]

[<Test>]
Expand Down Expand Up @@ -818,29 +827,29 @@ let TripleInterpolatedInVerbatimInterpolated = $\"123{456}789{$\"\"\"012\"\"\"}3
let code = "let x1 = $\"}\""
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |]
code
[|(FSharpErrorSeverity.Error, 3382, (1, 10, 1, 14),
[|(FSharpErrorSeverity.Error, 3383, (1, 10, 1, 14),
"A '}' character must be escaped (by doubling) in an interpolated string.")|]

[<Test>]
let ``String interpolation extra right brace verbatim`` () =
let code = "let x1 = @$\"}\""
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |]
code
[|(FSharpErrorSeverity.Error, 3382, (1, 10, 1, 15),
[|(FSharpErrorSeverity.Error, 3383, (1, 10, 1, 15),
"A '}' character must be escaped (by doubling) in an interpolated string.")|]

[<Test>]
let ``String interpolation extra right brace triple`` () =
let code = "let x1 = $\"\"\"}\"\"\""
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |]
code
[|(FSharpErrorSeverity.Error, 3382, (1, 10, 1, 18),
[|(FSharpErrorSeverity.Error, 3383, (1, 10, 1, 18),
"A '}' character must be escaped (by doubling) in an interpolated string.")|]

[<Test>]
let ``String interpolation extra right brace single quote with hole`` () =
let code = "let x1 = $\"{0}}\""
CompilerAssert.TypeCheckWithErrorsAndOptions [| "--langversion:preview" |]
code
[|(FSharpErrorSeverity.Error, 3382, (1, 14, 1, 17),
[|(FSharpErrorSeverity.Error, 3383, (1, 14, 1, 17),
"A '}' character must be escaped (by doubling) in an interpolated string.")|]

0 comments on commit 9129353

Please sign in to comment.