Skip to content

Commit

Permalink
Add support for literal type alias
Browse files Browse the repository at this point in the history
Fix #45
  • Loading branch information
MangelMaxime committed Feb 15, 2024
1 parent 13c6034 commit 32b8347
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 14 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Add support for `MethodSignature` on interface ([GH-28](https://github.com/glutinum-org/cli/issues/28]))
* Ignore `ExportAssignment` as we don't know what to do with it yet
* Add support for literal type alias ([GH-45](https://github.com/glutinum-org/cli/issues/45))

```ts
type Mode = "auto";
type Rank1 = 1;
type Trusty = true;
type Falsy = false;
type PiValue = 3.14;
```

## 0.4.0 - 2024-01-08

Expand Down
9 changes: 9 additions & 0 deletions src/Glutinum.Converter/FsharpAST.fs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ type FSharpTypeParameter =
Default: FSharpType option
}

static member Create
(name: string, ?constraint_: FSharpType, ?default_: FSharpType)
=
{
Name = name
Constraint = constraint_
Default = default_
}

type FSharpTypeAlias =
{
Name: string
Expand Down
16 changes: 16 additions & 0 deletions src/Glutinum.Converter/Reader/TypeNode.fs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ let readTypeNode (reader: TypeScriptReader) (typeNode: Ts.TypeNode) : GlueType =
|> GlueType.ClassDeclaration
| _ -> GlueType.Primitive GluePrimitive.Any

| Ts.SyntaxKind.LiteralType ->
let literalTypeNode = typeNode :?> Ts.LiteralTypeNode

let literalExpression =
unbox<Ts.LiteralExpression> literalTypeNode.literal

match tryReadLiteral literalExpression with
| Some literal -> GlueType.Literal literal
| None ->
failwith (
generateReaderError
"type node - literal type"
$"Could not read literal type"
typeNode
)

| _ ->
failwith (
generateReaderError
Expand Down
79 changes: 65 additions & 14 deletions src/Glutinum.Converter/Transform.fs
Original file line number Diff line number Diff line change
Expand Up @@ -459,24 +459,72 @@ module TypeAliasDeclaration =
: FSharpUnion)
|> FSharpType.Union

let transformLiteral (typeAliasName: string) (literalInfo: GlueLiteral) =
let makeTypeAlias primitiveType =
({
Name = typeAliasName
Type = primitiveType |> FSharpType.Primitive
TypeParameters = []
}
: FSharpTypeAlias)
|> FSharpType.TypeAlias

// We can use StringEnum to represent the literal
match literalInfo with
| GlueLiteral.String value ->
let case =
let caseName =
value
|> String.removeSingleQuote
|> String.removeDoubleQuote
// |> String.capitalizeFirstLetter

({
Attributes = []
Name = Naming.sanitizeName caseName
}
: FSharpUnionCase)

({
Attributes =
[
FSharpAttribute.RequireQualifiedAccess
FSharpAttribute.StringEnum CaseRules.None
]
Name = typeAliasName
Cases = [ case ]
IsOptional = false
}
: FSharpUnion)
|> FSharpType.Union

// For others type we will default to a type alias

| GlueLiteral.Int _ -> makeTypeAlias FSharpPrimitive.Int
| GlueLiteral.Float _ -> makeTypeAlias FSharpPrimitive.Float
| GlueLiteral.Bool _ -> makeTypeAlias FSharpPrimitive.Bool

let private transformTypeParameters
(typeParameters: GlueTypeParameter list)
: FSharpTypeParameter list
=
typeParameters
|> List.map (fun typeParameter ->
{
Name = Naming.sanitizeName typeParameter.Name
Constraint = typeParameter.Constraint |> Option.map transformType
Default = typeParameter.Default |> Option.map transformType
}
FSharpTypeParameter.Create(
typeParameter.Name,
?constraint_ =
(typeParameter.Constraint |> Option.map transformType),
?default_ = (typeParameter.Default |> Option.map transformType)
)
)

let private transformTypeAliasDeclaration
(glueTypeAliasDeclaration: GlueTypeAliasDeclaration)
: FSharpType
=

let typeAliasName = Naming.sanitizeName glueTypeAliasDeclaration.Name

// TODO: Make the transformation more robust
match glueTypeAliasDeclaration.Type with
| GlueType.Union(GlueTypeUnion cases) as unionType ->
Expand Down Expand Up @@ -556,7 +604,7 @@ let private transformTypeAliasDeclaration
FSharpAttribute.RequireQualifiedAccess
FSharpAttribute.StringEnum CaseRules.None
]
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
Cases = cases
IsOptional = false
}
Expand All @@ -580,7 +628,7 @@ let private transformTypeAliasDeclaration
|> List.distinct

({
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
Cases = cases
}
: FSharpEnum)
Expand All @@ -590,7 +638,7 @@ let private transformTypeAliasDeclaration
// Erased enum cases for improving the user experience
else
({
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
Type = transformType unionType
TypeParameters =
transformTypeParameters
Expand Down Expand Up @@ -634,17 +682,20 @@ let private transformTypeAliasDeclaration
| _ -> FSharpType.Discard

({
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
Type = typ
TypeParameters =
transformTypeParameters glueTypeAliasDeclaration.TypeParameters
}
: FSharpTypeAlias)
|> FSharpType.TypeAlias

| GlueType.Literal literalInfo ->
TypeAliasDeclaration.transformLiteral typeAliasName literalInfo

| GlueType.Primitive primitiveInfo ->
({
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
Type = transformPrimitive primitiveInfo |> FSharpType.Primitive
TypeParameters =
transformTypeParameters glueTypeAliasDeclaration.TypeParameters
Expand All @@ -654,7 +705,7 @@ let private transformTypeAliasDeclaration

| GlueType.TypeReference typeReference ->
({
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
Type = transformType (GlueType.TypeReference typeReference)
TypeParameters =
transformTypeParameters glueTypeAliasDeclaration.TypeParameters
Expand All @@ -664,7 +715,7 @@ let private transformTypeAliasDeclaration

| GlueType.Array glueType ->
({
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
Type = transformType (GlueType.Array glueType)
TypeParameters =
transformTypeParameters glueTypeAliasDeclaration.TypeParameters
Expand All @@ -679,7 +730,7 @@ let private transformTypeAliasDeclaration
let partialInterface =
{ originalInterface with
// Use the alias name instead of the original interface name
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
// Transform all the members to optional
Members =
originalInterface.Members
Expand All @@ -699,7 +750,7 @@ let private transformTypeAliasDeclaration
| GlueType.FunctionType functionType ->
{
Attributes = [ FSharpAttribute.AllowNullLiteral ]
Name = Naming.sanitizeName glueTypeAliasDeclaration.Name
Name = typeAliasName
TypeParameters =
transformTypeParameters glueTypeAliasDeclaration.TypeParameters
Members =
Expand Down
3 changes: 3 additions & 0 deletions tests/specs/typeAlias/literal/boolean.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type Test2 = true;

type Test3 = false;
14 changes: 14 additions & 0 deletions tests/specs/typeAlias/literal/boolean.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module rec Glutinum

open Fable.Core
open System

type Test2 =
bool

type Test3 =
bool

(***)
#r "nuget: Fable.Core"
(***)
1 change: 1 addition & 0 deletions tests/specs/typeAlias/literal/float.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type Test1 = 1.12
11 changes: 11 additions & 0 deletions tests/specs/typeAlias/literal/float.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module rec Glutinum

open Fable.Core
open System

type Test1 =
float

(***)
#r "nuget: Fable.Core"
(***)
1 change: 1 addition & 0 deletions tests/specs/typeAlias/literal/int.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type Test = 0
11 changes: 11 additions & 0 deletions tests/specs/typeAlias/literal/int.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module rec Glutinum

open Fable.Core
open System

type Test =
int

(***)
#r "nuget: Fable.Core"
(***)
2 changes: 2 additions & 0 deletions tests/specs/typeAlias/literal/string.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type GPUAutoLayoutMode =
"auto";
13 changes: 13 additions & 0 deletions tests/specs/typeAlias/literal/string.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module rec Glutinum

open Fable.Core
open System

[<RequireQualifiedAccess>]
[<StringEnum(CaseRules.None)>]
type GPUAutoLayoutMode =
| auto

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

0 comments on commit 32b8347

Please sign in to comment.