diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index abfb08252d7..56f71544b59 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -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)) diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index bc967f30dbe..424f3297a11 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -35,7 +35,7 @@ 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", 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 LPAREN = tagOfToken LPAREN let RPAREN = tagOfToken RPAREN @@ -491,7 +491,7 @@ 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) | LBRACE cont diff --git a/src/Compiler/SyntaxTree/LexHelpers.fs b/src/Compiler/SyntaxTree/LexHelpers.fs index 5ee9a16c90b..00bdd86cf1a 100644 --- a/src/Compiler/SyntaxTree/LexHelpers.fs +++ b/src/Compiler/SyntaxTree/LexHelpers.fs @@ -188,7 +188,7 @@ type LexerStringFinisher = else INTERP_STRING_BEGIN_END(s, synStringKind, cont) else if isPart then - INTERP_STRING_PART(s, cont) + INTERP_STRING_PART(s, None, cont) else INTERP_STRING_END(s, None, cont) elif kind.IsByteString then diff --git a/src/Compiler/lex.fsl b/src/Compiler/lex.fsl index 958c2fa51ea..a5499b2efbc 100644 --- a/src/Compiler/lex.fsl +++ b/src/Compiler/lex.fsl @@ -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) altStartForStringEnd = +let startString args (lexbuf: UnicodeLexing.Lexbuf) altStartForStringPartOrEnd = let buf = ByteBuffer.Create StringCapacity let m = lexbuf.LexemeRange let startp = lexbuf.StartPos @@ -158,9 +158,9 @@ let startString args (lexbuf: UnicodeLexing.Lexbuf) altStartForStringEnd = INTERP_STRING_BEGIN_END (s, synStringKind, cont) else if isPart then - INTERP_STRING_PART (s, cont) + INTERP_STRING_PART (s, altStartForStringPartOrEnd, cont) else - INTERP_STRING_END (s, altStartForStringEnd, cont) + INTERP_STRING_END (s, altStartForStringPartOrEnd, cont) else let s = Lexhelp.stringBufferAsString buf let synStringKind = diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 36e8d0838c8..bd46ab5711e 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -37,7 +37,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token STRING %token INTERP_STRING_BEGIN_END %token INTERP_STRING_BEGIN_PART -%token INTERP_STRING_PART +%token INTERP_STRING_PART %token INTERP_STRING_END %token LBRACE RBRACE @@ -6784,13 +6784,25 @@ interpolatedStringParts: [ SynInterpolatedStringPart.String(s, m) ] } | INTERP_STRING_PART interpolatedStringFill interpolatedStringParts - { SynInterpolatedStringPart.String(fst $1, rhs parseState 1) :: SynInterpolatedStringPart.FillExpr $2 :: $3 } + { let (s, altStart, _) = $1 + let mOrig = rhs parseState 1 + let m = + match altStart with + | Some r -> unionRanges r mOrig + | None -> mOrig + SynInterpolatedStringPart.String(s, m) :: 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 } + let (s, altStart, _) = $1 + let mOrig = rhs parseState 1 + let m = + match altStart with + | Some r -> unionRanges r mOrig + | None -> mOrig + SynInterpolatedStringPart.String(s, m) :: $2 } /* INTERP_STRING_BEGIN_END */ /* INTERP_STRING_BEGIN_PART int32 INTERP_STRING_END */ diff --git a/tests/service/data/SyntaxTree/String/SynExprInterpolatedStringWithTripleQuoteMultipleDollars.fs.bsl b/tests/service/data/SyntaxTree/String/SynExprInterpolatedStringWithTripleQuoteMultipleDollars.fs.bsl index e59b33d951a..db6d4bcdc96 100644 --- a/tests/service/data/SyntaxTree/String/SynExprInterpolatedStringWithTripleQuoteMultipleDollars.fs.bsl +++ b/tests/service/data/SyntaxTree/String/SynExprInterpolatedStringWithTripleQuoteMultipleDollars.fs.bsl @@ -18,7 +18,7 @@ ImplFile InterpolatedString ([String ("1 + ", (2,8--2,21)); FillExpr (Const (Int32 41, (2,21--2,23)), None); - String (" = ", (2,25--2,32)); + String (" = ", (2,23--2,32)); FillExpr (Const (Int32 6, (2,32--2,33)), None); String (" * 7", (2,33--2,43))], TripleQuote, (2,8--2,43)), (2,4--2,5), Yes (2,0--2,43), { LeadingKeyword = Let (2,0--2,3)