Skip to content

Commit 2b64f21

Browse files
authored
Include range of attributes in parent (implementation files) (#11495)
1 parent 63b14da commit 2b64f21

File tree

12 files changed

+304
-44
lines changed

12 files changed

+304
-44
lines changed

src/fsharp/pars.fsy

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ let mkClassMemberLocalBindings(isStatic, initialRangeOpt, attrs, vis, BindingSet
156156
match initialRangeOpt with
157157
| None -> bindingSetRange
158158
| Some m -> unionRanges m bindingSetRange
159+
// decls could have a leading attribute
160+
|> fun m -> (m, decls) ||> unionRangeWithListBy (fun (SynBinding(range = m)) -> m)
159161
if not (isNil ignoredFreeAttrs) then warning(Error(FSComp.SR.parsAttributesIgnored(), wholeRange));
160162
if isUse then errorR(Error(FSComp.SR.parsUseBindingsIllegalInImplicitClassConstructors(), wholeRange))
161163
SynMemberDefn.LetBindings (decls, isStatic, isRec, wholeRange)
@@ -167,7 +169,9 @@ let mkLocalBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs,
167169

168170
let mkDefnBindings (mWhole, BindingSetPreAttrs(_, isRec, isUse, declsPreAttrs, _bindingSetRange), attrs, vis, attrsm) =
169171
if isUse then warning(Error(FSComp.SR.parsUseBindingsIllegalInModules(), mWhole))
170-
let freeAttrs, decls = declsPreAttrs attrs vis
172+
let freeAttrs, decls = declsPreAttrs attrs vis
173+
// decls might have an extended range due to leading attributes
174+
let mWhole = (mWhole, decls) ||> unionRangeWithListBy (fun (SynBinding(range = m)) -> m)
171175
let letDecls = [ SynModuleDecl.Let (isRec, decls, mWhole) ]
172176
let attrDecls = if not (isNil freeAttrs) then [ SynModuleDecl.Attributes (freeAttrs, attrsm) ] else []
173177
attrDecls @ letDecls
@@ -1292,7 +1296,9 @@ moduleDefn:
12921296
| opt_attributes opt_declVisibility typeKeyword tyconDefn tyconDefnList
12931297
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
12941298
let (SynTypeDefn(SynComponentInfo(cas, a, cs, b, c, d, d2, d3), e, f, g, h)) = $4
1295-
let tc = (SynTypeDefn(SynComponentInfo($1@cas, a, cs, b, c, d, d2, d3), e, f, g, h))
1299+
let attrs = $1@cas
1300+
let mTc = (h, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
1301+
let tc = (SynTypeDefn(SynComponentInfo(attrs, a, cs, b, c, d, d2, d3), e, f, g, mTc))
12961302
let types = tc :: $5
12971303
[ SynModuleDecl.Types(types, (rhs parseState 3, types) ||> unionRangeWithListBy (fun t -> t.Range) ) ] }
12981304

@@ -1717,7 +1723,8 @@ memberCore:
17171723
let bindingBuilder, mBindLhs = $2
17181724
(fun vis memFlagsBuilder attrs rangeStart ->
17191725
let memberFlags = Some (memFlagsBuilder SynMemberKind.Member)
1720-
let binding = bindingBuilder (vis, $1, false, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags)
1726+
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
1727+
let binding = bindingBuilder (vis, $1, false, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, $5, mRhs, [], attrs, memberFlags)
17211728
let memberRange = unionRanges rangeStart mRhs
17221729
[ SynMemberDefn.Member (binding, memberRange) ]) }
17231730

@@ -1794,7 +1801,8 @@ memberCore:
17941801
// REDO with the correct member kind
17951802
let binding = bindingBuilder(vis, isInline, isMutable, mBindLhs, DebugPointAtBinding.NoneAtInvisible, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder memberKind))
17961803

1797-
let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, rhsRetInfo, rhsExpr, mBindLhs, spBind)) = binding
1804+
let (SynBinding (vis, _, isInline, _, attrs, doc, valSynData, pv, rhsRetInfo, rhsExpr, mBindLhs, spBind)) = binding
1805+
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
17981806

