From ec2ac4d736e85f394c937703bd0e3c0090aa2350 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 5 Mar 2024 15:23:58 +0100 Subject: [PATCH 1/4] Completion: don't prevent getting items after record definition --- src/Compiler/Service/ServiceParsedInputOps.fs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index f1a8d3e9737..d3808e688b7 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1644,16 +1644,22 @@ module ParsedInput = | SynType.LongIdent _ when rangeContainsPos ty.Range pos -> Some CompletionContext.Type | _ -> defaultTraverse ty - member _.VisitRecordDefn(_, fields, _) = + member _.VisitRecordDefn(_, fields, range) = fields |> List.tryPick (fun (SynField(idOpt = idOpt; range = fieldRange)) -> match idOpt with | Some id when rangeContainsPos id.idRange pos -> Some(CompletionContext.RecordField(RecordContext.Declaration true)) | _ when rangeContainsPos fieldRange pos -> Some(CompletionContext.RecordField(RecordContext.Declaration false)) - | _ -> None) + | _ -> None + ) // No completions in a record outside of all fields, except in attributes, which is established earlier in VisitAttributeApplication - |> Option.orElse (Some CompletionContext.Invalid) + |> Option.orElseWith (fun _ -> + if rangeContainsPos range pos then + Some CompletionContext.Invalid + else + None + ) member _.VisitUnionDefn(_, cases, _) = cases From c9366464320e23c1f8479dd305057e30cbe52918 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 5 Mar 2024 15:28:58 +0100 Subject: [PATCH 2/4] 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 35cb6319ddc..a7fbc893457 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)) +* Fix broken code completion after a record type declaration ([PR #16813]([Title](https://github.com/dotnet/fsharp/pull/16813))) ### Added From a13c2d319dfba1069ad9bde1fcbd5975bcd6b562 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 5 Mar 2024 11:51:15 -0400 Subject: [PATCH 3/4] Fantomas --- src/Compiler/Service/ServiceParsedInputOps.fs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index d3808e688b7..90062e81c68 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -1651,15 +1651,13 @@ module ParsedInput = | Some id when rangeContainsPos id.idRange pos -> Some(CompletionContext.RecordField(RecordContext.Declaration true)) | _ when rangeContainsPos fieldRange pos -> Some(CompletionContext.RecordField(RecordContext.Declaration false)) - | _ -> None - ) + | _ -> None) // No completions in a record outside of all fields, except in attributes, which is established earlier in VisitAttributeApplication |> Option.orElseWith (fun _ -> if rangeContainsPos range pos then Some CompletionContext.Invalid else - None - ) + None) member _.VisitUnionDefn(_, cases, _) = cases From 39c3b7978a9ef3904fd84e9ab542b0258efa2ced Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Fri, 8 Mar 2024 11:52:10 -0400 Subject: [PATCH 4/4] Add test --- tests/service/CompletionTests.fs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/service/CompletionTests.fs b/tests/service/CompletionTests.fs index 349647e0fa3..f973c434377 100644 --- a/tests/service/CompletionTests.fs +++ b/tests/service/CompletionTests.fs @@ -17,6 +17,15 @@ let assertHasItemWithNames names (completionInfo: DeclarationListInfo) = for name in names do Assert.That(Set.contains name itemNames, $"{name} not found in {itemNames}") +[] +let ``Expr - After record decl`` () = + let info = getCompletionInfo "{ Fi }" (4, 0) """ +type Record = { Field: int } + + +""" + assertHasItemWithNames ["ignore"] info + [] let ``Expr - record - field 01 - anon module`` () = let info = getCompletionInfo "{ Fi }" (4, 3) """