From 98573733cb5e15958f59c0fa6e0628ee046beb0c Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 30 May 2023 09:43:02 +0200 Subject: [PATCH] Proof of concept --- src/Compiler/Symbols/Symbols.fs | 27 ++++++++++++++++ src/Compiler/Symbols/Symbols.fsi | 3 ++ ...ervice.SurfaceArea.netstandard20.debug.bsl | 7 ++-- ...vice.SurfaceArea.netstandard20.release.bsl | 1 + tests/service/Symbols.fs | 32 +++++++++++++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index a7baed599bf..2307c8e30df 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -2355,6 +2355,33 @@ type FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) = |> LayoutRender.toArray |> Some + member x.GetValSignatureText (displayContext: FSharpDisplayContext, m: range) = + checkIsResolved() + let stringValOfMethInfo methInfo = + match methInfo with + | FSMeth(valRef = vref) -> NicePrint.stringValOrMember (displayContext.Contents cenv.g) cenv.infoReader vref + | _ -> NicePrint.stringOfMethInfo cenv.infoReader m (displayContext.Contents cenv.g) methInfo + + let stringValOfPropInfo (p: PropInfo) = + let t = p.GetPropertyType(cenv.amap, m ) |> NicePrint.layoutType (displayContext.Contents cenv.g) |> LayoutRender.showL + let withGetSet = + if p.HasGetter && p.HasSetter then "with get, set" + elif p.HasGetter then "with get" + elif p.HasSetter then "with set" + else "" + + $"member val %s{p.DisplayName}: %s{t} %s{withGetSet}" + + match d with + | E _ -> None + | V v -> + NicePrint.stringValOrMember (displayContext.Contents cenv.g) cenv.infoReader v + |> Some + | C methInfo + | M methInfo -> stringValOfMethInfo methInfo |> Some + | P p -> stringValOfPropInfo p |> Some + + member x.GetWitnessPassingInfo() = let witnessInfos = match d with diff --git a/src/Compiler/Symbols/Symbols.fsi b/src/Compiler/Symbols/Symbols.fsi index 418b42b03df..51a00334b74 100644 --- a/src/Compiler/Symbols/Symbols.fsi +++ b/src/Compiler/Symbols/Symbols.fsi @@ -966,6 +966,9 @@ type FSharpMemberOrFunctionOrValue = /// Format the type using the rules of the given display context member GetReturnTypeLayout: displayContext: FSharpDisplayContext -> TaggedText[] option + /// Get the signature text to included this Symbol into an existing signature file. + member GetValSignatureText: displayContext: FSharpDisplayContext * m: range -> string option + /// Check if this method has an entrpoint that accepts witness arguments and if so return /// the name of that entrypoint and information about the additional witness arguments member GetWitnessPassingInfo: unit -> (string * IList) option diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 2bf927ac27b..c25ff8ef9cf 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -4958,6 +4958,7 @@ FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSh FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Object] LiteralValue FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Object] get_LiteralValue() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] TryGetFullCompiledOperatorNameIdents() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String] GetValSignatureText(FSharp.Compiler.Symbols.FSharpDisplayContext, FSharp.Compiler.Text.Range) FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullDisplayName() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.String,System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]]] GetWitnessPassingInfo() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAbstractSignature] ImplementedAbstractSignatures @@ -5156,14 +5157,14 @@ FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_HasFields() FSharp.Compiler.Symbols.FSharpUnionCase: Boolean get_IsUnresolved() FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility Accessibility FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpAccessibility get_Accessibility() +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity DeclaringEntity +FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity get_DeclaringEntity() FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType ReturnType FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpType get_ReturnType() FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc XmlDoc FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpXmlDoc get_XmlDoc() FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range DeclarationLocation FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Text.Range get_DeclarationLocation() -FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity DeclaringEntity -FSharp.Compiler.Symbols.FSharpUnionCase: FSharp.Compiler.Symbols.FSharpEntity get_DeclaringEntity() FSharp.Compiler.Symbols.FSharpUnionCase: Int32 GetHashCode() FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] Attributes FSharp.Compiler.Symbols.FSharpUnionCase: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAttribute] get_Attributes() @@ -11375,4 +11376,4 @@ FSharp.Compiler.Xml.XmlDoc: System.String GetXmlText() FSharp.Compiler.Xml.XmlDoc: System.String[] GetElaboratedXmlLines() FSharp.Compiler.Xml.XmlDoc: System.String[] UnprocessedLines FSharp.Compiler.Xml.XmlDoc: System.String[] get_UnprocessedLines() -FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range) +FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range) \ No newline at end of file diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index 57f794c68b4..12d7438f650 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -4958,6 +4958,7 @@ FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSh FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Object] LiteralValue FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Object] get_LiteralValue() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String[]] TryGetFullCompiledOperatorNameIdents() +FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String] GetValSignatureText(FSharp.Compiler.Symbols.FSharpDisplayContext, FSharp.Compiler.Text.Range) FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.String] TryGetFullDisplayName() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.String,System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpParameter]]] GetWitnessPassingInfo() FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue: System.Collections.Generic.IList`1[FSharp.Compiler.Symbols.FSharpAbstractSignature] ImplementedAbstractSignatures diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index 71594bc81bf..2128e5112c5 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -567,3 +567,35 @@ match Unchecked.defaultof with getSymbolUses checkResults |> Seq.exists (fun symbolUse -> symbolUse.IsFromUse && symbolUse.Symbol.DisplayName = "F2") |> shouldEqual true + +module GetValSignatureText = + let private assertSignature (expected:string) source (lineNumber, column, line, identifier) = + let _, checkResults = getParseAndCheckResults source + let symbolUseOpt = checkResults.GetSymbolUseAtLocation(lineNumber, column, line, [ identifier ]) + match symbolUseOpt with + | None -> Assert.Fail "Expected symbol" + | Some symbolUse -> + match symbolUse.Symbol with + | :? FSharpMemberOrFunctionOrValue as mfv -> + let expected = expected.Replace("\r", "") + let signature = mfv.GetValSignatureText(symbolUse.DisplayContext, symbolUse.Range) + Assert.AreEqual(expected, signature.Value) + | symbol -> Assert.Fail $"Expected FSharpMemberOrFunctionOrValue, got %A{symbol}" + + [] + let ``Signature text for let binding`` () = + assertSignature + "val a: b: int -> c: int -> int" + "let a b c = b + c" + (1, 4, "let a b c = b + c", "a") + + [] + let ``Signature text for member binding`` () = + assertSignature + "member Bar: a: int -> b: int -> int" + """ +type Foo() = + member this.Bar (a:int) (b:int) : int = 0 +""" + (3, 19, " member this.Bar (a:int) (b:int) : int = 0", "Bar") +