17991807
let (SynValData(_, valSynInfo, _)) = valSynData
18001808

@@ -1811,37 +1819,37 @@ memberCore:
18111819
match memberKind, valSynInfo, memFlags.IsInstance with
18121820
| SynMemberKind.PropertyGet, SynValInfo ([], _ret), false
18131821
| SynMemberKind.PropertyGet, SynValInfo ([_], _ret), true ->
1814-
raiseParseErrorAt mBindLhs (FSComp.SR.parsGetterMustHaveAtLeastOneArgument())
1822+
raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterMustHaveAtLeastOneArgument())
18151823

18161824
| SynMemberKind.PropertyGet, SynValInfo (thisArg :: indexOrUnitArgs :: rest, ret), true ->
18171825
if not rest.IsEmpty then
1818-
reportParseErrorAt mBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
1826+
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
18191827
SynValInfo ([thisArg; indexOrUnitArgs], ret)
18201828

18211829
| SynMemberKind.PropertyGet, SynValInfo (indexOrUnitArgs :: rest, ret), false ->
18221830
if not rest.IsEmpty then
1823-
reportParseErrorAt mBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
1831+
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsGetterAtMostOneArgument ())
18241832
SynValInfo ([indexOrUnitArgs], ret)
18251833

18261834
| SynMemberKind.PropertySet, SynValInfo ([thisArg;valueArg], ret), true ->
18271835
SynValInfo ([thisArg; adjustValueArg valueArg], ret)
18281836

18291837
| SynMemberKind.PropertySet, SynValInfo (thisArg :: indexArgs :: valueArg :: rest, ret), true ->
18301838
if not rest.IsEmpty then
1831-
reportParseErrorAt mBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
1839+
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
18321840
SynValInfo ([thisArg; indexArgs @ adjustValueArg valueArg], ret)
18331841

18341842
| SynMemberKind.PropertySet, SynValInfo ([valueArg], ret), false ->
18351843
SynValInfo ([adjustValueArg valueArg], ret)
18361844

18371845
| SynMemberKind.PropertySet, SynValInfo (indexArgs :: valueArg :: rest, ret), _ ->
18381846
if not rest.IsEmpty then
1839-
reportParseErrorAt mBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
1847+
reportParseErrorAt mWholeBindLhs (FSComp.SR.parsSetterAtMostTwoArguments ())
18401848
SynValInfo ([indexArgs @ adjustValueArg valueArg], ret)
18411849

18421850
| _ ->
18431851
// should be unreachable, cover just in case
1844-
raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidProperty ())
1852+
raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidProperty ())
18451853

18461854
let valSynData = SynValData(Some(memFlags), valSynInfo, None)
18471855

@@ -1851,15 +1859,15 @@ memberCore:
18511859

18521860
let bindingPatAdjusted, xmlDocAdjusted =
18531861

1854-
let bindingOuter = propertyNameBindingBuilder(vis, optInline, isMutable, mBindLhs, spBind, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder SynMemberKind.Member))
1862+
let bindingOuter = propertyNameBindingBuilder(vis, optInline, isMutable, mWholeBindLhs, spBind, optReturnType, expr, exprm, [], attrs, Some(memFlagsBuilder SynMemberKind.Member))
18551863

18561864
let (SynBinding (_, _, _, _, _, doc2, _, bindingPatOuter, _, _, _, _)) = bindingOuter
18571865

18581866
let lidOuter, lidVisOuter =
18591867
match bindingPatOuter with
18601868
| SynPat.LongIdent (lid, None, None, SynArgPats.Pats [], lidVisOuter, m) -> lid, lidVisOuter
18611869
| SynPat.Named (_, id, _, visOuter, m) -> LongIdentWithDots([id], []), visOuter
1862-
| p -> raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidDeclarationSyntax())
1870+
| p -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax())
18631871

