Skip to content

Commit

Permalink
Add support for FunctionType
Browse files Browse the repository at this point in the history
  • Loading branch information
MangelMaxime committed Dec 4, 2023
1 parent 30392c2 commit f1cbc09
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/Glutinum.Converter/GlueAST.fs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ type ExcludedMember =
| Literal of GlueLiteral
// | Function

type GlueFunctionType =
{
Type: GlueType
Parameters: GlueParameter list
}

[<RequireQualifiedAccess>]
type GlueType =
| Discard
Expand All @@ -173,6 +179,7 @@ type GlueType =
| TypeReference of GlueTypeReference
| Partial of GlueInterface
| Array of GlueType
| FunctionType of GlueFunctionType

member this.Name =
match this with
Expand Down Expand Up @@ -201,4 +208,5 @@ type GlueType =
| IndexedAccessType _
| Union _
| Partial _
| FunctionType _
| Discard -> "obj"
40 changes: 40 additions & 0 deletions src/Glutinum.Converter/Read.fs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,16 @@ let private readTypeNode
| Ts.SyntaxKind.TypePredicate ->
GlueType.Primitive GluePrimitive.Bool

| Ts.SyntaxKind.FunctionType ->
let functionTypeNode = typeNode :?> Ts.FunctionTypeNode

{
Type = readTypeNode checker (Some functionTypeNode.``type``)
Parameters = readParameters checker functionTypeNode.parameters
}
|> GlueType.FunctionType


| _ -> failwith $"readTypeNode: Unsupported kind {typeNode.kind}"
| None -> GlueType.Primitive GluePrimitive.Unit

Expand Down Expand Up @@ -659,6 +669,25 @@ let private readFunctionDeclaration
Parameters = readParameters checker declaration.parameters
}


// let private readFunctionTye
// (checker: Ts.TypeChecker)
// (declaration: Ts.FunctionTypeNode)
// : GlueFunctionType
// =

// let name =
// match declaration.name with
// | Some name -> name.getText ()
// | None -> failwith "readFunctionDeclaration: Missing name"

// {
// IsDeclared = isDeclared
// Name = name
// Type = readTypeNode checker declaration.``type``
// Parameters = readParameters checker declaration.parameters
// }

let private readModuleDeclaration
(checker: Ts.TypeChecker)
(declaration: Ts.ModuleDeclaration)
Expand Down Expand Up @@ -780,6 +809,17 @@ let private readNode (checker: Ts.TypeChecker) (typeNode: Ts.Node) : GlueType =

readClassDeclaration checker declaration |> GlueType.ClassDeclaration

| Ts.SyntaxKind.FunctionType ->
let functionType = typeNode :?> Ts.FunctionTypeNode

// ({
// Parameters = readParameters checker functionType.parameters
// Type = readTypeNode checker functionType.``type``
// } : GlueCallSignature)
// |> GlueType.FuncTionType
GlueType.Discard


// | Ts.SyntaxKind.ExportAssignment ->
// let exportAssignment = typeNode :?> Ts.ExportAssignment

Expand Down
34 changes: 32 additions & 2 deletions src/Glutinum.Converter/Transform.fs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ let rec private transformType (glueType: GlueType) : FSharpType =
| GlueType.Variable _
| GlueType.KeyOf _
| GlueType.Discard
| GlueType.FunctionType _
| GlueType.Partial _
| GlueType.FunctionDeclaration _ ->
printfn "Could not transform type: %A" glueType
FSharpType.Discard
Expand Down Expand Up @@ -391,7 +393,12 @@ module TypeAliasDeclaration =
: FSharpUnionCase
|> Some
// Doesn't make sense to have a case for call signature
| GlueMember.CallSignature _ -> None
| GlueMember.CallSignature _
// Doesn't make sense to have a case for index signature
// because index signature is used because we don't know the name
// of the properties and so it is used only to describe the
// shape of the object
| GlueMember.IndexSignature _ -> None
)
| _ -> []

Expand Down Expand Up @@ -547,7 +554,8 @@ let private transformTypeAliasDeclaration
match m with
| GlueMember.Method { Type = typ }
| GlueMember.Property { Type = typ }
| GlueMember.CallSignature { Type = typ } ->
| GlueMember.CallSignature { Type = typ }
| GlueMember.IndexSignature { Type = typ } ->
match typ with
| GlueType.Union(GlueTypeUnion cases) -> cases
| _ -> [ typ ]
Expand Down Expand Up @@ -617,6 +625,27 @@ let private transformTypeAliasDeclaration

FSharpType.Interface partialInterface

| GlueType.FunctionType functionType ->
{
Attributes = [ FSharpAttribute.AllowNullLiteral ]
Name = glueTypeAliasDeclaration.Name
Members =
{
Attributes =
[ FSharpAttribute.EmitSelfInvoke ]
Name = "Invoke"
Parameters = functionType.Parameters |> List.map transformParameter
Type = transformType functionType.Type
IsOptional = false
IsStatic = false
Accessor = None
Accessibility = FSharpAccessiblity.Public
}
|> FSharpMember.Method
|> List.singleton
}
|> FSharpType.Interface

| _ -> FSharpType.Discard

let private transformModuleDeclaration
Expand Down Expand Up @@ -661,6 +690,7 @@ let rec private transformToFsharp (glueTypes: GlueType list) : FSharpType list =
| GlueType.ClassDeclaration classInfo ->
transformClassDeclaration classInfo

| GlueType.FunctionType _
| GlueType.Partial _
| GlueType.Array _
| GlueType.TypeReference _
Expand Down
1 change: 1 addition & 0 deletions tests/specs/functionType/simple.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type GreetFunction = (a: string) => void;
13 changes: 13 additions & 0 deletions tests/specs/functionType/simple.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module rec Glutinum

(***)
#r "nuget: Fable.Core"
(***)

open Fable.Core
open System

[<AllowNullLiteral>]
type GreetFunction =
[<Emit("$0($1...)")>]
abstract member Invoke: a: string -> unit

0 comments on commit f1cbc09

Please sign in to comment.