Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Fixed

* Tooltip "Full name" now shows demangled companion module names (e.g. `MyType.func` instead of `MyTypeModule.func`). ([Issue #17335](https://github.com/dotnet/fsharp/issues/17335), [PR #19867](https://github.com/dotnet/fsharp/pull/19867))
* Reject non-function bindings for single-case and partial active pattern names with FS1209, matching the existing multi-case behavior. ([PR #19763](https://github.com/dotnet/fsharp/pull/19763))
* Fix FS0421 "The address of the variable cannot be used at this point" incorrectly raised for the discard pattern `let _ = &expr` when `let x = &expr` compiles. ([Issue #18841](https://github.com/dotnet/fsharp/issues/18841), [PR #19811](https://github.com/dotnet/fsharp/pull/19811))
* Honor `--nowarn` and `--warnaserror` for warnings emitted during command-line option parsing ([Issue #19576](https://github.com/dotnet/fsharp/issues/19576), [PR #19776](https://github.com/dotnet/fsharp/pull/19776))
Expand Down
14 changes: 8 additions & 6 deletions src/Compiler/TypedTree/TypedTreeOps.FreeVars.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1395,17 +1395,19 @@ module internal MemberRepresentation =
let fullNameOfParentOfValRef vref =
match vref with
| VRefLocal x ->
match x.PublicPath with
| None -> ValueNone
| Some(ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPath pp)
match x.PublicPath, x.TryDeclaringEntity with
| None, _ -> ValueNone
| Some _, Parent eref -> ValueSome(fullNameOfEntityRef (fun (e: EntityRef) -> e.DemangledModuleOrNamespaceName) eref)
| Some(ValPubPath(pp, _)), ParentNone -> ValueSome(fullNameOfPubPath pp)
| VRefNonLocal nlr -> ValueSome(fullNameOfEntityRef (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity)

let fullNameOfParentOfValRefAsLayout vref =
match vref with
| VRefLocal x ->
match x.PublicPath with
| None -> ValueNone
| Some(ValPubPath(pp, _)) -> ValueSome(fullNameOfPubPathAsLayout pp)
match x.PublicPath, x.TryDeclaringEntity with
| None, _ -> ValueNone
| Some _, Parent eref -> ValueSome(fullNameOfEntityRefAsLayout (fun (e: EntityRef) -> e.DemangledModuleOrNamespaceName) eref)
| Some(ValPubPath(pp, _)), ParentNone -> ValueSome(fullNameOfPubPathAsLayout pp)
| VRefNonLocal nlr ->
ValueSome(fullNameOfEntityRefAsLayout (fun (x: EntityRef) -> x.DemangledModuleOrNamespaceName) nlr.EnclosingEntity)

Expand Down
67 changes: 67 additions & 0 deletions tests/FSharp.Compiler.Service.Tests/TooltipTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -852,3 +852,70 @@ let inline fo{caret}o< ^T> (x: ^T) = x
|> fun text ->
// Type param appears in tooltip
Assert.Contains("'T", text)

let private getFullNameRemarks (source: string) =
let _mainDesc, _xml, remarks =
Checker.getTooltip source
|> assertAndExtractTooltip
match remarks with
| Some r -> r
| None -> failwith "Expected tooltip remarks containing 'Full name:'"

[<Fact>]
let ``Companion module tooltip shows demangled name`` () =
let remarks =
getFullNameRemarks """
module TestNs
type MyType = { F: int }
module MyType =
let func1{caret}23 x = x
"""
Assert.Contains("MyType.func123", remarks)
Assert.DoesNotContain("MyTypeModule", remarks)

[<Fact>]
let ``Non-companion module keeps literal name`` () =
let remarks =
getFullNameRemarks """
module TestNs
module HelperModule =
let doSt{caret}uff () = ()
"""
Assert.Contains("HelperModule.doStuff", remarks)

[<Fact>]
let ``ModuleSuffix attribute without companion type demangles`` () =
let remarks =
getFullNameRemarks """
module TestNs
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Foo =
let x{caret} = 1
"""
Assert.Contains("Foo.x", remarks)
Assert.DoesNotContain("FooModule", remarks)

[<Fact>]
let ``Nested companion module demangled`` () =
let remarks =
getFullNameRemarks """
module TestNs
module Outer =
type Inner = { v: int }
module Inner =
let hel{caret}per x = x
"""
Assert.Contains("Outer.Inner.helper", remarks)
Assert.DoesNotContain("InnerModule", remarks)

[<Fact>]
let ``List dot map tooltip shows List not ListModule`` () =
let remarks =
getFullNameRemarks """
module TestNs
let _ = List.m{caret}ap id [1]
"""
Assert.Contains("List.map", remarks)
Assert.DoesNotContain("ListModule", remarks)


Loading