18641872
// Merge the visibility from the outer point with the inner point, e.g.
18651873
// member <VIS1> this.Size with <VIS2> get () = m_size
@@ -1869,7 +1877,7 @@ memberCore:
18691877
| None, None -> None
18701878
| Some lidVisInner, None | None, Some lidVisInner -> Some lidVisInner
18711879
| Some _, Some _ ->
1872-
errorR(Error(FSComp.SR.parsMultipleAccessibilitiesForGetSet(), mBindLhs))
1880+
errorR(Error(FSComp.SR.parsMultipleAccessibilitiesForGetSet(), mWholeBindLhs))
18731881
lidVisInner
18741882

18751883
// Replace the "get" or the "set" with the right name
@@ -1897,11 +1905,11 @@ memberCore:
18971905
| SynPat.Typed (p, ty, m) -> SynPat.Typed(go p, ty, m)
18981906
| SynPat.Attrib (p, attribs, m) -> SynPat.Attrib(go p, attribs, m)
18991907
| SynPat.Wild(m) -> SynPat.Wild(m)
1900-
| _ -> raiseParseErrorAt mBindLhs (FSComp.SR.parsInvalidDeclarationSyntax())
1908+
| _ -> raiseParseErrorAt mWholeBindLhs (FSComp.SR.parsInvalidDeclarationSyntax())
19011909

19021910
go pv, PreXmlDoc.Merge doc2 doc
19031911

1904-
let binding = SynBinding (vis, SynBindingKind.Normal, isInline, isMutable, attrs, xmlDocAdjusted, valSynData, bindingPatAdjusted, rhsRetInfo, rhsExpr, mBindLhs, spBind)
1912+
let binding = SynBinding (vis, SynBindingKind.Normal, isInline, isMutable, attrs, xmlDocAdjusted, valSynData, bindingPatAdjusted, rhsRetInfo, rhsExpr, mWholeBindLhs, spBind)
19051913
let memberRange = unionRanges rangeStart mWhole
19061914
Some (SynMemberDefn.Member (binding, memberRange))))
19071915
}
@@ -1976,14 +1984,15 @@ classDefnMember:
19761984
$4 $1 isStatic flags rangeStart }
19771985

19781986
| opt_attributes opt_declVisibility NEW atomicPattern optAsSpec EQUALS typedSeqExprBlock opt_ODECLEND
1979-
{ let m = unionRanges (rhs2 parseState 1 6) $7.Range
1987+
{ let mWholeBindLhs = rhs2 parseState 1 (if Option.isSome $5 then 5 else 4)
1988+
let m = unionRanges mWholeBindLhs $7.Range
19801989
let expr = $7
19811990
let valSynData = SynValData (Some CtorMemberFlags, SynValInfo([SynInfo.InferSynArgInfoFromPat $4], SynInfo.unnamedRetVal), $5)
19821991
let vis = $2
19831992
let declPat = SynPat.LongIdent (LongIdentWithDots([mkSynId (rhs parseState 3) "new"], []), None, Some noInferredTypars, SynArgPats.Pats [$4], vis, rhs parseState 3)
19841993
// Check that 'SynPatForConstructorDecl' matches this correctly
19851994
assert (match declPat with SynPatForConstructorDecl _ -> true | _ -> false)
1986-
[ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, grabXmlDoc(parseState, 3), valSynData, declPat, None, expr, m, DebugPointAtBinding.NoneAtInvisible), m) ] }
1995+
[ SynMemberDefn.Member(SynBinding (None, SynBindingKind.Normal, false, false, $1, grabXmlDoc(parseState, 3), valSynData, declPat, None, expr, mWholeBindLhs, DebugPointAtBinding.NoneAtInvisible), m) ] }
19871996

