From a277545b45c14c81886726d571f1d05f63ac08e0 Mon Sep 17 00:00:00 2001 From: Andrii Chebukin Date: Sun, 13 Sep 2026 20:06:15 +0200 Subject: [PATCH 1/5] Record the parameter and type parameter counts of a navigable item Navigate To orders matches that are otherwise equal by these counts for C# and VB. NavigableItem now carries them: every curried and tupled argument of the method a declaration compiles to, without the instance and without a solitary unit argument, and its explicitly declared type parameters. Co-Authored-By: Claude Opus 5 --- .../.FSharp.Compiler.Service/11.0.100.md | 1 + src/Compiler/Service/ServiceNavigation.fs | 63 ++++++++++++++++--- src/Compiler/Service/ServiceNavigation.fsi | 20 ++++-- ...iler.Service.SurfaceArea.netstandard20.bsl | 6 +- .../FSharp.Compiler.Service.Tests.fsproj | 1 + .../NavigateToTests.fs | 63 +++++++++++++++++++ 6 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 tests/FSharp.Compiler.Service.Tests/NavigateToTests.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index f383908e195..a94b11cfd88 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -169,6 +169,7 @@ * Fix signature generation (`fsc --sig`, `GenerateSignature`, `GetValSignatureText`) dropping the parentheses around a destructured or pattern-annotated tuple parameter when a sibling argument in the same curried group is named, so `(int * float) * z: string` no longer prints as the flat 3-tuple `int * float * z: string`. ([Issue #20397](https://github.com/dotnet/fsharp/issues/20397), [PR #20589](https://github.com/dotnet/fsharp/pull/20589)) ### Added +* `NavigableItem` carries `ParameterCount` and `TypeParameterCount`, the counts C# and VB give Navigate To to order matches that are otherwise equal. * FCS: add FSharpCheckFileResults.FileSignature ([PR #20478](https://github.com/dotnet/fsharp/pull/20478)) * Added the `ReraiseInComputationExpressions` language feature (`--langversion:preview`): `reraise ()` in the `with` handler of a computation expression is compiled to a rethrow through `ExceptionDispatchInfo` instead of being rejected with FS0413. ([Suggestion #660](https://github.com/fsharp/fslang-suggestions/issues/660), [RFC FS-1347](https://github.com/fsharp/fslang-design/pull/843), [PR #20405](https://github.com/dotnet/fsharp/pull/20405)) diff --git a/src/Compiler/Service/ServiceNavigation.fs b/src/Compiler/Service/ServiceNavigation.fs index f42b335da53..c09ab0c188e 100755 --- a/src/Compiler/Service/ServiceNavigation.fs +++ b/src/Compiler/Service/ServiceNavigation.fs @@ -764,10 +764,37 @@ type NavigableItem = IsSignature: bool Kind: NavigableItemKind Container: NavigableContainer + ParameterCount: int + TypeParameterCount: int } [] module NavigateTo = + let private typeParameterCountOf (typars: SynTyparDecls option) = + match typars with + | Some typars -> typars.TyparDecls.Length + | None -> 0 + + let rec private isUnitType synType = + match synType with + | SynType.LongIdent(SynLongIdent([ id ], _, _)) -> id.idText = "unit" + | SynType.Paren(innerType, _) + | SynType.WithGlobalConstraints(innerType, _, _) -> isUnitType innerType + | _ -> false + + /// The parameters of the compiled method: the parser leaves a solitary unit argument of a signature in its arity, + /// where a binding has already dropped it. + let private parameterCountOfSignature (SynValInfo(curriedArgInfos, _)) (synType: SynType) = + match curriedArgInfos, synType with + | [ [ _ ] ], SynType.Fun(argType = argType) when isUnitType argType -> 0 + | [ [ _ ] ], SynType.WithGlobalConstraints(SynType.Fun(argType = argType), _, _) when isUnitType argType -> 0 + | _ -> List.sumBy List.length curriedArgInfos + + let private parameterCountOfBinding (SynValData(memberFlags = memberFlags; valInfo = SynValInfo(curriedArgInfos, _))) = + match memberFlags, curriedArgInfos with + | Some memberFlags, _self :: argInfos when memberFlags.IsInstance -> List.sumBy List.length argInfos + | _ -> List.sumBy List.length curriedArgInfos + let GetNavigableItems (parsedInput: ParsedInput) : NavigableItem[] = let convertToDisplayName name = @@ -778,7 +805,7 @@ module NavigateTo = let result = ResizeArray() - let addLongIdent kind (lid: LongIdent) (isSignature: bool) (container: NavigableContainer) = + let addLongIdent kind (lid: LongIdent) (isSignature: bool) (container: NavigableContainer) typeParameterCount = if not lid.IsEmpty then let name = textOfLid lid @@ -789,10 +816,12 @@ module NavigateTo = IsSignature = isSignature Kind = kind Container = container + ParameterCount = 0 + TypeParameterCount = typeParameterCount } |> result.Add - let addIdent kind (id: Ident) (isSignature: bool) (container: NavigableContainer) = + let addIdentWithArity kind (id: Ident) (isSignature: bool) (container: NavigableContainer) parameterCount typeParameterCount = if not (String.IsNullOrEmpty id.idText) then let name = convertToDisplayName id.idText @@ -803,11 +832,16 @@ module NavigateTo = IsSignature = isSignature Kind = kind Container = container + ParameterCount = parameterCount + TypeParameterCount = typeParameterCount } |> result.Add + let addIdent kind id isSignature container = + addIdentWithArity kind id isSignature container 0 0 + let addModule lid isSig container = - addLongIdent NavigableItemKind.Module lid isSig container + addLongIdent NavigableItemKind.Module lid isSig container 0 let addModuleAbbreviation (id: Ident) isSig container = addIdent NavigableItemKind.ModuleAbbreviation id isSig container @@ -818,14 +852,17 @@ module NavigateTo = NavigableContainer.Container(NavigableContainerType.Exception, [ id.idText ], container) let addComponentInfo containerType kind (info: SynComponentInfo) isSig container = + let (SynComponentInfo(typeParams = typeParams)) = info let lid = info.LongIdent - addLongIdent kind lid isSig container + addLongIdent kind lid isSig container (typeParameterCountOf typeParams) NavigableContainer.Container(containerType, pathOfLid lid, container) let addValSig kind synValSig isSig container = - let (SynValSig(ident = SynIdent(id, _))) = synValSig - addIdent kind id isSig container + let (SynValSig(ident = SynIdent(id, _); explicitTypeParams = SynValTyparDecls(typars, _); synType = synType; arity = arity)) = + synValSig + + addIdentWithArity kind id isSig container (parameterCountOfSignature arity synType) (typeParameterCountOf typars) let addField synField isSig container = let (SynField(idOpt = id)) = synField @@ -863,17 +900,25 @@ module NavigateTo = | Some mf -> mapMemberKind mf.MemberKind | _ -> NavigableItemKind.ModuleValue + let typeParameterCount = + match headPat with + | SynPat.LongIdent(typarDecls = Some(SynValTyparDecls(typars, _))) -> typeParameterCountOf typars + | _ -> 0 + + let addBindingIdent id = + addIdentWithArity kind id false container (parameterCountOfBinding valData) typeParameterCount + match headPat with | SynPat.LongIdent(longDotId = SynLongIdent([ _; id ], _, _)) -> // instance members - addIdent kind id false container + addBindingIdent id | SynPat.LongIdent(longDotId = SynLongIdent([ id ], _, _)) -> // functions - addIdent kind id false container + addBindingIdent id | SynPat.Named(SynIdent(id, _), _, _, _) | SynPat.As(_, SynPat.Named(SynIdent(id, _), _, _, _), _) -> // values - addIdent kind id false container + addBindingIdent id | _ -> () let addMember valSig (memberFlags: SynMemberFlags) isSig container = diff --git a/src/Compiler/Service/ServiceNavigation.fsi b/src/Compiler/Service/ServiceNavigation.fsi index cfccd6ef20c..49475c7f93b 100755 --- a/src/Compiler/Service/ServiceNavigation.fsi +++ b/src/Compiler/Service/ServiceNavigation.fsi @@ -112,12 +112,20 @@ type NavigableContainer = member Name: string type NavigableItem = - { Name: string - NeedsBackticks: bool - Range: range - IsSignature: bool - Kind: NavigableItemKind - Container: NavigableContainer } + { + Name: string + NeedsBackticks: bool + Range: range + IsSignature: bool + Kind: NavigableItemKind + Container: NavigableContainer + /// The number of parameters of the method the declaration compiles to, as C# and VB count them to order + /// equally good Navigate To matches: every curried and tupled argument, without the instance and without a + /// solitary unit argument. + ParameterCount: int + /// The number of explicitly declared type parameters. + TypeParameterCount: int + } [] module public NavigateTo = diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl index bce0bc86e9b..357272884a2 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl @@ -3949,10 +3949,14 @@ FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.Text.Range Range FSharp.Compiler.EditorServices.NavigableItem: FSharp.Compiler.Text.Range get_Range() FSharp.Compiler.EditorServices.NavigableItem: Int32 GetHashCode() FSharp.Compiler.EditorServices.NavigableItem: Int32 GetHashCode(System.Collections.IEqualityComparer) +FSharp.Compiler.EditorServices.NavigableItem: Int32 ParameterCount +FSharp.Compiler.EditorServices.NavigableItem: Int32 TypeParameterCount +FSharp.Compiler.EditorServices.NavigableItem: Int32 get_ParameterCount() +FSharp.Compiler.EditorServices.NavigableItem: Int32 get_TypeParameterCount() FSharp.Compiler.EditorServices.NavigableItem: System.String Name FSharp.Compiler.EditorServices.NavigableItem: System.String ToString() FSharp.Compiler.EditorServices.NavigableItem: System.String get_Name() -FSharp.Compiler.EditorServices.NavigableItem: Void .ctor(System.String, Boolean, FSharp.Compiler.Text.Range, Boolean, FSharp.Compiler.EditorServices.NavigableItemKind, FSharp.Compiler.EditorServices.NavigableContainer) +FSharp.Compiler.EditorServices.NavigableItem: Void .ctor(System.String, Boolean, FSharp.Compiler.Text.Range, Boolean, FSharp.Compiler.EditorServices.NavigableItemKind, FSharp.Compiler.EditorServices.NavigableContainer, Int32, Int32) FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Constructor FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 EnumCase FSharp.Compiler.EditorServices.NavigableItemKind+Tags: Int32 Exception diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 2ff9555dee6..77ccb5a9b0a 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -52,6 +52,7 @@ + diff --git a/tests/FSharp.Compiler.Service.Tests/NavigateToTests.fs b/tests/FSharp.Compiler.Service.Tests/NavigateToTests.fs new file mode 100644 index 00000000000..cf67e20c870 --- /dev/null +++ b/tests/FSharp.Compiler.Service.Tests/NavigateToTests.fs @@ -0,0 +1,63 @@ +module FSharp.Compiler.Service.Tests.NavigateToTests + +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Service.Tests.Common +open FSharp.Compiler.Syntax +open Xunit + +let private implementation = + """ +let value = 1 +let curried a b = a + b +let tupledAndCurried (a, b) c = a + b + c +let takesUnit () = 1 +let generic<'T> (x: 'T) = x + +type C<'T, 'U>() = + member _.Method(a: int, b: int) = a + b + member _.Property = 1 + static member Static x y = x + y +""" + +let private signature = + """ +module M + +val curried: int -> int -> int +val takesUnit: unit -> int +val generic<'T> : 'T * 'T -> 'T + +type C<'T> = + member Method: a: int * b: int -> int + abstract Abstract: unit -> unit +""" + +let private arityOf (parseTree: ParsedInput) name = + let item = + NavigateTo.GetNavigableItems parseTree + |> Array.find (fun item -> item.Name = name) + + item.ParameterCount, item.TypeParameterCount + +[] +[] +[] +[] +[] +[] +[] +[] +[] +[] +let ``A declaration in an implementation file counts the parameters it compiles to`` (name: string, parameterCount: int, typeParameterCount: int) = + Assert.Equal((parameterCount, typeParameterCount), arityOf (getParseResults implementation) name) + +[] +[] +[] +[] +[] +[] +[] +let ``A declaration in a signature file counts the parameters it compiles to`` (name: string, parameterCount: int, typeParameterCount: int) = + Assert.Equal((parameterCount, typeParameterCount), arityOf (getParseResultsOfSignatureFile signature) name) From 923ed178900aca61da760e1a8c4cc29a89392da3 Mon Sep 17 00:00:00 2001 From: Andrii Chebukin Date: Sun, 13 Sep 2026 20:11:30 +0200 Subject: [PATCH 2/5] Link the release note to its PR Co-Authored-By: Claude Opus 5 --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index a94b11cfd88..61faf95c599 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -169,7 +169,7 @@ * Fix signature generation (`fsc --sig`, `GenerateSignature`, `GetValSignatureText`) dropping the parentheses around a destructured or pattern-annotated tuple parameter when a sibling argument in the same curried group is named, so `(int * float) * z: string` no longer prints as the flat 3-tuple `int * float * z: string`. ([Issue #20397](https://github.com/dotnet/fsharp/issues/20397), [PR #20589](https://github.com/dotnet/fsharp/pull/20589)) ### Added -* `NavigableItem` carries `ParameterCount` and `TypeParameterCount`, the counts C# and VB give Navigate To to order matches that are otherwise equal. +* `NavigableItem` carries `ParameterCount` and `TypeParameterCount`, the counts C# and VB give Navigate To to order matches that are otherwise equal. ([PR #20531](https://github.com/dotnet/fsharp/pull/20531)) * FCS: add FSharpCheckFileResults.FileSignature ([PR #20478](https://github.com/dotnet/fsharp/pull/20478)) * Added the `ReraiseInComputationExpressions` language feature (`--langversion:preview`): `reraise ()` in the `with` handler of a computation expression is compiled to a rethrow through `ExceptionDispatchInfo` instead of being rejected with FS0413. ([Suggestion #660](https://github.com/fsharp/fslang-suggestions/issues/660), [RFC FS-1347](https://github.com/fsharp/fslang-design/pull/843), [PR #20405](https://github.com/dotnet/fsharp/pull/20405)) From faec21c5a3a3e58a9ad63668a1152745794c2efa Mon Sep 17 00:00:00 2001 From: Andrii Chebukin Date: Sun, 13 Sep 2026 20:12:01 +0200 Subject: [PATCH 3/5] Give Navigate To the counts it sorts equal F# matches by Navigate To orders matches of the same kind by the folder distance to the file being edited, then by parameter and type parameter count and name, for C# and VB. Roslyn computes the same key for F# results once they carry the counts, which NavigableItem now records. Needs the FSharpNavigateToSearchResult constructor that takes the counts, from dotnet/roslyn#85280. Co-Authored-By: Claude Opus 5 --- docs/release-notes/.VisualStudio/18.vNext.md | 2 ++ .../src/FSharp.Editor/Navigation/NavigateToSearchService.fs | 4 +++- .../FSharp.Editor.Tests/NavigateToSearchServiceTests.fs | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/.VisualStudio/18.vNext.md b/docs/release-notes/.VisualStudio/18.vNext.md index e6034dca8df..8610d9eff3d 100644 --- a/docs/release-notes/.VisualStudio/18.vNext.md +++ b/docs/release-notes/.VisualStudio/18.vNext.md @@ -7,6 +7,8 @@ * Go To Definition no longer blocks the UI thread with a bare `Task.Wait`: the synchronous `IFSharpGoToDefinitionService` call now waits through the cancellable threaded-wait dialog, and the editor's `TaskCompletionSource` bridges run their continuations on the thread pool instead of inline on whichever thread finished the check, so repeated F12 on a large solution no longer starves semantic classification and other main-thread work. ([PR #20482](https://github.com/dotnet/fsharp/pull/20482)) * Peek Definition on an F# symbol whose definition lives in metadata no longer deadlocks Visual Studio. Peek holds the main thread in `JoinableTaskFactory.Run` without pumping messages while it asks the language service for the definition, and generating the metadata document needs that same thread; Peek now stops at definitions that already have a document, and Go To Definition, which owns the wait it makes, still opens the generated one. ([PR #20503](https://github.com/dotnet/fsharp/pull/20503)) +* Navigate To (Ctrl+T) orders F# matches of the same kind as it orders C# and Visual Basic ones: a match in the file being edited first, then by how far its folder is from that file, then by parameter and type parameter count and name. + * Improve Find All References performance by throttling parallel typechecks. ([PR #20128](https://github.com/dotnet/fsharp/pull/20128)) * Fixed Rename incorrectly renaming `get` and `set` keywords for properties with explicit accessors. ([Issue #18270](https://github.com/dotnet/fsharp/issues/18270), [PR #19252](https://github.com/dotnet/fsharp/pull/19252)) * Fixed Find All References crash when F# project contains non-F# files like `.cshtml`. ([Issue #16394](https://github.com/dotnet/fsharp/issues/16394), [PR #19252](https://github.com/dotnet/fsharp/pull/19252)) diff --git a/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs b/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs index 546b00e1b16..56a18f876db 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/NavigateToSearchService.fs @@ -179,7 +179,9 @@ type internal FSharpNavigateToSearchService ImmutableArray.Create(TaggedText(TextTags.Text, item.Name)), document, sourceSpan - ) + ), + item.ParameterCount, + item.TypeParameterCount ) | _ -> () |] diff --git a/vsintegration/tests/FSharp.Editor.Tests/NavigateToSearchServiceTests.fs b/vsintegration/tests/FSharp.Editor.Tests/NavigateToSearchServiceTests.fs index 08816ea6191..ccd9525c2aa 100644 --- a/vsintegration/tests/FSharp.Editor.Tests/NavigateToSearchServiceTests.fs +++ b/vsintegration/tests/FSharp.Editor.Tests/NavigateToSearchServiceTests.fs @@ -72,3 +72,8 @@ module HeyHo = [] let ``nested containers`` () = assertResultsContain "hh.a.b.g.d" "Delta" + + [] + let ``results carry the counts Navigate To sorts equal matches by`` () = + let result = navigateToSearch "+>" |> Seq.find (fun i -> i.Name = "+>") + Assert.Equal((2, 0), (result.ParameterCount, result.TypeParameterCount)) From 27af195de0260d16271393cfb7c4c76256f56e5d Mon Sep 17 00:00:00 2001 From: Andrii Chebukin Date: Sun, 13 Sep 2026 20:19:34 +0200 Subject: [PATCH 4/5] Link the release note to its PR Co-Authored-By: Claude Opus 5 --- docs/release-notes/.VisualStudio/18.vNext.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.VisualStudio/18.vNext.md b/docs/release-notes/.VisualStudio/18.vNext.md index 8610d9eff3d..2a149039fbd 100644 --- a/docs/release-notes/.VisualStudio/18.vNext.md +++ b/docs/release-notes/.VisualStudio/18.vNext.md @@ -8,6 +8,7 @@ * Go To Definition no longer blocks the UI thread with a bare `Task.Wait`: the synchronous `IFSharpGoToDefinitionService` call now waits through the cancellable threaded-wait dialog, and the editor's `TaskCompletionSource` bridges run their continuations on the thread pool instead of inline on whichever thread finished the check, so repeated F12 on a large solution no longer starves semantic classification and other main-thread work. ([PR #20482](https://github.com/dotnet/fsharp/pull/20482)) * Peek Definition on an F# symbol whose definition lives in metadata no longer deadlocks Visual Studio. Peek holds the main thread in `JoinableTaskFactory.Run` without pumping messages while it asks the language service for the definition, and generating the metadata document needs that same thread; Peek now stops at definitions that already have a document, and Go To Definition, which owns the wait it makes, still opens the generated one. ([PR #20503](https://github.com/dotnet/fsharp/pull/20503)) * Navigate To (Ctrl+T) orders F# matches of the same kind as it orders C# and Visual Basic ones: a match in the file being edited first, then by how far its folder is from that file, then by parameter and type parameter count and name. +* Navigate To (Ctrl+T) orders F# matches of the same kind as it orders C# and Visual Basic ones: a match in the file being edited first, then by how far its folder is from that file, then by parameter and type parameter count and name. ([PR #20532](https://github.com/dotnet/fsharp/pull/20532)) * Improve Find All References performance by throttling parallel typechecks. ([PR #20128](https://github.com/dotnet/fsharp/pull/20128)) * Fixed Rename incorrectly renaming `get` and `set` keywords for properties with explicit accessors. ([Issue #18270](https://github.com/dotnet/fsharp/issues/18270), [PR #19252](https://github.com/dotnet/fsharp/pull/19252)) From 5e76a07a4d48b1c88a8e1171c308055ad35a130a Mon Sep 17 00:00:00 2001 From: XperiAndri Date: Sat, 26 Sep 2026 13:47:34 +0200 Subject: [PATCH 5/5] Keep one release note, in the version in development Linking the note added a copy of it instead of editing the first, and `main` has since opened 11.0.200 for SDK 11.0.200, leaving 11.0.100 shipped. Co-Authored-By: Claude Opus 5 (1M context) --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 1 - docs/release-notes/.FSharp.Compiler.Service/11.0.200.md | 1 + docs/release-notes/.VisualStudio/18.vNext.md | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index 61faf95c599..f383908e195 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -169,7 +169,6 @@ * Fix signature generation (`fsc --sig`, `GenerateSignature`, `GetValSignatureText`) dropping the parentheses around a destructured or pattern-annotated tuple parameter when a sibling argument in the same curried group is named, so `(int * float) * z: string` no longer prints as the flat 3-tuple `int * float * z: string`. ([Issue #20397](https://github.com/dotnet/fsharp/issues/20397), [PR #20589](https://github.com/dotnet/fsharp/pull/20589)) ### Added -* `NavigableItem` carries `ParameterCount` and `TypeParameterCount`, the counts C# and VB give Navigate To to order matches that are otherwise equal. ([PR #20531](https://github.com/dotnet/fsharp/pull/20531)) * FCS: add FSharpCheckFileResults.FileSignature ([PR #20478](https://github.com/dotnet/fsharp/pull/20478)) * Added the `ReraiseInComputationExpressions` language feature (`--langversion:preview`): `reraise ()` in the `with` handler of a computation expression is compiled to a rethrow through `ExceptionDispatchInfo` instead of being rejected with FS0413. ([Suggestion #660](https://github.com/fsharp/fslang-suggestions/issues/660), [RFC FS-1347](https://github.com/fsharp/fslang-design/pull/843), [PR #20405](https://github.com/dotnet/fsharp/pull/20405)) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.200.md index 6212188b65f..7919e2d7e74 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.200.md @@ -1,5 +1,6 @@ ### Added +* `NavigableItem` carries `ParameterCount` and `TypeParameterCount`, the counts C# and VB give Navigate To to order matches that are otherwise equal. ([PR #20531](https://github.com/dotnet/fsharp/pull/20531)) * F# Interactive gains a JSON-RPC server mode, `--fsi-server-jsonrpc:`, in which a host submits interactions over a named pipe and receives structured results — diagnostics with positions, escaping exceptions, the values each interaction bound, and the session's own process id — instead of recovering them by looking for a `SERVER-PROMPT>` marker in the output text. Program output continues to flow through the redirected console streams. The pipe admits only the user running the session; `--fsi-server-client-pid:` names the host process whose exit ends the session. `FsiEvaluationSession` exposes both options as `JsonRpcServerPipeName` and `JsonRpcClientProcessId`. The mode is part of the .NET fsi only. ([PR #20396](https://github.com/dotnet/fsharp/pull/20396)) ### Fixed diff --git a/docs/release-notes/.VisualStudio/18.vNext.md b/docs/release-notes/.VisualStudio/18.vNext.md index 2a149039fbd..c4ba0f4f9be 100644 --- a/docs/release-notes/.VisualStudio/18.vNext.md +++ b/docs/release-notes/.VisualStudio/18.vNext.md @@ -7,7 +7,6 @@ * Go To Definition no longer blocks the UI thread with a bare `Task.Wait`: the synchronous `IFSharpGoToDefinitionService` call now waits through the cancellable threaded-wait dialog, and the editor's `TaskCompletionSource` bridges run their continuations on the thread pool instead of inline on whichever thread finished the check, so repeated F12 on a large solution no longer starves semantic classification and other main-thread work. ([PR #20482](https://github.com/dotnet/fsharp/pull/20482)) * Peek Definition on an F# symbol whose definition lives in metadata no longer deadlocks Visual Studio. Peek holds the main thread in `JoinableTaskFactory.Run` without pumping messages while it asks the language service for the definition, and generating the metadata document needs that same thread; Peek now stops at definitions that already have a document, and Go To Definition, which owns the wait it makes, still opens the generated one. ([PR #20503](https://github.com/dotnet/fsharp/pull/20503)) -* Navigate To (Ctrl+T) orders F# matches of the same kind as it orders C# and Visual Basic ones: a match in the file being edited first, then by how far its folder is from that file, then by parameter and type parameter count and name. * Navigate To (Ctrl+T) orders F# matches of the same kind as it orders C# and Visual Basic ones: a match in the file being edited first, then by how far its folder is from that file, then by parameter and type parameter count and name. ([PR #20532](https://github.com/dotnet/fsharp/pull/20532)) * Improve Find All References performance by throttling parallel typechecks. ([PR #20128](https://github.com/dotnet/fsharp/pull/20128))