Skip to content

Commit

Permalink
- use a new rule for '"}" +' to catch the correct range start
Browse files Browse the repository at this point in the history
- clean up work around structures introduced before and not needed anymore with this
  • Loading branch information
dawedawe committed Feb 29, 2024
1 parent 369bbfb commit 4d01cda
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 78 deletions.
2 changes: 1 addition & 1 deletion docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### Fixed

* Fix wrong range start of INTERP_STRING_END. ([PR #16774](https://github.com/dotnet/fsharp/pull/16774))
* Fix wrong range start of INTERP_STRING_END. ([PR #16774](https://github.com/dotnet/fsharp/pull/16774), [PR #16785](https://github.com/dotnet/fsharp/pull/16785))
* Fix missing warning for recursive calls in list comprehensions. ([PR #16652](https://github.com/dotnet/fsharp/pull/16652))
* Code generated files with > 64K methods and generated symbols crash when loaded. Use infered sequence points for debugging. ([Issue #16399](https://github.com/dotnet/fsharp/issues/16399), [#PR 16514](https://github.com/dotnet/fsharp/pull/16514))
* `nameof Module` expressions and patterns are processed to link files in `--test:GraphBasedChecking`. ([PR #16550](https://github.com/dotnet/fsharp/pull/16550), [PR #16743](https://github.com/dotnet/fsharp/pull/16743))
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2685,7 +2685,7 @@ module internal ParseAndCheckFile =
| INTERP_STRING_BEGIN_PART _ | INTERP_STRING_PART _ as tok, _ ->
let braceOffset =
match tok with
| INTERP_STRING_BEGIN_PART(_, SynStringKind.TripleQuote, (LexerContinuation.Token(_, (_, _, dl, _, _) :: _))) ->
| INTERP_STRING_BEGIN_PART(_, SynStringKind.TripleQuote, (LexerContinuation.Token(_, (_, _, dl, _) :: _))) ->
dl - 1
| _ -> 0

Expand Down
16 changes: 8 additions & 8 deletions src/Compiler/Service/ServiceLexing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ module FSharpTokenTag =
let INTERP_STRING_BEGIN_PART =
tagOfToken (INTERP_STRING_BEGIN_PART("a", SynStringKind.Regular, LexCont.Default))

let INTERP_STRING_PART = tagOfToken (INTERP_STRING_PART("a", None, LexCont.Default))
let INTERP_STRING_END = tagOfToken (INTERP_STRING_END("a", None, LexCont.Default))
let INTERP_STRING_PART = tagOfToken (INTERP_STRING_PART("a", LexCont.Default))
let INTERP_STRING_END = tagOfToken (INTERP_STRING_END("a", LexCont.Default))
let LPAREN = tagOfToken LPAREN
let RPAREN = tagOfToken RPAREN
let LBRACK = tagOfToken LBRACK
Expand Down Expand Up @@ -491,9 +491,9 @@ module internal LexerStateEncoding =
| STRING_TEXT cont
| EOF cont
| INTERP_STRING_BEGIN_PART(_, _, cont)
| INTERP_STRING_PART(_, _, cont)
| INTERP_STRING_PART(_, cont)
| INTERP_STRING_BEGIN_END(_, _, cont)
| INTERP_STRING_END(_, _, cont)
| INTERP_STRING_END(_, cont)
| LBRACE cont
| RBRACE cont
| BYTEARRAY(_, _, cont)
Expand Down Expand Up @@ -621,12 +621,12 @@ module internal LexerStateEncoding =
let tag1, i1, kind1, rest =
match stringNest with
| [] -> false, 0, 0, []
| (i1, kind1, _, _, _) :: rest -> true, i1, encodeStringStyle kind1, rest
| (i1, kind1, _, _) :: rest -> true, i1, encodeStringStyle kind1, rest

let tag2, i2, kind2 =
match rest with
| [] -> false, 0, 0
| (i2, kind2, _, _, _) :: _ -> true, i2, encodeStringStyle kind2
| (i2, kind2, _, _) :: _ -> true, i2, encodeStringStyle kind2

(if tag1 then 0b100000000000 else 0)
||| (if tag2 then 0b010000000000 else 0)
Expand Down Expand Up @@ -696,9 +696,9 @@ module internal LexerStateEncoding =
let nest =
[
if tag1 then
i1, decodeStringStyle kind1, 0, None, range0
i1, decodeStringStyle kind1, 0, range0
if tag2 then
i2, decodeStringStyle kind2, 0, None, range0
i2, decodeStringStyle kind2, 0, range0
]

nest
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/SyntaxTree/LexHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ type LexerStringFinisher =
else
INTERP_STRING_BEGIN_END(s, synStringKind, cont)
else if isPart then
INTERP_STRING_PART(s, None, cont)
INTERP_STRING_PART(s, cont)
else
INTERP_STRING_END(s, None, cont)
INTERP_STRING_END(s, cont)
elif kind.IsByteString then
let synByteStringKind =
if isVerbatim then
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/SyntaxTree/ParseHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ type LexerStringKind =

/// Represents the degree of nesting of '{..}' and the style of the string to continue afterwards, in an interpolation fill.
/// Nesting counters and styles of outer interpolating strings are pushed on this stack.
type LexerInterpolatedStringNesting = (int * LexerStringStyle * int * range option * range) list
type LexerInterpolatedStringNesting = (int * LexerStringStyle * int * range) list

/// The parser defines a number of tokens for whitespace and
/// comments eliminated by the lexer. These carry a specification of
Expand Down Expand Up @@ -973,7 +973,7 @@ let checkEndOfFileError t =

match nesting with
| [] -> ()
| (_, _, _, _, m) :: _ -> reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedStringFill ())
| (_, _, _, m) :: _ -> reportParseErrorAt m (FSComp.SR.parsEofInInterpolatedStringFill ())

type BindingSet = BindingSetPreAttrs of range * bool * bool * (SynAttributes -> SynAccess option -> SynAttributes * SynBinding list) * range

Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/SyntaxTree/ParseHelpers.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ type LexerStringKind =

static member String: LexerStringKind

type LexerInterpolatedStringNesting = (int * LexerStringStyle * int * range option * range) list
type LexerInterpolatedStringNesting = (int * LexerStringStyle * int * range) list

[<RequireQualifiedAccess; NoComparison; NoEquality>]
type LexerContinuation =
Expand Down
89 changes: 52 additions & 37 deletions src/Compiler/lex.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ let checkExprGreaterColonOp (lexbuf:UnicodeLexing.Lexbuf) =
let unexpectedChar lexbuf =
LEX_FAILURE (FSComp.SR.lexUnexpectedChar(lexeme lexbuf))

let startString args (lexbuf: UnicodeLexing.Lexbuf) altStartForStringPartOrEnd =
let startString args (lexbuf: UnicodeLexing.Lexbuf) =
let buf = ByteBuffer.Create StringCapacity
let m = lexbuf.LexemeRange
let startp = lexbuf.StartPos
Expand Down Expand Up @@ -158,9 +158,9 @@ let startString args (lexbuf: UnicodeLexing.Lexbuf) altStartForStringPartOrEnd =
INTERP_STRING_BEGIN_END (s, synStringKind, cont)
else
if isPart then
INTERP_STRING_PART (s, altStartForStringPartOrEnd, cont)
INTERP_STRING_PART (s, cont)
else
INTERP_STRING_END (s, altStartForStringPartOrEnd, cont)
INTERP_STRING_END (s, cont)
else
let s = Lexhelp.stringBufferAsString buf
let synStringKind =
Expand Down Expand Up @@ -587,20 +587,20 @@ rule token (args: LexArgs) (skip: bool) = parse
else mlOnly m args skip lexbuf }

| '"'
{ let buf, fin, m = startString args lexbuf None
{ let buf, fin, m = startString args lexbuf

// Single quote in triple quote ok, others disallowed
match args.stringNest with
| (_, LexerStringStyle.ExtendedInterpolated, _, _, _) :: _
| (_, LexerStringStyle.TripleQuote, _, _, _) :: _ -> ()
| (_, LexerStringStyle.ExtendedInterpolated, _, _) :: _
| (_, LexerStringStyle.TripleQuote, _, _) :: _ -> ()
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
| [] -> ()

if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, LexerStringKind.String, args.interpolationDelimiterLength, m))
else singleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }

| '$' '"' '"' '"'
{ let buf, fin, m = startString args lexbuf None
{ let buf, fin, m = startString args lexbuf

// Single quote in triple quote ok, others disallowed
match args.stringNest with
Expand All @@ -612,7 +612,7 @@ rule token (args: LexArgs) (skip: bool) = parse
else tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf }

| ('$'+) '"' '"' '"'
{ let buf, fin, m = startString args lexbuf None
{ let buf, fin, m = startString args lexbuf

if lexbuf.SupportsFeature LanguageFeature.ExtendedStringInterpolation then
// Single quote in triple quote ok, others disallowed
Expand All @@ -635,11 +635,11 @@ rule token (args: LexArgs) (skip: bool) = parse
}

| '$' '"'
{ let buf,fin,m = startString args lexbuf None
{ let buf,fin,m = startString args lexbuf

// Single quote in triple quote ok, others disallowed
match args.stringNest with
| (_, style, _, _, _) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
| (_, style, _, _) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
| _ -> ()

Expand All @@ -649,7 +649,7 @@ rule token (args: LexArgs) (skip: bool) = parse
singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf }

| '"' '"' '"'
{ let buf, fin, m = startString args lexbuf None
{ let buf, fin, m = startString args lexbuf

args.interpolationDelimiterLength <- 0

Expand All @@ -664,12 +664,12 @@ rule token (args: LexArgs) (skip: bool) = parse
tripleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }

| '@' '"'
{ let buf, fin, m = startString args lexbuf None
{ let buf, fin, m = startString args lexbuf

// Single quote in triple quote ok, others disallowed
match args.stringNest with
| (_, LexerStringStyle.ExtendedInterpolated, _, _, _) :: _
| (_, LexerStringStyle.TripleQuote, _, _, _) :: _ -> ()
| (_, LexerStringStyle.ExtendedInterpolated, _, _) :: _
| (_, LexerStringStyle.TripleQuote, _, _) :: _ -> ()
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
| _ -> ()

Expand All @@ -679,11 +679,11 @@ rule token (args: LexArgs) (skip: bool) = parse
verbatimString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }

| ("$@" | "@$") '"'
{ let buf, fin, m = startString args lexbuf None
{ let buf, fin, m = startString args lexbuf

// Single quote in triple quote ok, others disallowed
match args.stringNest with
| (_, style, _, _, _) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
| (_, style, _, _) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
| _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
| _ -> ()

Expand Down Expand Up @@ -888,33 +888,48 @@ rule token (args: LexArgs) (skip: bool) = parse
{
match args.stringNest with
| [] -> ()
| (counter, style, d, _, m) :: rest ->
| (counter, style, d, m) :: rest ->
// Note, we do not update the 'm', any incomplete-interpolation error
// will be reported w.r.t. the first '{'
args.stringNest <- (counter + 1, style, d, None, m) :: rest
args.stringNest <- (counter + 1, style, d, m) :: rest
// To continue token-by-token lexing may involve picking up the new args.stringNes
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
LBRACE cont
}

| "|" { BAR }

| "}" +
{
match args.stringNest with
| (1, style, _, _r) :: rest ->
args.stringNest <- rest
let buf, fin, m = startString args lexbuf
if not skip then
STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, style, LexerStringKind.InterpolatedStringPart, args.interpolationDelimiterLength, m))
else
match style with
| LexerStringStyle.Verbatim -> verbatimString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
| LexerStringStyle.SingleQuote -> singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
| LexerStringStyle.TripleQuote -> tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
| LexerStringStyle.ExtendedInterpolated -> extendedInterpolatedString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
| (counter, style, d, m) :: rest ->
// Note, we do not update the 'm', any incomplete-interpolation error
// will be reported w.r.t. the first '{'
args.stringNest <- (counter - 1, style, d, m) :: rest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
RBRACE cont
| _ ->
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
RBRACE cont
}

| "}"
{
// We encounter a '}' in the expression token stream. First check if we're in an interpolated string expression
// and continue the string if necessary
match args.stringNest with
| (1, LexerStringStyle.ExtendedInterpolated, delimLength, altR, r) :: rest when delimLength > 1 ->
// On the first "}" of multiple "}", keep the range of the starting "}" for later processing in startString
let altStart =
match altR with
| None -> Some lexbuf.LexemeRange
| _ -> altR
args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, delimLength - 1, altStart, r) :: rest
token args skip lexbuf
| (1, style, _, altR, _r) :: rest ->
| (1, style, _, _r) :: rest ->
args.stringNest <- rest
let buf, fin, m = startString args lexbuf altR
let buf, fin, m = startString args lexbuf
if not skip then
STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, style, LexerStringKind.InterpolatedStringPart, args.interpolationDelimiterLength, m))
else
Expand All @@ -923,10 +938,10 @@ rule token (args: LexArgs) (skip: bool) = parse
| LexerStringStyle.SingleQuote -> singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
| LexerStringStyle.TripleQuote -> tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
| LexerStringStyle.ExtendedInterpolated -> extendedInterpolatedString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
| (counter, style, d, altR, m) :: rest ->
| (counter, style, d, m) :: rest ->
// Note, we do not update the 'm', any incomplete-interpolation error
// will be reported w.r.t. the first '{'
args.stringNest <- (counter - 1, style, d, altR, m) :: rest
args.stringNest <- (counter - 1, style, d, m) :: rest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
RBRACE cont

Expand Down Expand Up @@ -1264,7 +1279,7 @@ and singleQuoteString (sargs: LexerStringArgs) (skip: bool) = parse
if kind.IsInterpolated then
// get a new range for where the fill starts
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.SingleQuote, args.interpolationDelimiterLength, None, m2) :: args.stringNest
args.stringNest <- (1, LexerStringStyle.SingleQuote, args.interpolationDelimiterLength, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
fin.Finish buf kind LexerStringFinisherContext.InterpolatedPart cont
else
Expand Down Expand Up @@ -1380,7 +1395,7 @@ and verbatimString (sargs: LexerStringArgs) (skip: bool) = parse
if kind.IsInterpolated then
// get a new range for where the fill starts
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.Verbatim, args.interpolationDelimiterLength, None, m2) :: args.stringNest
args.stringNest <- (1, LexerStringStyle.Verbatim, args.interpolationDelimiterLength, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
fin.Finish buf kind (LexerStringFinisherContext.InterpolatedPart ||| LexerStringFinisherContext.Verbatim) cont
else
Expand Down Expand Up @@ -1499,7 +1514,7 @@ and tripleQuoteString (sargs: LexerStringArgs) (skip: bool) = parse
if kind.IsInterpolated then
// get a new range for where the fill starts
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.TripleQuote, args.interpolationDelimiterLength, None, m2) :: args.stringNest
args.stringNest <- (1, LexerStringStyle.TripleQuote, args.interpolationDelimiterLength, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
fin.Finish buf kind (LexerStringFinisherContext.InterpolatedPart ||| LexerStringFinisherContext.TripleQuote) cont
else
Expand Down Expand Up @@ -1604,7 +1619,7 @@ and extendedInterpolatedString (sargs: LexerStringArgs) (skip: bool) = parse
let maxBraces = 2 * args.interpolationDelimiterLength - 1
if numBraces > maxBraces then
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, None, m2) :: args.stringNest
args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
fail args lexbuf
(FSComp.SR.lexTooManyLBracesInTripleQuote())
Expand All @@ -1625,7 +1640,7 @@ and extendedInterpolatedString (sargs: LexerStringArgs) (skip: bool) = parse
String.replicate extraBraces "{" |> addUnicodeString buf
// get a new range for where the fill starts
let m2 = lexbuf.LexemeRange
args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, None, m2) :: args.stringNest
args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, m2) :: args.stringNest
let cont = LexCont.Token(args.ifdefStack, args.stringNest)
fin.Finish buf kind (LexerStringFinisherContext.InterpolatedPart ||| LexerStringFinisherContext.TripleQuote) cont
}
Expand Down
Loading

0 comments on commit 4d01cda

Please sign in to comment.