19881997
| opt_attributes opt_declVisibility STATIC typeKeyword tyconDefn
19891998
{ if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2))
@@ -2802,9 +2811,10 @@ localBinding:
28022811
let localBindingRange = unionRanges (rhs2 parseState 1 5) mRhs
28032812
let localBindingBuilder =
28042813
(fun attrs vis mLetKwd ->
2805-
let mWhole = unionRanges mLetKwd mRhs
2814+
let mWhole = (unionRanges mLetKwd mRhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
28062815
let spBind = if IsControlFlowExpression expr then DebugPointAtBinding.NoneAtLet else DebugPointAtBinding.Yes mWhole
2807-
bindingBuilder (vis, $1, $2, mBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None))
2816+
let mWholeBindLhs = (mBindLhs, attrs) ||> unionRangeWithListBy (fun (a: SynAttributeList) -> a.Range)
2817+
bindingBuilder (vis, $1, $2, mWholeBindLhs, spBind, optReturnType, expr, mRhs, opts, attrs, None))
28082818
localBindingRange, localBindingBuilder }
28092819

28102820
| opt_inline opt_mutable bindingPattern opt_topReturnTypeWithTypeConstraints EQUALS error

src/fsharp/service/ServiceStructure.fs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,9 +443,8 @@ module Structure =
443443
| SynBindingKind.Normal ->
444444
let collapse = Range.endToEnd binding.RangeOfBindingWithoutRhs binding.RangeOfBindingWithRhs
445445
match memberFlags with
446-
| Some ({MemberKind=SynMemberKind.Constructor}) ->
447-
let collapse = Range.startToEnd expr.Range br
448-
rcheck Scope.New Collapse.Below br collapse
446+
| Some {MemberKind=SynMemberKind.Constructor} ->
447+
rcheck Scope.New Collapse.Below binding.RangeOfBindingWithRhs collapse
449448
| Some _ ->
450449
rcheck Scope.Member Collapse.Below binding.RangeOfBindingWithRhs collapse
451450
| None ->

