@@ -120,7 +120,7 @@ let checkExprGreaterColonOp (lexbuf:UnicodeLexing.Lexbuf) =
120120let unexpectedChar lexbuf =
121121 LEX_FAILURE (FSComp.SR.lexUnexpectedChar(lexeme lexbuf))
122122
123- let startString args (lexbuf: UnicodeLexing.Lexbuf) =
123+ let startString args (lexbuf: UnicodeLexing.Lexbuf) altStartForStringEnd =
124124 let buf = ByteBuffer.Create StringCapacity
125125 let m = lexbuf.LexemeRange
126126 let startp = lexbuf.StartPos
@@ -160,7 +160,7 @@ let startString args (lexbuf: UnicodeLexing.Lexbuf) =
160160 if isPart then
161161 INTERP_STRING_PART (s, cont)
162162 else
163- INTERP_STRING_END (s, cont)
163+ INTERP_STRING_END (s, altStartForStringEnd, cont)
164164 else
165165 let s = Lexhelp.stringBufferAsString buf
166166 let synStringKind =
@@ -587,20 +587,20 @@ rule token (args: LexArgs) (skip: bool) = parse
587587 else mlOnly m args skip lexbuf }
588588
589589 | '"'
590- { let buf, fin, m = startString args lexbuf
590+ { let buf, fin, m = startString args lexbuf None
591591
592592 // Single quote in triple quote ok, others disallowed
593593 match args.stringNest with
594- | (_, LexerStringStyle.ExtendedInterpolated, _, _) :: _
595- | (_, LexerStringStyle.TripleQuote, _, _) :: _ -> ()
594+ | (_, LexerStringStyle.ExtendedInterpolated, _, _, _ ) :: _
595+ | (_, LexerStringStyle.TripleQuote, _, _, _ ) :: _ -> ()
596596 | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
597597 | [] -> ()
598598
599599 if not skip then STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, LexerStringStyle.SingleQuote, LexerStringKind.String, args.interpolationDelimiterLength, m))
600600 else singleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }
601601
602602 | '$' '"' '"' '"'
603- { let buf, fin, m = startString args lexbuf
603+ { let buf, fin, m = startString args lexbuf None
604604
605605 // Single quote in triple quote ok, others disallowed
606606 match args.stringNest with
@@ -612,7 +612,7 @@ rule token (args: LexArgs) (skip: bool) = parse
612612 else tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf }
613613
614614 | ('$'+) '"' '"' '"'
615- { let buf, fin, m = startString args lexbuf
615+ { let buf, fin, m = startString args lexbuf None
616616
617617 if lexbuf.SupportsFeature LanguageFeature.ExtendedStringInterpolation then
618618 // Single quote in triple quote ok, others disallowed
@@ -635,11 +635,11 @@ rule token (args: LexArgs) (skip: bool) = parse
635635 }
636636
637637 | '$' '"'
638- { let buf,fin,m = startString args lexbuf
638+ { let buf,fin,m = startString args lexbuf None
639639
640640 // Single quote in triple quote ok, others disallowed
641641 match args.stringNest with
642- | (_, style, _, _) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
642+ | (_, style, _, _, _ ) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
643643 | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
644644 | _ -> ()
645645
@@ -649,7 +649,7 @@ rule token (args: LexArgs) (skip: bool) = parse
649649 singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringFirst, args) skip lexbuf }
650650
651651 | '"' '"' '"'
652- { let buf, fin, m = startString args lexbuf
652+ { let buf, fin, m = startString args lexbuf None
653653
654654 args.interpolationDelimiterLength <- 0
655655
@@ -664,12 +664,12 @@ rule token (args: LexArgs) (skip: bool) = parse
664664 tripleQuoteString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }
665665
666666 | '@' '"'
667- { let buf, fin, m = startString args lexbuf
667+ { let buf, fin, m = startString args lexbuf None
668668
669669 // Single quote in triple quote ok, others disallowed
670670 match args.stringNest with
671- | (_, LexerStringStyle.ExtendedInterpolated, _, _) :: _
672- | (_, LexerStringStyle.TripleQuote, _, _) :: _ -> ()
671+ | (_, LexerStringStyle.ExtendedInterpolated, _, _, _ ) :: _
672+ | (_, LexerStringStyle.TripleQuote, _, _, _ ) :: _ -> ()
673673 | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
674674 | _ -> ()
675675
@@ -679,11 +679,11 @@ rule token (args: LexArgs) (skip: bool) = parse
679679 verbatimString (buf, fin, m, LexerStringKind.String, args) skip lexbuf }
680680
681681 | ("$@" | "@$") '"'
682- { let buf, fin, m = startString args lexbuf
682+ { let buf, fin, m = startString args lexbuf None
683683
684684 // Single quote in triple quote ok, others disallowed
685685 match args.stringNest with
686- | (_, style, _, _) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
686+ | (_, style, _, _, _ ) :: _ when style = LexerStringStyle.ExtendedInterpolated || style = LexerStringStyle.TripleQuote -> ()
687687 | _ :: _ -> errorR(Error(FSComp.SR.lexSingleQuoteInSingleQuote(), m))
688688 | _ -> ()
689689
@@ -888,10 +888,10 @@ rule token (args: LexArgs) (skip: bool) = parse
888888 {
889889 match args.stringNest with
890890 | [] -> ()
891- | (counter, style, d, m) :: rest ->
891+ | (counter, style, d, _, m) :: rest ->
892892 // Note, we do not update the 'm', any incomplete-interpolation error
893893 // will be reported w.r.t. the first '{'
894- args.stringNest <- (counter + 1, style, d, m) :: rest
894+ args.stringNest <- (counter + 1, style, d, None, m) :: rest
895895 // To continue token-by-token lexing may involve picking up the new args.stringNes
896896 let cont = LexCont.Token(args.ifdefStack, args.stringNest)
897897 LBRACE cont
@@ -904,12 +904,17 @@ rule token (args: LexArgs) (skip: bool) = parse
904904 // We encounter a '}' in the expression token stream. First check if we're in an interpolated string expression
905905 // and continue the string if necessary
906906 match args.stringNest with
907- | (1, LexerStringStyle.ExtendedInterpolated, delimLength, r) :: rest when delimLength > 1 ->
908- args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, delimLength - 1, r) :: rest
907+ | (1, LexerStringStyle.ExtendedInterpolated, delimLength, altR, r) :: rest when delimLength > 1 ->
908+ // On the first "}" of multiple "}", keep the range of the starting "}" for later processing in startString
909+ let altStart =
910+ match altR with
911+ | None -> Some lexbuf.LexemeRange
912+ | _ -> altR
913+ args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, delimLength - 1, altStart, r) :: rest
909914 token args skip lexbuf
910- | (1, style, _, _ ) :: rest ->
915+ | (1, style, _, altR, _r ) :: rest ->
911916 args.stringNest <- rest
912- let buf, fin, m = startString args lexbuf
917+ let buf, fin, m = startString args lexbuf altR
913918 if not skip then
914919 STRING_TEXT (LexCont.String(args.ifdefStack, args.stringNest, style, LexerStringKind.InterpolatedStringPart, args.interpolationDelimiterLength, m))
915920 else
@@ -918,11 +923,10 @@ rule token (args: LexArgs) (skip: bool) = parse
918923 | LexerStringStyle.SingleQuote -> singleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
919924 | LexerStringStyle.TripleQuote -> tripleQuoteString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
920925 | LexerStringStyle.ExtendedInterpolated -> extendedInterpolatedString (buf, fin, m, LexerStringKind.InterpolatedStringPart, args) skip lexbuf
921-
922- | (counter, style, d, m) :: rest ->
926+ | (counter, style, d, altR, m) :: rest ->
923927 // Note, we do not update the 'm', any incomplete-interpolation error
924928 // will be reported w.r.t. the first '{'
925- args.stringNest <- (counter - 1, style, d, m) :: rest
929+ args.stringNest <- (counter - 1, style, d, altR, m) :: rest
926930 let cont = LexCont.Token(args.ifdefStack, args.stringNest)
927931 RBRACE cont
928932
@@ -1260,7 +1264,7 @@ and singleQuoteString (sargs: LexerStringArgs) (skip: bool) = parse
12601264 if kind.IsInterpolated then
12611265 // get a new range for where the fill starts
12621266 let m2 = lexbuf.LexemeRange
1263- args.stringNest <- (1, LexerStringStyle.SingleQuote, args.interpolationDelimiterLength, m2) :: args.stringNest
1267+ args.stringNest <- (1, LexerStringStyle.SingleQuote, args.interpolationDelimiterLength, None, m2) :: args.stringNest
12641268 let cont = LexCont.Token(args.ifdefStack, args.stringNest)
12651269 fin.Finish buf kind LexerStringFinisherContext.InterpolatedPart cont
12661270 else
@@ -1376,7 +1380,7 @@ and verbatimString (sargs: LexerStringArgs) (skip: bool) = parse
13761380 if kind.IsInterpolated then
13771381 // get a new range for where the fill starts
13781382 let m2 = lexbuf.LexemeRange
1379- args.stringNest <- (1, LexerStringStyle.Verbatim, args.interpolationDelimiterLength, m2) :: args.stringNest
1383+ args.stringNest <- (1, LexerStringStyle.Verbatim, args.interpolationDelimiterLength, None, m2) :: args.stringNest
13801384 let cont = LexCont.Token(args.ifdefStack, args.stringNest)
13811385 fin.Finish buf kind (LexerStringFinisherContext.InterpolatedPart ||| LexerStringFinisherContext.Verbatim) cont
13821386 else
@@ -1495,7 +1499,7 @@ and tripleQuoteString (sargs: LexerStringArgs) (skip: bool) = parse
14951499 if kind.IsInterpolated then
14961500 // get a new range for where the fill starts
14971501 let m2 = lexbuf.LexemeRange
1498- args.stringNest <- (1, LexerStringStyle.TripleQuote, args.interpolationDelimiterLength, m2) :: args.stringNest
1502+ args.stringNest <- (1, LexerStringStyle.TripleQuote, args.interpolationDelimiterLength, None, m2) :: args.stringNest
14991503 let cont = LexCont.Token(args.ifdefStack, args.stringNest)
15001504 fin.Finish buf kind (LexerStringFinisherContext.InterpolatedPart ||| LexerStringFinisherContext.TripleQuote) cont
15011505 else
@@ -1600,7 +1604,7 @@ and extendedInterpolatedString (sargs: LexerStringArgs) (skip: bool) = parse
16001604 let maxBraces = 2 * args.interpolationDelimiterLength - 1
16011605 if numBraces > maxBraces then
16021606 let m2 = lexbuf.LexemeRange
1603- args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, m2) :: args.stringNest
1607+ args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, None, m2) :: args.stringNest
16041608 let cont = LexCont.Token(args.ifdefStack, args.stringNest)
16051609 fail args lexbuf
16061610 (FSComp.SR.lexTooManyLBracesInTripleQuote())
@@ -1621,7 +1625,7 @@ and extendedInterpolatedString (sargs: LexerStringArgs) (skip: bool) = parse
16211625 String.replicate extraBraces "{" |> addUnicodeString buf
16221626 // get a new range for where the fill starts
16231627 let m2 = lexbuf.LexemeRange
1624- args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, m2) :: args.stringNest
1628+ args.stringNest <- (1, LexerStringStyle.ExtendedInterpolated, args.interpolationDelimiterLength, None, m2) :: args.stringNest
16251629 let cont = LexCont.Token(args.ifdefStack, args.stringNest)
16261630 fin.Finish buf kind (LexerStringFinisherContext.InterpolatedPart ||| LexerStringFinisherContext.TripleQuote) cont
16271631 }
0 commit comments