未验证 提交 e389d774 编写于 作者: F Florian Verdonck 提交者: GitHub

Correct SynAttribute range (#13998)

* Add failing test.

* Update range for SynAttribute.

* Use unionRanges instead of mkFileIndexRange.

* Update ranges in unit tests.

* Fix ServiceTests.

* Update failing FSharpSuite.Tests.

* Update negative tests.

* Trigger CI
上级 ffdfc716
......@@ -581,7 +581,7 @@ module ParsedInput =
|> Option.orElseWith (fun () -> ifPosInRange r (fun _ -> List.tryPick (walkSynModuleDecl isTopLevel) decls))
and walkAttribute (attr: SynAttribute) =
if isPosInRange attr.Range then
if isPosInRange attr.TypeName.Range then
Some EntityKind.Attribute
else
None
......
......@@ -1561,18 +1561,23 @@ attributeListElements:
attribute:
/* A custom attribute */
| path opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
{ let arg = match $3 with None -> mkSynUnit $1.Range | Some e -> e
({ TypeName=$1; ArgExpr=arg; Target=None; AppliesToGetterAndSetter=false; Range=$1.Range } : SynAttribute) }
{ let arg = match $3 with None -> mkSynUnit $1.Range | Some e -> e
let m = unionRanges $1.Range arg.Range
({ TypeName=$1; ArgExpr=arg; Target=None; AppliesToGetterAndSetter=false; Range=m } : SynAttribute) }
/* A custom attribute with an attribute target */
| attributeTarget path opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
{ let arg = match $4 with None -> mkSynUnit $2.Range | Some e -> e
({ TypeName=$2; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=$2.Range } : SynAttribute) }
{ let arg = match $4 with None -> mkSynUnit $2.Range | Some e -> e
let startRange = match $1 with Some (ident:Ident) -> ident.idRange | None -> $2.Range
let m = unionRanges startRange arg.Range
({ TypeName=$2; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=m } : SynAttribute) }
/* A custom attribute with an attribute target */
| attributeTarget OBLOCKBEGIN path oblockend opt_HIGH_PRECEDENCE_APP opt_atomicExprAfterType
{ let arg = match $6 with None -> mkSynUnit $3.Range | Some e -> e
({ TypeName=$3; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=$3.Range } : SynAttribute) }
let startRange = match $1 with Some ident -> ident.idRange | None -> $3.Range
let m = unionRanges startRange arg.Range
({ TypeName=$3; ArgExpr=arg; Target=$1; AppliesToGetterAndSetter=false; Range=m } : SynAttribute) }
/* The target of a custom attribute */
......
......@@ -17,7 +17,7 @@ module Diags =
|> compile
|> shouldFail
|> withDiagnostics [
(Error 501, Line 7, Col 3, Line 7, Col 23, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
(Error 501, Line 7, Col 3, Line 7, Col 30, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
// SOURCE=E_AdjustUses01b.fs SCFLAGS=--test:ErrorRanges # E_AdjustUses01b.fs
......@@ -28,6 +28,6 @@ module Diags =
|> compile
|> shouldFail
|> withDiagnostics [
(Error 501, Line 7, Col 3, Line 7, Col 23, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
(Error 501, Line 7, Col 3, Line 7, Col 30, "The object constructor 'StructuralComparisonAttribute' takes 0 argument(s) but is here given 1. The required signature is 'new: unit -> StructuralComparisonAttribute'.")
]
......@@ -79,8 +79,8 @@ module AttributeUsage =
|> shouldFail
|> withDiagnostics [
(Error 842, Line 21, Col 21, Line 21, Col 22, "This attribute is not valid for use on this language element")
(Error 842, Line 24, Col 28, Line 24, Col 29, "This attribute is not valid for use on this language element")
(Error 842, Line 27, Col 15, Line 27, Col 16, "This attribute is not valid for use on this language element")
(Error 842, Line 24, Col 21, Line 24, Col 29, "This attribute is not valid for use on this language element")
(Error 842, Line 27, Col 7, Line 27, Col 16, "This attribute is not valid for use on this language element")
]
// SOURCE=E_AttributeTargets02.fs # E_AttributeTargets02.fs
......@@ -90,9 +90,9 @@ module AttributeUsage =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 842, Line 14, Col 17, Line 14, Col 34, "This attribute is not valid for use on this language element")
(Error 842, Line 24, Col 14, Line 24, Col 29, "This attribute is not valid for use on this language element")
(Error 842, Line 29, Col 25, Line 29, Col 40, "This attribute is not valid for use on this language element")
(Error 842, Line 14, Col 7, Line 14, Col 34, "This attribute is not valid for use on this language element")
(Error 842, Line 24, Col 7, Line 24, Col 36, "This attribute is not valid for use on this language element")
(Error 842, Line 29, Col 15, Line 29, Col 47, "This attribute is not valid for use on this language element")
]
// SOURCE=E_ConditionalAttribute.fs SCFLAGS="--test:ErrorRanges" # E_ConditionalAttribute.fs
......
......@@ -41,7 +41,7 @@ module Basic =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 841, Line 7, Col 12, Line 7, Col 49, "This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module.")
(Error 841, Line 7, Col 3, Line 7, Col 111, "This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module.")
]
// SOURCE=E_AttributeApplication02.fs SCFLAGS="--test:ErrorRanges" # E_AttributeApplication02.fs
......@@ -106,8 +106,8 @@ module Basic =
(Error 1, Line 10, Col 3, Line 10, Col 59, "This expression was expected to have type\n 'int array' \nbut here has type\n 'unit' ")
(Error 267, Line 10, Col 3, Line 10, Col 59, "This is not a valid constant expression or custom attribute value")
(Error 850, Line 10, Col 3, Line 10, Col 59, "This attribute cannot be used in this version of F#")
(Error 850, Line 13, Col 3, Line 13, Col 52, "This attribute cannot be used in this version of F#")
(Error 850, Line 16, Col 13, Line 16, Col 37, "This attribute cannot be used in this version of F#")
(Error 850, Line 13, Col 3, Line 13, Col 101, "This attribute cannot be used in this version of F#")
(Error 850, Line 16, Col 3, Line 16, Col 50, "This attribute cannot be used in this version of F#")
]
// SOURCE=E_AttributeTargetSpecifications.fs # E_AttributeTargetSpecifications.fs
......@@ -305,7 +305,7 @@ module Basic =
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 429, Line 16, Col 28, Line 16, Col 31, "The attribute type 'CA1' has 'AllowMultiple=false'. Multiple instances of this attribute cannot be attached to a single language element.")
(Error 429, Line 16, Col 28, Line 16, Col 37, "The attribute type 'CA1' has 'AllowMultiple=false'. Multiple instances of this attribute cannot be attached to a single language element.")
]
// SOURCE=W_StructLayoutExplicit01.fs SCFLAGS="--test:ErrorRanges" PEVER="/Exp_Fail" # W_StructLayoutExplicit01.fs
......
......@@ -53,9 +53,9 @@ module Basic =
|> shouldFail
|> withDiagnostics [
(Error 683, Line 14, Col 6, Line 14, Col 27, "Attributes are not allowed within patterns")
(Error 842, Line 14, Col 8, Line 14, Col 23, "This attribute is not valid for use on this language element")
(Error 842, Line 14, Col 8, Line 14, Col 25, "This attribute is not valid for use on this language element")
(Error 683, Line 14, Col 42, Line 14, Col 63, "Attributes are not allowed within patterns")
(Error 842, Line 14, Col 44, Line 14, Col 59, "This attribute is not valid for use on this language element")
(Error 842, Line 14, Col 44, Line 14, Col 61, "This attribute is not valid for use on this language element")
]
// SOURCE=E_ErrorsForInlineValue.fs SCFLAGS="--test:ErrorRanges" # E_ErrorsForInlineValue.fs
......
......@@ -27,7 +27,7 @@ type C() =
Range = { StartLine = 3
StartColumn = 13
EndLine = 3
EndColumn = 37 }
EndColumn = 41 }
Message =
"This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
{ Error = Warning 202
......@@ -41,7 +41,7 @@ type C() =
Range = { StartLine = 6
StartColumn = 22
EndLine = 6
EndColumn = 78 }
EndColumn = 82 }
Message =
"This attribute is currently unsupported by the F# compiler. Applying it will not achieve its intended effect." }
{ Error = Warning 202
......
......@@ -119,6 +119,9 @@
<Compile Include="..\service\SyntaxTreeTests\SynIdentTests.fs">
<Link>SyntaxTree\SynIdentTests.fs</Link>
</Compile>
<Compile Include="..\service\SyntaxTreeTests\AttributeTests.fs">
<Link>SyntaxTree\AttributeTests.fs</Link>
</Compile>
<Compile Include="..\service\FileSystemTests.fs">
<Link>FileSystemTests.fs</Link>
</Compile>
......
......@@ -271,7 +271,7 @@ neg20.fs(216,5,216,12): typecheck error FS0842: This attribute is not valid for
neg20.fs(219,5,219,15): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(222,5,222,24): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(222,5,222,31): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(225,5,225,22): typecheck error FS0842: This attribute is not valid for use on this language element
......@@ -289,9 +289,9 @@ neg20.fs(243,5,243,23): typecheck error FS0842: This attribute is not valid for
neg20.fs(249,9,249,27): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(255,5,255,21): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(255,5,255,28): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(258,5,258,31): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(258,5,258,38): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(261,5,261,17): typecheck error FS0842: This attribute is not valid for use on this language element
......@@ -299,7 +299,7 @@ neg20.fs(265,5,265,24): typecheck error FS0842: This attribute is not valid for
neg20.fs(268,5,268,27): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(271,5,271,13): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(271,5,271,15): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(278,14,278,95): typecheck error FS0507: No accessible member or object constructor named 'ProcessStartInfo' takes 0 arguments. Note the call to this member also provides 2 named arguments.
......
neg31.fs(9,6,9,30): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(9,6,9,64): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(71,12,71,36): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(71,12,71,70): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(107,13,107,41): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(107,13,107,48): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(28,6,28,30): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(28,6,28,64): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(93,14,93,42): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(93,14,93,49): typecheck error FS1200: The attribute 'CLSCompliantAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(47,6,47,30): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg31.fs(47,6,47,64): typecheck error FS1200: The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code.
neg32.fs(17,21,17,49): typecheck error FS0842: This attribute is not valid for use on this language element
neg32.fs(17,11,17,56): typecheck error FS0842: This attribute is not valid for use on this language element
neg32.fs(24,15,24,16): typecheck error FS0043: The member or object constructor 'TryParse' does not take 1 argument(s). An overload was found taking 2 arguments.
......
......@@ -319,7 +319,7 @@ neg20.fs(216,5,216,12): typecheck error FS0842: This attribute is not valid for
neg20.fs(219,5,219,15): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(222,5,222,24): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(222,5,222,31): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(225,5,225,22): typecheck error FS0842: This attribute is not valid for use on this language element
......@@ -337,9 +337,9 @@ neg20.fs(243,5,243,23): typecheck error FS0842: This attribute is not valid for
neg20.fs(249,9,249,27): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(255,5,255,21): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(255,5,255,28): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(258,5,258,31): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(258,5,258,38): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(261,5,261,17): typecheck error FS0842: This attribute is not valid for use on this language element
......@@ -347,7 +347,7 @@ neg20.fs(265,5,265,24): typecheck error FS0842: This attribute is not valid for
neg20.fs(268,5,268,27): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(271,5,271,13): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(271,5,271,15): typecheck error FS0842: This attribute is not valid for use on this language element
neg20.fs(278,14,278,95): typecheck error FS0507: No accessible member or object constructor named 'ProcessStartInfo' takes 0 arguments. Note the call to this member also provides 2 named arguments.
......
// #Conformance #SignatureFiles #Attributes #Regression
// Regression for 6446 - verifying spec matches implementation when fs/fsi files attributes differ
//<Expects status="error" id="FS1200" span="(17,7-17,15)">The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.</Expects>
//<Expects status="error" id="FS1200" span="(17,7-17,23)">The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.</Expects>
module M
......
// #Conformance #SignatureFiles #Attributes #Regression
// Regression for 6446 - verifying spec matches implementation when fs/fsi files attributes differ
//<Expects status="error" id="FS1200" span="(17,7-17,15)">The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.</Expects>
//<Expects status="error" id="FS1200" span="(17,7-17,23)">The attribute 'ObsoleteAttribute' appears in both the implementation and the signature, but the attribute arguments differ\. Only the attribute from the signature will be included in the compiled code\.</Expects>
module M
......
// #Regression #Misc
// Regression test for FSHARP1.0:5936
// This test ensures that you can't apply the CompiledName attribute more than once to a property
//<Expects status="error" span="(29,16-29,28)" id="FS0429">The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$</Expects>
//<Expects status="error" span="(30,15-30,27)" id="FS0429">The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$</Expects>
//<Expects status="error" span="(29,16-29,39)" id="FS0429">The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$</Expects>
//<Expects status="error" span="(30,15-30,38)" id="FS0429">The attribute type 'CompiledNameAttribute' has 'AllowMultiple=false'\. Multiple instances of this attribute cannot be attached to a single language element\.$</Expects>
module M
type T() =
......
......@@ -46,7 +46,7 @@ match () with
assertHasSymbolUsages ["x"; "y"; "CompiledNameAttribute"] checkResults
dumpDiagnostics checkResults |> shouldEqual [
"(3,2--3,25): Attributes are not allowed within patterns"
"(3,4--3,16): This attribute is not valid for use on this language element"
"(3,4--3,23): This attribute is not valid for use on this language element"
]
......
module FSharp.Compiler.Service.Tests.SyntaxTreeTests.AttributeTests
open FSharp.Compiler.Service.Tests.Common
open FSharp.Compiler.Syntax
open NUnit.Framework
[<Test>]
let ``range of attribute`` () =
let ast =
"""
[<MyAttribute(foo ="bar")>]
do ()
"""
|> getParseResults
match ast with
| ParsedInput.ImplFile (ParsedImplFileInput(contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls =
[ SynModuleDecl.Attributes(attributes = [ { Attributes = [ { Range = mAttribute } ] } ]) ; SynModuleDecl.Expr _ ] ) ])) ->
assertRange (2, 2) (2, 25) mAttribute
| _ -> Assert.Fail $"Could not get valid AST, got {ast}"
[<Test>]
let ``range of attribute with path`` () =
let ast =
"""
[<Prefix.MyAttribute(foo ="bar")>]
do ()
"""
|> getParseResults
match ast with
| ParsedInput.ImplFile (ParsedImplFileInput(contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls =
[ SynModuleDecl.Attributes(attributes = [ { Attributes = [ { Range = mAttribute } ] } ]) ; SynModuleDecl.Expr _ ] ) ])) ->
assertRange (2, 2) (2, 32) mAttribute
| _ -> Assert.Fail $"Could not get valid AST, got {ast}"
[<Test>]
let ``range of attribute with target`` () =
let ast =
"""
[<assembly: MyAttribute(foo ="bar")>]
do ()
"""
|> getParseResults
match ast with
| ParsedInput.ImplFile (ParsedImplFileInput(contents = [ SynModuleOrNamespace.SynModuleOrNamespace(decls =
[ SynModuleDecl.Attributes(attributes = [ { Attributes = [ { Range = mAttribute } ] } ]) ; SynModuleDecl.Expr _ ] ) ])) ->
assertRange (2, 2) (2, 35) mAttribute
| _ -> Assert.Fail $"Could not get valid AST, got {ast}"
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册