tests/FSharp.Compiler.ComponentTests/ErrorMessages/InvalidLiteralTests.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ let [<Literal>] (A x) = 1
1515
"""
1616
|> typecheck
1717
|> shouldFail
18-
|> withSingleDiagnostic (Error 3391, Line 3, Col 17, Line 3, Col 22, "A [<Literal>] declaration cannot use an active pattern for its identifier")
18+
|> withSingleDiagnostic (Error 3391, Line 3, Col 5, Line 3, Col 22, "A [<Literal>] declaration cannot use an active pattern for its identifier")

tests/fsharp/typecheck/sigs/neg10.bsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ neg10.fs(16,32,16,34): typecheck error FS1207: Interfaces inherited by other int
1515

1616
neg10.fs(17,28,17,30): typecheck error FS0887: The type 'C1' is not an interface type
1717

18-
neg10.fs(19,17,19,28): typecheck error FS0870: Structs cannot have an object constructor with no arguments. This is a restriction imposed on all CLI languages as structs automatically support a default constructor.
18+
neg10.fs(19,17,19,22): typecheck error FS0870: Structs cannot have an object constructor with no arguments. This is a restriction imposed on all CLI languages as structs automatically support a default constructor.
1919

2020
neg10.fs(21,16,21,46): typecheck error FS0001: A generic construct requires that the type 'System.Enum' have a public default constructor
2121

tests/fsharp/typecheck/sigs/neg16.bsl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,24 @@ neg16.fs(90,8,90,18): typecheck error FS0039: The pattern discriminator 'FooB++'
7373

7474
neg16.fs(90,7,90,22): typecheck error FS0025: Incomplete pattern matches on this expression.
7575

76-
neg16.fs(97,15,97,16): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
76+
neg16.fs(96,3,97,16): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
7777

78-
neg16.fs(100,11,100,14): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
78+
neg16.fs(99,3,100,14): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
7979

80-
neg16.fs(100,11,100,14): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
80+
neg16.fs(99,3,100,14): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
8181

82-
neg16.fs(103,7,103,9): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
82+
neg16.fs(102,3,103,9): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
8383

84-
neg16.fs(103,7,103,9): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
84+
neg16.fs(102,3,103,9): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
8585

8686
neg16.fs(119,17,119,24): typecheck error FS0823: The 'VolatileField' attribute may only be used on 'let' bindings in classes
8787

88-
neg16.fs(107,16,107,19): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
88+
neg16.fs(106,5,107,19): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
8989

90-
neg16.fs(110,16,110,20): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
90+
neg16.fs(109,5,110,20): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
9191

92-
neg16.fs(113,9,113,11): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
92+
neg16.fs(112,5,113,11): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
9393

94-
neg16.fs(116,9,116,13): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
94+
neg16.fs(115,5,116,13): typecheck error FS0879: Volatile fields must be marked 'mutable' and cannot be thread-static
9595

9696
neg16.fs(130,10,130,11): typecheck error FS0935: Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal

tests/fsharp/typecheck/sigs/neg20.bsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ neg20.fs(195,5,195,10): typecheck error FS0842: This attribute is not valid for
305305

306306
neg20.fs(198,5,198,11): typecheck error FS0842: This attribute is not valid for use on this language element
307307

308-
neg20.fs(202,7,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations
308+
neg20.fs(201,3,202,9): typecheck error FS0825: The 'DefaultValue' attribute may only be used on 'val' declarations
309309

310310
neg20.fs(204,5,204,14): typecheck error FS0842: This attribute is not valid for use on this language element
311311

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
neg47.fs(18,9,18,26): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module
33

4-
neg47.fs(24,12,24,33): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module
4+
neg47.fs(23,5,24,33): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module
55

6-
neg47.fs(29,16,29,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module
6+
neg47.fs(28,9,29,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module
77

8-
neg47.fs(33,12,33,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module
8+
neg47.fs(32,5,33,27): typecheck error FS1221: DLLImport bindings must be static members in a class or function definitions in a module

tests/fsharpqa/Source/Conformance/DeclarationElements/CustomAttributes/Basic/E_StructLayout.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// #Regression #Conformance #DeclarationElements #Attributes
22
// Tests to ensure that you can't use StructLayout inappropriately
33
// Regression tests for FSHARP1.0:5931
4-
//<Expects status="error" span="(14,1-15,1)" id="FS1206">The type 'SExplicitBroken' has been marked as having an Explicit layout, but the field 'v2' has not been marked with the 'FieldOffset' attribute$</Expects>
5-
//<Expects status="error" span="(24,1-25,1)" id="FS1211">The FieldOffset attribute can only be placed on members of types marked with the StructLayout\(LayoutKind\.Explicit\)$</Expects>
4+
//<Expects status="error" span="(12,1-13,1)" id="FS1206">The type 'SExplicitBroken' has been marked as having an Explicit layout, but the field 'v2' has not been marked with the 'FieldOffset' attribute$</Expects>
5+
//<Expects status="error" span="(22,1-23,1)" id="FS1211">The FieldOffset attribute can only be placed on members of types marked with the StructLayout\(LayoutKind\.Explicit\)$</Expects>
66

77
module M
88

tests/fsharpqa/Source/Conformance/SpecialAttributesAndTypes/Imported/System.ThreadStatic/W_Deprecated01.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// #Regression #Conformance #Attributes
22
// Regression test for FSHARP1.0:4226
33
// We want to make sure the warning emits the correct suggestion (val and mutable were swapped)
4-
//<Expects status="errors" span="(8,9-8,10)" id="FS0056">Thread static and context static 'let' bindings are deprecated\. Instead use a declaration of the form 'static val mutable <ident> : <type>' in a class\. Add the 'DefaultValue' attribute to this declaration to indicate that the value is initialized to the default value on each new thread\.$</Expects>
4+
//<Expects status="errors" span="(7,5-8,10)" id="FS0056">Thread static and context static 'let' bindings are deprecated\. Instead use a declaration of the form 'static val mutable <ident> : <type>' in a class\. Add the 'DefaultValue' attribute to this declaration to indicate that the value is initialized to the default value on each new thread\.$</Expects>
55
module M
66
module Foo =
77
[<System.ThreadStatic>]

0 commit comments

Comments
 (0)