Skip to content

Commit

Permalink
Gentype: support @tag
Browse files Browse the repository at this point in the history
Fixes #6436
  • Loading branch information
cristianoc committed Oct 12, 2023
1 parent b9df8ac commit 9869145
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#### :bug: Bug Fix

- Fix issue with Dynamic import of module in nested expressions https://github.com/rescript-lang/rescript-compiler/pull/6431
- Fix issue where GenType was not supporting `@tag` on ordinary variatns https://github.com/rescript-lang/rescript-compiler/pull/6437

# 11.0.0-rc.4

Expand Down
8 changes: 8 additions & 0 deletions jscomp/gentype/Annotation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ let tagIsGenTypeAs s = s = "genType.as" || s = "gentype.as"
let tagIsAs s = s = "bs.as" || s = "as"
let tagIsInt s = s = "bs.int" || s = "int"
let tagIsString s = s = "bs.string" || s = "string"

let tagIsTag s = s = "tag"

let tagIsUnboxed s = s = "unboxed" || s = "ocaml.unboxed"
let tagIsGenTypeImport s = s = "genType.import" || s = "gentype.import"
let tagIsGenTypeOpaque s = s = "genType.opaque" || s = "gentype.opaque"
Expand Down Expand Up @@ -146,6 +149,11 @@ let getAttributeImportRenaming attributes =
(Some importString, Some renameString)
| _ -> (None, genTypeAsRenaming)

let getTag attributes =
match attributes |> getAttributePayload tagIsTag with
| Some (_, StringPayload s) -> Some s
| _ -> None

