From ff60e29a7fdaa2e9d814e32eec0c88e582bb5319 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Tue, 6 Aug 2024 12:52:21 +0200 Subject: [PATCH 1/6] Symbols: add Mfv.ApparentEnclosingType --- .../Service/ServiceInterfaceStubGenerator.fs | 6 +++- src/Compiler/Symbols/Symbols.fs | 32 ++++++++++++++----- src/Compiler/Symbols/Symbols.fsi | 5 ++- tests/FSharp.Compiler.Service.Tests/Common.fs | 5 +++ .../ProjectAnalysisTests.fs | 8 ++--- 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs index b6325670b31..b1a59d562d6 100644 --- a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs +++ b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs @@ -351,7 +351,11 @@ module InterfaceStubGenerator = // Ordinary instance members | _, true, _, name -> name + parArgs // Ordinary functions or values - | false, _, _, name when not (v.ApparentEnclosingEntity.HasAttribute()) -> + | false, _, _, name when + v.ApparentEnclosingEntity + |> Option.map _.HasAttribute() + |> Option.defaultValue false + |> not -> name + " " + parArgs // Ordinary static members or things (?) that require fully qualified access | _, _, _, name -> name + parArgs diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index 28045551725..e43166ddf08 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -1722,20 +1722,36 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = | ParentNone -> None | Parent p -> FSharpEntity(cenv, p) |> Some - member _.ApparentEnclosingEntity: FSharpEntity = + member _.ApparentEnclosingEntity: FSharpEntity option = let createEntity (ttype: TType) = - let tcref, tyargs = destAppTy cenv.g ttype - FSharpEntity(cenv, tcref, tyargs) + match tryAppTy cenv.g ttype with + | ValueSome(tcref, tyargs) -> Some(FSharpEntity(cenv, tcref, tyargs)) + | _ -> None checkIsResolved() - match d with + + match d with | E e -> createEntity e.ApparentEnclosingType | P p -> createEntity p.ApparentEnclosingType | M m | C m -> createEntity m.ApparentEnclosingType - | V v -> - match v.ApparentEnclosingEntity with - | ParentNone -> invalidOp "the value or member doesn't have a logical parent" - | Parent p -> FSharpEntity(cenv, p) + | V v -> + + match v.ApparentEnclosingEntity with + | ParentNone -> invalidOp "the value or member doesn't have a logical parent" + | Parent p -> Some(FSharpEntity(cenv, p)) + + member _.ApparentEnclosingType: FSharpType = + checkIsResolved() + + match d with + | E e -> FSharpType(cenv, e.ApparentEnclosingType) + | P p -> FSharpType(cenv, p.ApparentEnclosingType) + | M m | C m -> FSharpType(cenv, m.ApparentEnclosingType) + | V v -> + + match v.ApparentEnclosingEntity with + | ParentNone -> invalidOp "the value or member doesn't have a logical parent" + | Parent p -> FSharpType(cenv, generalizedTyconRef cenv.g p) member _.GenericParameters = checkIsResolved() diff --git a/src/Compiler/Symbols/Symbols.fsi b/src/Compiler/Symbols/Symbols.fsi index 0fec9922171..8d5499e857e 100644 --- a/src/Compiler/Symbols/Symbols.fsi +++ b/src/Compiler/Symbols/Symbols.fsi @@ -794,7 +794,10 @@ type FSharpMemberOrFunctionOrValue = member DeclaringEntity: FSharpEntity option /// Get the logical enclosing entity, which for an extension member is type being extended - member ApparentEnclosingEntity: FSharpEntity + member ApparentEnclosingEntity: FSharpEntity option + + /// Get the logical enclosing type, which for an extension member is type being extended + member ApparentEnclosingType: FSharpType /// Get the declaration location of the member, function or value member DeclarationLocation: range diff --git a/tests/FSharp.Compiler.Service.Tests/Common.fs b/tests/FSharp.Compiler.Service.Tests/Common.fs index 74368c9b1f3..fd138d1e19f 100644 --- a/tests/FSharp.Compiler.Service.Tests/Common.fs +++ b/tests/FSharp.Compiler.Service.Tests/Common.fs @@ -417,6 +417,11 @@ let getSymbolFullName (symbol: FSharpSymbol) = | :? FSharpField as field -> Some field.FullName | _ -> None +let tryGetEntityFullName (entity: FSharpEntity option) = + entity + |> Option.map _.FullName + |> Option.defaultValue "" + let assertContainsSymbolWithName name source = getSymbols source |> Seq.choose getSymbolName diff --git a/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs b/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs index df1a064ae9d..c4261eaeab3 100644 --- a/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/ProjectAnalysisTests.fs @@ -3317,9 +3317,9 @@ let ``Test Project23 property`` () = extensionProps |> Array.collect (fun f -> [| if f.HasGetterMethod then - yield (f.DeclaringEntity.Value.FullName, f.ApparentEnclosingEntity.FullName, f.GetterMethod.CompiledName, f.GetterMethod.DeclaringEntity.Value.FullName, attribsOfSymbol f) + yield (f.DeclaringEntity.Value.FullName, tryGetEntityFullName f.ApparentEnclosingEntity, f.GetterMethod.CompiledName, f.GetterMethod.DeclaringEntity.Value.FullName, attribsOfSymbol f) if f.HasSetterMethod then - yield (f.DeclaringEntity.Value.FullName, f.ApparentEnclosingEntity.FullName, f.SetterMethod.CompiledName, f.SetterMethod.DeclaringEntity.Value.FullName, attribsOfSymbol f) + yield (f.DeclaringEntity.Value.FullName, tryGetEntityFullName f.ApparentEnclosingEntity, f.SetterMethod.CompiledName, f.SetterMethod.DeclaringEntity.Value.FullName, attribsOfSymbol f) |]) |> Array.toList @@ -3362,9 +3362,9 @@ let ``Test Project23 extension properties' getters/setters should refer to the c match x.Symbol with | :? FSharpMemberOrFunctionOrValue as f -> if f.HasGetterMethod then - yield (f.DeclaringEntity.Value.FullName, f.GetterMethod.DeclaringEntity.Value.FullName, f.ApparentEnclosingEntity.FullName, f.GetterMethod.ApparentEnclosingEntity.FullName, attribsOfSymbol f) + yield (f.DeclaringEntity.Value.FullName, f.GetterMethod.DeclaringEntity.Value.FullName, tryGetEntityFullName f.ApparentEnclosingEntity, tryGetEntityFullName f.GetterMethod.ApparentEnclosingEntity, attribsOfSymbol f) if f.HasSetterMethod then - yield (f.DeclaringEntity.Value.FullName, f.SetterMethod.DeclaringEntity.Value.FullName, f.ApparentEnclosingEntity.FullName, f.SetterMethod.ApparentEnclosingEntity.FullName, attribsOfSymbol f) + yield (f.DeclaringEntity.Value.FullName, f.SetterMethod.DeclaringEntity.Value.FullName, tryGetEntityFullName f.ApparentEnclosingEntity, tryGetEntityFullName f.SetterMethod.ApparentEnclosingEntity, attribsOfSymbol f) | _ -> () |]) |> Array.toList From 836ccdf6805d6375c18c5b90e64b49eaceb932fe Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 18 Sep 2025 12:23:55 +0200 Subject: [PATCH 2/6] Surfface area --- .../FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 161933e9c16..0014e55d827 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 @@ -2081,8 +2081,8 @@ FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: FSharp.Compiler.Text.Range[ FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUsesAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetDeclarationListSymbols(Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpParseFileResults], Int32, System.String, FSharp.Compiler.EditorServices.PartialLongName, Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.EditorServices.AssemblySymbol]]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean]) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetSymbolUseAtLocation(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) -FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] TryGetCapturedDisplayContext(FSharp.Compiler.Text.Range) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] GetDisplayContextForPos(FSharp.Compiler.Text.Position) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] TryGetCapturedDisplayContext(FSharp.Compiler.Text.Range) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] ImplementationFile FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] get_ImplementationFile() FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpType] TryGetCapturedType(FSharp.Compiler.Text.Range) @@ -5630,8 +5630,6 @@ FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsValCompiled FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Boolean get_IsValue() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() -FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpEntity ApparentEnclosingEntity -FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpEntity get_ApparentEnclosingEntity() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpInlineAnnotation InlineAnnotation FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpInlineAnnotation get_InlineAnnotation() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue EventAddMethod @@ -5644,8 +5642,10 @@ FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.F FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue get_SetterMethod() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpParameter ReturnParameter FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpParameter get_ReturnParameter() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType ApparentEnclosingType FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType EventDelegateType FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType FullType +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType get_ApparentEnclosingType() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType get_EventDelegateType() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpType get_FullType() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc @@ -5654,7 +5654,9 @@ FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Text.Rang FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Text.Range get_DeclarationLocation() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: FSharp.Compiler.Text.TaggedText[] FormatLayout(FSharp.Compiler.Symbols.FSharpDisplayContext) FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Int32 GetHashCode() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] ApparentEnclosingEntity FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] DeclaringEntity +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] get_ApparentEnclosingEntity() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpEntity] get_DeclaringEntity() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] EventForFSharpProperty FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue] get_EventForFSharpProperty() From 44129e1ab0c7cca2f09b56c8bdbd0172a0edc137 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 18 Sep 2025 12:32:41 +0200 Subject: [PATCH 3/6] Fantomas --- src/Compiler/Service/ServiceInterfaceStubGenerator.fs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs index b1a59d562d6..c53ab5d7583 100644 --- a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs +++ b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs @@ -352,10 +352,11 @@ module InterfaceStubGenerator = | _, true, _, name -> name + parArgs // Ordinary functions or values | false, _, _, name when - v.ApparentEnclosingEntity - |> Option.map _.HasAttribute() - |> Option.defaultValue false - |> not -> + v.ApparentEnclosingEntity + |> Option.map _.HasAttribute() + |> Option.defaultValue false + |> not + -> name + " " + parArgs // Ordinary static members or things (?) that require fully qualified access | _, _, _, name -> name + parArgs From f93aa6c9711e54a795fa3021f62258f9acf42f16 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 18 Sep 2025 12:41:40 +0200 Subject: [PATCH 4/6] Release notes --- docs/release-notes/.FSharp.Compiler.Service/10.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index e5c6a408edf..3d38fc1ab2d 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -1,4 +1,5 @@ ### Added +* Symbols: add Mfv.ApparentEnclosingType ([PR #17494](https://github.com/dotnet/fsharp/pull/17494)) * Add opt-in warning attribute not valid for union case with fields [PR #18532](https://github.com/dotnet/fsharp/pull/18532)) * Add support for `when 'T : Enum` library-only static optimization constraint. ([PR #18546](https://github.com/dotnet/fsharp/pull/18546)) * Add support for tail calls in computation expressions ([PR #18804](https://github.com/dotnet/fsharp/pull/18804)) From 85573f510bd1adae2e8de9092198579636d14bba Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 18 Sep 2025 13:04:43 +0200 Subject: [PATCH 5/6] Fix Editor --- .../FSharp.Editor/Navigation/GoToDefinition.fs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs index 94615461dc1..5b9227c139b 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs @@ -204,8 +204,12 @@ type internal GoToDefinition(metadataAsSource: FSharpMetadataAsSourceService) = match targetSymbolUse.Symbol with | :? FSharpEntity as symbol -> symbol.TryGetMetadataText() |> Option.map (fun text -> text, symbol.DisplayName) | :? FSharpMemberOrFunctionOrValue as symbol -> - symbol.ApparentEnclosingEntity.TryGetMetadataText() - |> Option.map (fun text -> text, symbol.ApparentEnclosingEntity.DisplayName) + symbol.ApparentEnclosingEntity + |> Option.bind (fun entity -> + entity.TryGetMetadataText() + |> Option.map (fun text -> text, entity.DisplayName) + ) + | :? FSharpField as symbol -> match symbol.DeclaringEntity with | Some entity -> @@ -652,8 +656,11 @@ type internal GoToDefinition(metadataAsSource: FSharpMetadataAsSourceService) = match targetSymbolUse.Symbol with | :? FSharpEntity as symbol -> symbol.TryGetMetadataText() |> Option.map (fun text -> text, symbol.DisplayName) | :? FSharpMemberOrFunctionOrValue as symbol -> - symbol.ApparentEnclosingEntity.TryGetMetadataText() - |> Option.map (fun text -> text, symbol.ApparentEnclosingEntity.DisplayName) + symbol.ApparentEnclosingEntity + |> Option.bind (fun entity -> + entity.TryGetMetadataText() + |> Option.map (fun text -> text, entity.DisplayName) + ) | :? FSharpField as symbol -> match symbol.DeclaringEntity with | Some entity -> From bb5ba1c31eb6e27a60e898d92ab8b94658edf583 Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Thu, 18 Sep 2025 16:10:33 +0200 Subject: [PATCH 6/6] Fantomas --- .../src/FSharp.Editor/Navigation/GoToDefinition.fs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs index 5b9227c139b..99b3ff241ad 100644 --- a/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs +++ b/vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs @@ -205,10 +205,7 @@ type internal GoToDefinition(metadataAsSource: FSharpMetadataAsSourceService) = | :? FSharpEntity as symbol -> symbol.TryGetMetadataText() |> Option.map (fun text -> text, symbol.DisplayName) | :? FSharpMemberOrFunctionOrValue as symbol -> symbol.ApparentEnclosingEntity - |> Option.bind (fun entity -> - entity.TryGetMetadataText() - |> Option.map (fun text -> text, entity.DisplayName) - ) + |> Option.bind (fun entity -> entity.TryGetMetadataText() |> Option.map (fun text -> text, entity.DisplayName)) | :? FSharpField as symbol -> match symbol.DeclaringEntity with @@ -657,10 +654,7 @@ type internal GoToDefinition(metadataAsSource: FSharpMetadataAsSourceService) = | :? FSharpEntity as symbol -> symbol.TryGetMetadataText() |> Option.map (fun text -> text, symbol.DisplayName) | :? FSharpMemberOrFunctionOrValue as symbol -> symbol.ApparentEnclosingEntity - |> Option.bind (fun entity -> - entity.TryGetMetadataText() - |> Option.map (fun text -> text, entity.DisplayName) - ) + |> Option.bind (fun entity -> entity.TryGetMetadataText() |> Option.map (fun text -> text, entity.DisplayName)) | :? FSharpField as symbol -> match symbol.DeclaringEntity with | Some entity ->