From e160014695334c92768dc951ab4d88dcacb94cb1 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 6 Mar 2024 16:12:46 -0400 Subject: [PATCH 1/3] Parser: fix pattern range for idents with trivia --- src/Compiler/SyntaxTree/SyntaxTree.fs | 14 +++++++++- src/Compiler/SyntaxTree/SyntaxTree.fsi | 5 +++- src/Compiler/pars.fsy | 3 +- .../data/SyntaxTree/ModuleMember/Let 05.fs | 3 ++ .../SyntaxTree/ModuleMember/Let 05.fs.bsl | 28 +++++++++++++++++++ ...ePatternDefinitionWithoutParameters.fs.bsl | 4 +-- 6 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 tests/service/data/SyntaxTree/ModuleMember/Let 05.fs create mode 100644 tests/service/data/SyntaxTree/ModuleMember/Let 05.fs.bsl diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 8b034740be4..a97976bee5c 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -16,7 +16,19 @@ type Ident(text: string, range: range) = member _.idRange = range override _.ToString() = text -type SynIdent = SynIdent of ident: Ident * trivia: IdentTrivia option +type SynIdent = + | SynIdent of ident: Ident * trivia: IdentTrivia option + + member this.Range = + match this with + | SynIdent(ident, trivia) -> + match trivia with + | Some value -> + match value with + | IdentTrivia.OriginalNotationWithParen(leftParen, _, rightParen) + | IdentTrivia.HasParenthesis(leftParen, rightParen) -> unionRanges leftParen rightParen + | _ -> ident.idRange + | None -> ident.idRange type LongIdent = Ident list diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index 3d9ef06dcad..fa88b48004d 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -16,7 +16,10 @@ type Ident = member idRange: range /// Represents an identifier with potentially additional trivia information. -type SynIdent = SynIdent of ident: Ident * trivia: IdentTrivia option +type SynIdent = + | SynIdent of ident: Ident * trivia: IdentTrivia option + + member Range: range /// Represents a long identifier e.g. 'A.B.C' type LongIdent = Ident list diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 4080fc7ec8b..b33d55722a5 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3627,8 +3627,7 @@ atomicPattern: mkSynPatMaybeVar lidwd vis (lhs parseState) else let synIdent = List.head lidwd.IdentsWithTrivia - let (SynIdent(id, _)) = synIdent - SynPat.Named(synIdent, false, vis, id.idRange) } + SynPat.Named(synIdent, false, vis, synIdent.Range) } | constant { SynPat.Const(fst $1, snd $1) } diff --git a/tests/service/data/SyntaxTree/ModuleMember/Let 05.fs b/tests/service/data/SyntaxTree/ModuleMember/Let 05.fs new file mode 100644 index 00000000000..3d306418d47 --- /dev/null +++ b/tests/service/data/SyntaxTree/ModuleMember/Let 05.fs @@ -0,0 +1,3 @@ +let (|AP|) + +() diff --git a/tests/service/data/SyntaxTree/ModuleMember/Let 05.fs.bsl b/tests/service/data/SyntaxTree/ModuleMember/Let 05.fs.bsl new file mode 100644 index 00000000000..684cfa3cfb0 --- /dev/null +++ b/tests/service/data/SyntaxTree/ModuleMember/Let 05.fs.bsl @@ -0,0 +1,28 @@ +ImplFile + (ParsedImplFileInput + ("/root/ModuleMember/Let 05.fs", false, QualifiedNameOfFile Let 05, [], [], + [SynModuleOrNamespace + ([Let 05], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named + (SynIdent + (|AP|, Some (HasParenthesis ((1,4--1,5), (1,9--1,10)))), + false, None, (1,4--1,10)), None, + ArbitraryAfterError ("localBinding2", (1,10--1,10)), + (1,4--1,10), Yes (1,0--1,10), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = None })], (1,0--1,10)); + Expr (Const (Unit, (3,0--3,2)), (3,0--3,2))], PreXmlDocEmpty, [], + None, (1,0--3,2), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(3,0)-(3,1) parse error Incomplete structured construct at or before this point in binding. Expected '=' or other token. +(1,0)-(2,0) parse warning The declarations in this file will be placed in an implicit module 'Let 05' based on the file name 'Let 05.fs'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file. diff --git a/tests/service/data/SyntaxTree/OperatorName/PartialActivePatternDefinitionWithoutParameters.fs.bsl b/tests/service/data/SyntaxTree/OperatorName/PartialActivePatternDefinitionWithoutParameters.fs.bsl index d3f6d9d59f8..be0b81e8577 100644 --- a/tests/service/data/SyntaxTree/OperatorName/PartialActivePatternDefinitionWithoutParameters.fs.bsl +++ b/tests/service/data/SyntaxTree/OperatorName/PartialActivePatternDefinitionWithoutParameters.fs.bsl @@ -16,12 +16,12 @@ ImplFile (SynIdent (|Boolean|_|, Some (HasParenthesis ((2,4--2,5), (2,16--2,17)))), false, - None, (2,5--2,16)), None, + None, (2,4--2,17)), None, LongIdent (false, SynLongIdent ([Boolean; parse], [(2,27--2,28)], [None; None]), None, - (2,20--2,33)), (2,5--2,16), Yes (2,0--2,33), + (2,20--2,33)), (2,4--2,17), Yes (2,0--2,33), { LeadingKeyword = Let (2,0--2,3) InlineKeyword = None EqualsRange = Some (2,18--2,19) })], (2,0--2,33))], From ed39cc39f597c184bb771d1ec71afc4314ef0d6e Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 6 Mar 2024 16:25:33 -0400 Subject: [PATCH 2/3] Release notes --- docs/release-notes/.FSharp.Compiler.Service/8.0.300.md | 1 + 1 file changed, 1 insertion(+) 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 148f3734185..457d6ebc2bf 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -16,6 +16,7 @@ * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) * Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764)) * Disallow using base to invoke an abstract base method. ([Issue #13926](https://github.com/dotnet/fsharp/issues/13926), [PR #16773](https://github.com/dotnet/fsharp/pull/16773)) +* Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) ### Added From 438d1087ed86be5d27ee767dc01c6fd6cce2ae55 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 6 Mar 2024 17:30:24 -0400 Subject: [PATCH 3/3] Surface area --- .../FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl | 2 ++ ...Sharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 3c4b22f76c1..99e5d26e302 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -7529,6 +7529,8 @@ FSharp.Compiler.Syntax.SynField: System.String ToString() FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Syntax.Ident get_ident() FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Syntax.Ident ident FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Syntax.SynIdent NewSynIdent(FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTrivia.IdentTrivia]) +FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Text.Range get_Range() FSharp.Compiler.Syntax.SynIdent: Int32 Tag FSharp.Compiler.Syntax.SynIdent: Int32 get_Tag() FSharp.Compiler.Syntax.SynIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTrivia.IdentTrivia] get_trivia() diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index 3c4b22f76c1..99e5d26e302 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -7529,6 +7529,8 @@ FSharp.Compiler.Syntax.SynField: System.String ToString() FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Syntax.Ident get_ident() FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Syntax.Ident ident FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Syntax.SynIdent NewSynIdent(FSharp.Compiler.Syntax.Ident, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTrivia.IdentTrivia]) +FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Text.Range Range +FSharp.Compiler.Syntax.SynIdent: FSharp.Compiler.Text.Range get_Range() FSharp.Compiler.Syntax.SynIdent: Int32 Tag FSharp.Compiler.Syntax.SynIdent: Int32 get_Tag() FSharp.Compiler.Syntax.SynIdent: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.SyntaxTrivia.IdentTrivia] get_trivia()