let getDocPayload attributes =
let docPayload = attributes |> getAttributePayload tagIsDoc in
match docPayload with
Expand Down
7 changes: 4 additions & 3 deletions jscomp/gentype/EmitType.ml
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
|> String.concat ", ")
^ "]"
| TypeVar s -> s
| Variant {inherits; noPayloads; payloads; polymorphic; unboxed} ->
| Variant {inherits; noPayloads; payloads; polymorphic; tag; unboxed} ->
let inheritsRendered =
inherits
|> List.map (fun type_ ->
Expand All @@ -183,7 +183,8 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
in
let tagField =
case |> labelJSToString
|> field ~name:(Runtime.jsVariantTag ~polymorphic:false)
|> field
~name:(Runtime.jsVariantTag ~polymorphic:false ~tag)
in
match (unboxed, type_) with
| true, type_ ->
Expand All @@ -198,7 +199,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
(* poly variant *)
[
case |> labelJSToString
|> field ~name:(Runtime.jsVariantTag ~polymorphic);
|> field ~name:(Runtime.jsVariantTag ~polymorphic ~tag);
type_ |> render
|> field ~name:(Runtime.jsVariantValue ~polymorphic);
]
Expand Down
5 changes: 3 additions & 2 deletions jscomp/gentype/GenTypeCommon.ml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ and variant = {
noPayloads: case list;
payloads: payload list;
polymorphic: bool; (* If true, this is a polymorphic variant *)
tag: string option; (* The name of the tag field at runtime *)
unboxed: bool;
}

Expand Down Expand Up @@ -168,8 +169,8 @@ let rec depToResolvedName (dep : dep) =
| Internal resolvedName -> resolvedName
| Dot (p, s) -> ResolvedName.dot s (p |> depToResolvedName)

let createVariant ~inherits ~noPayloads ~payloads ~polymorphic ~unboxed =
Variant {inherits; noPayloads; payloads; polymorphic; unboxed}
let createVariant ~inherits ~noPayloads ~payloads ~polymorphic ~tag ~unboxed =
Variant {inherits; noPayloads; payloads; polymorphic; tag; unboxed}

let ident ?(builtin = true) ?(typeArgs = []) name =
Ident {builtin; name; typeArgs}
Expand Down
7 changes: 5 additions & 2 deletions jscomp/gentype/Runtime.ml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ let rec emitModuleAccessPath ~config moduleAccessPath =
| Dot (p, moduleItem) ->
p |> emitModuleAccessPath ~config |> EmitText.fieldAccess ~label:moduleItem

let jsVariantTag ~polymorphic =
let jsVariantTag ~polymorphic ~tag =
match polymorphic with
| true -> "NAME"
| false -> "TAG"
| false -> (
match tag with
| Some tag -> tag
| None -> "TAG")

let jsVariantPayloadTag ~n = "_" ^ string_of_int n

Expand Down
2 changes: 1 addition & 1 deletion jscomp/gentype/Runtime.mli
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ val newModuleItem : name:string -> moduleItem
val newRecordValue : unboxed:bool -> recordGen -> recordValue
val recordGen : unit -> recordGen
val recordValueToString : recordValue -> string
val jsVariantTag : polymorphic:bool -> string
val jsVariantTag : polymorphic:bool -> tag:string option -> string
val jsVariantPayloadTag : n:int -> string
val jsVariantValue : polymorphic:bool -> string
2 changes: 1 addition & 1 deletion jscomp/gentype/TranslateCoreType.ml
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ and translateCoreType_ ~config ~typeVarsGen
let inherits = inheritsTranslations |> List.map (fun {type_} -> type_) in
let type_ =
createVariant ~noPayloads ~payloads ~inherits ~polymorphic:true
~unboxed:false
~tag:None ~unboxed:false
in
let dependencies =
(inheritsTranslations
Expand Down
5 changes: 3 additions & 2 deletions jscomp/gentype/TranslateTypeDeclarations.ml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
let unboxedAnnotation =
typeAttributes |> Annotation.hasAttribute Annotation.tagIsUnboxed
in
let tagAnnotation = typeAttributes |> Annotation.getTag in
let returnTypeDeclaration (typeDeclaration : CodeItem.typeDeclaration) =
match opaque = Some true with
| true -> [{typeDeclaration with importTypes = []}]
Expand Down Expand Up @@ -203,7 +204,7 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
else variant.payloads
in
createVariant ~inherits:variant.inherits ~noPayloads ~payloads
~polymorphic:true ~unboxed:false
~polymorphic:true ~tag:None ~unboxed:false
| _ -> translation.type_
in
{translation with type_} |> handleGeneralDeclaration
Expand Down Expand Up @@ -295,7 +296,7 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
in
let variantTyp =
createVariant ~inherits:[] ~noPayloads ~payloads ~polymorphic:false
~unboxed:unboxedAnnotation
~tag:tagAnnotation ~unboxed:unboxedAnnotation
in
let resolvedTypeName = typeName |> TypeEnv.addModulePath ~typeEnv in
let exportFromTypeDeclaration =
Expand Down
6 changes: 3 additions & 3 deletions jscomp/gentype/TranslateTypeExprFromTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ let translateConstr ~config ~paramsTranslation ~(path : Path.t) ~typeEnv =
case 0 "Ok" paramTranslation1.type_;
case 1 "Error" paramTranslation2.type_;
]
~polymorphic:false ~unboxed:false
~polymorphic:false ~tag:None ~unboxed:false
in
{
dependencies =
Expand Down Expand Up @@ -386,7 +386,7 @@ and translateTypeExprFromTypes_ ~config ~typeVarsGen ~typeEnv
in
let type_ =
createVariant ~inherits:[] ~noPayloads ~payloads:[] ~polymorphic:true
~unboxed:false
~tag:None ~unboxed:false
in
{dependencies = []; type_}
| {noPayloads = []; payloads = [(_label, t)]; unknowns = []} ->
Expand Down Expand Up @@ -415,7 +415,7 @@ and translateTypeExprFromTypes_ ~config ~typeVarsGen ~typeEnv
in
let type_ =
createVariant ~inherits:[] ~noPayloads ~payloads ~polymorphic:true
~unboxed:false
~tag:None ~unboxed:false
in
let dependencies =
payloadTranslations
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions jscomp/gentype_tests/typescript-react-example/src/Lib.bs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions jscomp/gentype_tests/typescript-react-example/src/Lib.gen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* TypeScript file generated from Lib.res by genType. */
/* eslint-disable import/first */


// tslint:disable-next-line:interface-over-type-literal
export type action =
{ action: "A"; _0: string }
| { action: "B"; _0: string };
6 changes: 6 additions & 0 deletions jscomp/gentype_tests/typescript-react-example/src/Lib.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@gentype
@tag("action")
type action = | A(string) | B(string)

let a = A("a")
let b = B("b")

0 comments on commit 9869145

Please sign in to comment.