Skip to content

Commit

Permalink
Unannotate function alias values
Browse files Browse the repository at this point in the history
  • Loading branch information
SoxPopuli committed Mar 4, 2025
1 parent 4730990 commit 61ae855
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 42 deletions.
98 changes: 57 additions & 41 deletions src/FsAutoComplete.Core/SignatureFormatter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,52 @@ module SignatureFormatter =

let private isMeasureType (t: FSharpEntity) = Set.contains t.FullName measureTypeNames

type ParameterType =
| Generic of FSharpGenericParameter
| Concrete of FSharpEntity
| Function of ParameterType list
| Tuple of ParameterType list
| StructTuple of ParameterType list

static member displayName =
function
| Generic x -> "'" + x.DisplayName
| Concrete x -> x.DisplayName
| Function x -> x |> List.map ParameterType.displayName |> String.join " -> "
| Tuple x ->
let args = x |> List.map ParameterType.displayName |> String.join " * "
$"({args})"
| StructTuple x ->
let args = x |> List.map ParameterType.displayName |> String.join " * "
$"struct ({args})"

static member displayNameUnAnnotated =
function
| Generic x -> "'" + x.DisplayName
| Concrete x -> x.UnAnnotate().DisplayName
| Function x -> x |> List.map ParameterType.displayNameUnAnnotated |> String.join " -> "
| Tuple x ->
let args = x |> List.map ParameterType.displayNameUnAnnotated |> String.join " * "
$"({args})"
| StructTuple x ->
let args = x |> List.map ParameterType.displayNameUnAnnotated |> String.join " * "
$"struct ({args})"

let rec getGenericArgumentTypes (e: FSharpType) =
e.GenericArguments
|> Seq.map (fun x ->
if x.IsGenericParameter then
Generic x.GenericParameter
else if x.IsFunctionType then
Function(getGenericArgumentTypes x)
else if x.IsStructTupleType then
StructTuple(getGenericArgumentTypes x)
else if x.IsTupleType then
Tuple(getGenericArgumentTypes x)
else
x.TypeDefinition |> Concrete)
|> Seq.toList

let rec formatFSharpType (context: FSharpDisplayContext) (typ: FSharpType) : string =
let context = context.WithPrefixGenericParameters()

Expand All @@ -58,6 +104,11 @@ module SignatureFormatter =
sprintf "struct (%s)" refTupleStr
else
refTupleStr
elif typ.IsAbbreviation && typ.AbbreviatedType.IsFunctionType then
typ.AbbreviatedType
|> getGenericArgumentTypes
|> List.map ParameterType.displayName
|> String.join " -> "
elif typ.IsGenericParameter then // no longer need to differentiate between SRTP and normal generic parameter types
"'" + typ.GenericParameter.Name
elif typ.HasTypeDefinition && typ.GenericArguments.Count > 0 then
Expand Down Expand Up @@ -592,41 +643,6 @@ module SignatureFormatter =

sprintf "active pattern %s: %s" apc.Name findVal

type ParameterType =
| Generic of FSharpGenericParameter
| Concrete of FSharpEntity
| Function of ParameterType list
| Tuple of ParameterType list
| StructTuple of ParameterType list

static member displayName =
function
| Generic x -> "'" + x.DisplayName
| Concrete x -> x.DisplayName
| Function x -> x |> List.map ParameterType.displayName |> String.join " -> "
| Tuple x ->
let args = x |> List.map ParameterType.displayName |> String.join " * "
$"({args})"
| StructTuple x ->
let args = x |> List.map ParameterType.displayName |> String.join " * "
$"struct ({args})"

let rec getUnAnnotatedParameterNames (e: FSharpType) =
e.GenericArguments
|> Seq.map (fun x ->
if x.IsGenericParameter then
Generic x.GenericParameter
else if x.IsFunctionType then
Function(getUnAnnotatedParameterNames x)
else if x.IsStructTupleType then
StructTuple(getUnAnnotatedParameterNames x)
else if x.IsTupleType then
Tuple(getUnAnnotatedParameterNames x)
else
x.TypeDefinition.UnAnnotate() |> Concrete)
|> Seq.toList


let getEntitySignature displayContext (fse: FSharpEntity) =
let modifier =
match fse.Accessibility with
Expand Down Expand Up @@ -765,24 +781,24 @@ module SignatureFormatter =
if fse.IsFSharpAbbreviation then
if fse.AbbreviatedType.IsFunctionType then
let typeNames =
getUnAnnotatedParameterNames fse.AbbreviatedType
|> List.map ParameterType.displayName
getGenericArgumentTypes fse.AbbreviatedType
|> List.map ParameterType.displayNameUnAnnotated
|> String.join " -> "

basicName ++ "=" ++ typeNames
else if fse.AbbreviatedType.IsGenericParameter then
basicName ++ "=" ++ $"'{fse.AbbreviatedType.GenericParameter.DisplayName}"
else if fse.AbbreviatedType.IsStructTupleType then
let typeNames =
getUnAnnotatedParameterNames fse.AbbreviatedType
|> List.map ParameterType.displayName
getGenericArgumentTypes fse.AbbreviatedType
|> List.map ParameterType.displayNameUnAnnotated
|> String.join " * "

basicName ++ "=" ++ $"struct ({typeNames})"
else if fse.AbbreviatedType.IsTupleType then
let typeNames =
getUnAnnotatedParameterNames fse.AbbreviatedType
|> List.map ParameterType.displayName
getGenericArgumentTypes fse.AbbreviatedType
|> List.map ParameterType.displayNameUnAnnotated
|> String.join " * "

basicName ++ "=" ++ $"({typeNames})"
Expand Down
7 changes: 6 additions & 1 deletion test/FsAutoComplete.Tests.Lsp/CoreTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,12 @@ let tooltipTests state =
verifySignature
108u
7u
"type StructFunctionTupleAlias = Int32 -> struct (Int32 * String)" ] ]
"type StructFunctionTupleAlias = Int32 -> struct (Int32 * String)"

verifySignature
109u
7u
"val functionAliasValue: int -> int" ] ]

let closeTests state =
// Note: clear diagnostics also implies clear caches (-> remove file & project options from State).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,4 @@ type GenericTypeAliasTuple<'A, 'B> = ('A * 'B * int)
type GenericFunctionTupleAlias<'T> = 'T -> ('T * string)
type StructTupleAlias = (struct (int * string))
type StructFunctionTupleAlias = int -> (struct (int * string))
let functionAliasValue: FunctionAlias = fun _ -> 2

0 comments on commit 61ae855

Please sign in to comment.