Skip to content

Commit 8a363c4

Browse files
authored
Range of SynExprRecordField should include the expression (#18617)
1 parent 4853ba3 commit 8a363c4

26 files changed

+195
-46
lines changed

docs/release-notes/.FSharp.Compiler.Service/10.0.100.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Fix parsing errors using anonymous records and units of measures ([PR #18543](https://github.com/dotnet/fsharp/pull/18543))
44
* Fixed: Allow `return`, `return!`, `yield`, `yield!` type annotations without parentheses ([PR #18533](https://github.com/dotnet/fsharp/pull/18533))
5+
* Range of `SynExprRecordField` should include the expression ([PR #18617](https://github.com/dotnet/fsharp/pull/18617))
56
* Allow `let!` and `use!` type annotations without requiring parentheses ([PR #18508](https://github.com/dotnet/fsharp/pull/18508))
67
* Fix find all references for F# exceptions ([PR #18565](https://github.com/dotnet/fsharp/pull/18565))
78
* Shorthand lambda: fix completion for chained calls and analysis for unfinished expression ([PR #18560](https://github.com/dotnet/fsharp/pull/18560))

src/Compiler/Checking/CheckRecordSyntaxHelpers.fs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,13 @@ let TransformAstForNestedUpdates (cenv: TcFileState) (env: TcEnv) overallTy (lid
129129
| _ ->
130130
let fields =
131131
[
132-
SynExprRecordField((LongIdentWithDots([ fieldId ], []), true), None, Some nestedField, None)
132+
SynExprRecordField(
133+
(LongIdentWithDots([ fieldId ], []), true),
134+
None,
135+
Some nestedField,
136+
unionRanges fieldId.idRange nestedField.Range,
137+
None
138+
)
133139
]
134140

135141
SynExpr.Record(None, copyInfo outerFieldId, fields, outerFieldId.idRange)

src/Compiler/SyntaxTree/ParseHelpers.fs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -704,10 +704,31 @@ let patFromParseError (e: SynPat) = SynPat.FromParseError(e, e.Range)
704704
// to form
705705
// binding1*sep1, binding2*sep2
706706
let rebindRanges first fields lastSep =
707-
let rec run (name, mEquals, value) l acc =
707+
let calculateFieldRange (lidwd: SynLongIdent) (mEquals: range option) (value: SynExpr option) =
708+
match lidwd with
709+
| SynLongIdent([], _, _) ->
710+
// Special case used in inherit clause
711+
match mEquals, value with
712+
| Some mEq, Some expr -> unionRanges mEq expr.Range
713+
| Some mEq, None -> mEq
714+
| None, Some expr -> expr.Range
715+
| None, None -> range0
716+
| _ ->
717+
// Normal case
718+
match value with
719+
| Some expr -> unionRanges lidwd.Range expr.Range
720+
| None ->
721+
match mEquals with
722+
| Some mEq -> unionRanges lidwd.Range mEq
723+
| None -> lidwd.Range
724+
725+
let rec run (name, mEquals, value: SynExpr option) l acc =
726+
let lidwd, _ = name
727+
let fieldRange = calculateFieldRange lidwd mEquals value
728+
708729
match l with
709-
| [] -> List.rev (SynExprRecordField(name, mEquals, value, lastSep) :: acc)
710-
| (f, m) :: xs -> run f xs (SynExprRecordField(name, mEquals, value, m) :: acc)
730+
| [] -> List.rev (SynExprRecordField(name, mEquals, value, fieldRange, lastSep) :: acc)
731+
| (f, m) :: xs -> run f xs (SynExprRecordField(name, mEquals, value, fieldRange, m) :: acc)
711732

712733
run first fields []
713734

src/Compiler/SyntaxTree/SyntaxTree.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,7 @@ type SynExprRecordField =
896896
fieldName: RecordFieldName *
897897
equalsRange: range option *
898898
expr: SynExpr option *
899+
range: range *
899900
blockSeparator: BlockSeparator option
900901

901902
[<NoEquality; NoComparison; RequireQualifiedAccess>]

src/Compiler/SyntaxTree/SyntaxTree.fsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,7 @@ type SynExprRecordField =
999999
fieldName: RecordFieldName *
10001000
equalsRange: range option *
10011001
expr: SynExpr option *
1002+
range: range *
10021003
blockSeparator: BlockSeparator option
10031004

10041005
[<NoEquality; NoComparison; RequireQualifiedAccess>]

src/Compiler/pars.fsy

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5624,7 +5624,7 @@ recdExpr:
56245624
let l = List.rev $5
56255625
let dummyField = mkRecdField (SynLongIdent([], [], [])) // dummy identifier, it will be discarded
56265626
let l = rebindRanges (dummyField, None, None) l $6
5627-
let (SynExprRecordField(_, _, _, inheritsSep)) = List.head l
5627+
let (SynExprRecordField(_, _, _, _, inheritsSep)) = List.head l
56285628
let bindings = List.tail l
56295629
(Some($2, arg, rhs2 parseState 2 4, inheritsSep, rhs parseState 1), None, bindings) }
56305630

@@ -5666,7 +5666,7 @@ recdExprCore:
56665666
reportParseErrorAt m (FSComp.SR.parsUnderscoreInvalidFieldName())
56675667
reportParseErrorAt m (FSComp.SR.parsFieldBinding())
56685668
let f = mkUnderscoreRecdField m
5669-
(None, [ SynExprRecordField(f, None, None, None) ]) }
5669+
(None, [ SynExprRecordField(f, None, None, m, None) ]) }
56705670

56715671
| UNDERSCORE EQUALS
56725672
{ let m = rhs parseState 1
@@ -5675,7 +5675,7 @@ recdExprCore:
56755675
let mEquals = rhs parseState 2
56765676
reportParseErrorAt (rhs2 parseState 1 2) (FSComp.SR.parsFieldBinding())
56775677

5678-
(None, [ SynExprRecordField(f, Some mEquals, None, None) ]) }
5678+
(None, [ SynExprRecordField(f, Some mEquals, None, (rhs2 parseState 1 2), None) ]) }
56795679

56805680
| UNDERSCORE EQUALS declExprBlock recdExprBindings opt_seps_recd
56815681
{ reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnderscoreInvalidFieldName())
@@ -5860,9 +5860,9 @@ braceBarExprCore:
58605860
{ let orig, flds = $2
58615861
let flds =
58625862
flds |> List.choose (function
5863-
| SynExprRecordField((synLongIdent, _), mEquals, Some e, _) when orig.IsSome -> Some(synLongIdent, mEquals, e) // copy-and-update, long identifier signifies nesting
5864-
| SynExprRecordField((SynLongIdent([ _id ], _, _) as synLongIdent, _), mEquals, Some e, _) -> Some(synLongIdent, mEquals, e) // record construction, long identifier not valid
5865-
| SynExprRecordField((synLongIdent, _), mEquals, None, _) -> Some(synLongIdent, mEquals, arbExpr ("anonField", synLongIdent.Range))
5863+
| SynExprRecordField((synLongIdent, _), mEquals, Some e, _, _) when orig.IsSome -> Some(synLongIdent, mEquals, e) // copy-and-update, long identifier signifies nesting
5864+
| SynExprRecordField((SynLongIdent([ _id ], _, _) as synLongIdent, _), mEquals, Some e, _, _) -> Some(synLongIdent, mEquals, e) // record construction, long identifier not valid
5865+
| SynExprRecordField((synLongIdent, _), mEquals, None, _, _) -> Some(synLongIdent, mEquals, arbExpr ("anonField", synLongIdent.Range))
58665866
| _ -> reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsInvalidAnonRecdType()); None)
58675867
let mLeftBrace = rhs parseState 1
58685868
let mRightBrace = rhs parseState 3
@@ -5875,8 +5875,8 @@ braceBarExprCore:
58755875
let orig, flds = $2
58765876
let flds =
58775877
flds |> List.map (function
5878-
| SynExprRecordField((synLongIdent, _), mEquals, Some e, _) -> (synLongIdent, mEquals, e)
5879-
| SynExprRecordField((synLongIdent, _), mEquals, None, _) -> (synLongIdent, mEquals, arbExpr ("anonField", synLongIdent.Range)))
5878+
| SynExprRecordField((synLongIdent, _), mEquals, Some e, _, _) -> (synLongIdent, mEquals, e)
5879+
| SynExprRecordField((synLongIdent, _), mEquals, None, _, _) -> (synLongIdent, mEquals, arbExpr ("anonField", synLongIdent.Range)))
58805880
let mLeftBrace = rhs parseState 1
58815881
let mExpr = rhs parseState 2
58825882
(fun (mStruct: range option) ->

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7888,7 +7888,9 @@ FSharp.Compiler.Syntax.SynExprAndBang: Int32 Tag
78887888
FSharp.Compiler.Syntax.SynExprAndBang: Int32 get_Tag()
78897889
FSharp.Compiler.Syntax.SynExprAndBang: System.String ToString()
78907890
FSharp.Compiler.Syntax.SynExprModule: Boolean shouldBeParenthesizedInContext(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.SynExpr)
7891-
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Syntax.SynExprRecordField NewSynExprRecordField(System.Tuple`2[FSharp.Compiler.Syntax.SynLongIdent,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]])
7891+
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Syntax.SynExprRecordField NewSynExprRecordField(System.Tuple`2[FSharp.Compiler.Syntax.SynLongIdent,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]])
7892+
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Text.Range get_range()
7893+
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Text.Range range
78927894
FSharp.Compiler.Syntax.SynExprRecordField: Int32 Tag
78937895
FSharp.Compiler.Syntax.SynExprRecordField: Int32 get_Tag()
78947896
FSharp.Compiler.Syntax.SynExprRecordField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] expr

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7888,7 +7888,9 @@ FSharp.Compiler.Syntax.SynExprAndBang: Int32 Tag
78887888
FSharp.Compiler.Syntax.SynExprAndBang: Int32 get_Tag()
78897889
FSharp.Compiler.Syntax.SynExprAndBang: System.String ToString()
78907890
FSharp.Compiler.Syntax.SynExprModule: Boolean shouldBeParenthesizedInContext(Microsoft.FSharp.Core.FSharpFunc`2[System.Int32,System.String], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SyntaxNode], FSharp.Compiler.Syntax.SynExpr)
7891-
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Syntax.SynExprRecordField NewSynExprRecordField(System.Tuple`2[FSharp.Compiler.Syntax.SynLongIdent,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]])
7891+
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Syntax.SynExprRecordField NewSynExprRecordField(System.Tuple`2[FSharp.Compiler.Syntax.SynLongIdent,System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr], FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[FSharp.Compiler.Text.Range,Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Position]]])
7892+
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Text.Range get_range()
7893+
FSharp.Compiler.Syntax.SynExprRecordField: FSharp.Compiler.Text.Range range
78927894
FSharp.Compiler.Syntax.SynExprRecordField: Int32 Tag
78937895
FSharp.Compiler.Syntax.SynExprRecordField: Int32 get_Tag()
78947896
FSharp.Compiler.Syntax.SynExprRecordField: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.SynExpr] expr

tests/service/data/SyntaxTree/Expression/CopySynExprRecordContainsTheRangeOfTheEqualsSignInSynExprRecordField.fs.bsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ ImplFile
1212
(None, Some (Ident foo, ((2,6--2,10), None)),
1313
[SynExprRecordField
1414
((SynLongIdent ([X], [], [None]), true), Some (4,12--4,13),
15-
Some (Const (Int32 12, (5,16--5,18))), None)], (2,0--5,20)),
16-
(2,0--5,20))], PreXmlDocEmpty, [], None, (2,0--5,20),
17-
{ LeadingKeyword = None })], (true, true),
15+
Some (Const (Int32 12, (5,16--5,18))), (3,8--5,18), None)],
16+
(2,0--5,20)), (2,0--5,20))], PreXmlDocEmpty, [], None,
17+
(2,0--5,20), { LeadingKeyword = None })], (true, true),
1818
{ ConditionalDirectives = []
1919
WarnDirectives = []
2020
CodeComments = [] }, set []))
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Foo
2+
3+
{ inherit Exception(
4+
"This is a " +
5+
"multiline " +
6+
"message"
7+
)
8+
X = 42
9+
Y = "test"
10+
}

0 commit comments

Comments
 (0)