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 d5c2087765..a8354f05aa 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -17,6 +17,7 @@ * Fix `YieldFromFinal`/`ReturnFromFinal` being incorrectly called in non-tail positions (`for`, `use`, `use!`, `try/with` handler). ([Issue #19402](https://github.com/dotnet/fsharp/issues/19402), [PR #19403](https://github.com/dotnet/fsharp/pull/19403)) * Fixed how the source ranges of warn directives are reported (as trivia) in the parser output (by not reporting leading spaces). ([Issue #19405](https://github.com/dotnet/fsharp/issues/19405), [PR #19408]((https://github.com/dotnet/fsharp/pull/19408))) * Fix UoM value type `ToString()` returning garbage values when `--checknulls+` is enabled, caused by double address-taking in codegen. ([Issue #19435](https://github.com/dotnet/fsharp/issues/19435), [PR #19440](https://github.com/dotnet/fsharp/pull/19440)) +* Fix methods being tagged as `Member` instead of `Method` in tooltips. ([Issue #10540](https://github.com/dotnet/fsharp/issues/10540), [PR #19501](https://github.com/dotnet/fsharp/pull/19501)) ### Added diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index 62c95f6bbf..844dd4446b 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -1383,7 +1383,8 @@ module PrintTastMemberOrVals = let resL = if short then tauL else - let nameL = layoutMemberName denv vref niceMethodTypars argInfos tagMember vref.DisplayNameCoreMangled true + let tag = if isNil argInfos then tagMember else tagMethod + let nameL = layoutMemberName denv vref niceMethodTypars argInfos tag vref.DisplayNameCoreMangled true let nameL = if short then nameL else mkInlineL denv vref.Deref nameL stat --- ((nameL |> addColonL) ^^ tauL) prettyTyparInst, resL diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index 7da5a63eef..83b9c7007f 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -3433,7 +3433,14 @@ let fullDisplayTextOfValRefAsLayout (vref: ValRef) = | SynMemberKind.PropertyGetSet -> tagProperty vref.DisplayName | SynMemberKind.ClassConstructor | SynMemberKind.Constructor -> tagMethod vref.DisplayName - | SynMemberKind.Member -> tagMember vref.DisplayName + | SynMemberKind.Member -> + match vref.ValReprInfo with + | Some valReprInfo -> + let numArgGroups = valReprInfo.ArgInfos.Length + let isMethod = if memberInfo.MemberFlags.IsInstance then numArgGroups > 1 else numArgGroups > 0 + if isMethod then tagMethod vref.DisplayName + else tagMember vref.DisplayName + | None -> tagMember vref.DisplayName match fullNameOfParentOfValRefAsLayout vref with | ValueNone -> wordL n | ValueSome pathText -> diff --git a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs index b082644ebb..f510684e1f 100644 --- a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs @@ -388,6 +388,17 @@ let assertAndGetSingleToolTipText items = let text,_xml,_remarks = assertAndExtractTooltip items text +let getMainDescriptionTags (ToolTipText(items)) = + match items with + | ToolTipElement.Group [ singleElement ] :: _ -> singleElement.MainDescription + | _ -> failwith $"Expected single group in tooltip, got {items}" + +let assertNameTagInTooltip expectedTag expectedName (tooltip: ToolTipText) = + let tags = getMainDescriptionTags tooltip + let found = tags |> Array.exists (fun t -> t.Tag = expectedTag && t.Text = expectedName) + let desc = tags |> Array.map (fun t -> sprintf "(%A, %s)" t.Tag t.Text) |> String.concat ", " + Assert.True(found, sprintf "Expected tag %A with text '%s' in tooltip, but found: %s" expectedTag expectedName desc) + let normalize (s: string) = s.Replace("\r\n", "\n").Replace("\n\n", "\n") [] @@ -602,3 +613,50 @@ let normaliz{caret}e' x = x + 1 """ testXmlDocFallbackToSigFileWhileInImplFile sigSource implSource "Normalize with a prime" + +// https://github.com/dotnet/fsharp/issues/10540 +[] +let ``Instance method should be tagged as Method in tooltip`` () = + Checker.getTooltip """ +type T() = + member x.Metho{caret}d() = () +""" + |> assertNameTagInTooltip TextTag.Method "Method" + +// https://github.com/dotnet/fsharp/issues/10540 +[] +let ``Instance method with parameters should be tagged as Method in tooltip`` () = + Checker.getTooltip """ +type T() = + member x.Ad{caret}d(a: int, b: int) = a + b +""" + |> assertNameTagInTooltip TextTag.Method "Add" + +// https://github.com/dotnet/fsharp/issues/10540 +[] +let ``Static method should be tagged as Method in tooltip`` () = + Checker.getTooltip """ +type T() = + static member Creat{caret}e() = T() +""" + |> assertNameTagInTooltip TextTag.Method "Create" + +// https://github.com/dotnet/fsharp/issues/10540 +[] +let ``Property-like member should be tagged as Property`` () = + Checker.getTooltip """ +type T() = + member x.Valu{caret}e = 42 +""" + |> assertNameTagInTooltip TextTag.Property "Value" + +// https://github.com/dotnet/fsharp/issues/10540 +[] +let ``Auto property should be tagged as Property`` () = + Checker.getTooltip """ +namespace Foo + +type Bar() = + member val Fo{caret}o = "bla" with get, set +""" + |> assertNameTagInTooltip TextTag.Property "Foo"