Skip to content

Port PR https://github.com/rescript-lang/rescript-compiler/pull/6021 … #6024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@

# 10.1.3

#### :boom: Breaking Change

- `genType`: streamline the treatment of optionals as undefined https://github.com/rescript-lang/rescript-compiler/pull/6024
- Represent `option<t>` as `undefined | t` instead of `null | undefined | t`. This is more permissive when importing functions taking optional values (allows to use option types), but stricter when e.g. exporting ReScript functions taking arguments of option type. Fallback: use `Js.undefined<_>` instead.
- Represent `{x:option<string>}` as `{x:(undefined | string)}` instead of `{x?: string}`. This is more in line with TS's behaviour. Fallback: use `{x?:string}`.

#### :nail_care: Polish
- Add the gap property to jsxDOMStyle https://github.com/rescript-lang/rescript-compiler/pull/5956

Expand All @@ -36,6 +42,7 @@
#### :rocket: New Feature

- Add experimental suppport for directives. An annotation such as `@@directive("use client;")` emits `use client;` verbatim before imports https://github.com/rescript-lang/rescript-compiler/pull/5999
- `genType`: add `Core` standard library support for the following builtin types: `Null.t`, `Nullable.t`, `Undefined.t`, `Dict.t<_>`, `Promise.t<_>`, `Date.t`, `BigInt.t`, `RegExp.t`, `Map.t<_, _>`, `WeakMap.t<_, _>`, `Set<_>`, `WeakSet<_>` https://github.com/rescript-lang/rescript-compiler/pull/6024

# 10.1.2

Expand Down
99 changes: 12 additions & 87 deletions jscomp/gentype/Converter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ type t =
| CircularC of string * t
| FunctionC of functionC
| IdentC
| NullableC of t
| ObjectC of fieldsC
| OptionC of t
| PromiseC of t
| RecordC of fieldsC
| TupleC of t list
| VariantC of variantC

Expand Down Expand Up @@ -66,8 +64,7 @@ let rec toString converter =
|> String.concat ", ")
^ " -> " ^ toString retConverter ^ ")"
| IdentC -> "id"
| NullableC c -> "nullable(" ^ toString c ^ ")"
| ObjectC fieldsC | RecordC fieldsC ->
| ObjectC fieldsC ->
let dot = match converter with ObjectC _ -> ". " | _ -> "" in
"{" ^ dot
^ (fieldsC
Expand Down Expand Up @@ -114,6 +111,7 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
| Array (t, mutable_) ->
let tConverter, tNormalized = t |> visit ~visited in
(ArrayC tConverter, Array (tNormalized, mutable_))
| Dict _ -> (IdentC, normalized_)
| Function
({ argTypes; componentName; retType; typeVars; uncurried } as function_)
->
Expand Down Expand Up @@ -182,10 +180,10 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
else (IdentC, normalized_))
| Null t ->
let tConverter, tNormalized = t |> visit ~visited in
(NullableC tConverter, Null tNormalized)
(OptionC tConverter, Null tNormalized)
| Nullable t ->
let tConverter, tNormalized = t |> visit ~visited in
(NullableC tConverter, Nullable tNormalized)
(OptionC tConverter, Nullable tNormalized)
| Object (closedFlag, fields) ->
let fieldsConverted =
fields
Expand Down Expand Up @@ -214,27 +212,6 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
| Promise t ->
let tConverter, tNormalized = t |> visit ~visited in
(PromiseC tConverter, Promise tNormalized)
| Record fields ->
let fieldsConverted =
fields
|> List.map (fun ({ type_ } as field) ->
(field, type_ |> visit ~visited))
in
( RecordC
(fieldsConverted
|> List.map (fun ({ nameJS; nameRE; optional }, (converter, _)) ->
{
lblJS = nameJS;
lblRE = nameRE;
c =
(match optional = Mandatory with
| true -> converter
| false -> OptionC converter);
})),
Record
(fieldsConverted
|> List.map (fun (field, (_, tNormalized)) ->
{ field with type_ = tNormalized })) )
| Tuple innerTypes ->
let innerConversions, normalizedList =
innerTypes |> List.map (visit ~visited) |> List.split
Expand Down Expand Up @@ -379,7 +356,6 @@ let rec converterIsIdentity ~config ~toJS converter =
argConverter |> converterIsIdentity ~config ~toJS:(not toJS)
| GroupConverter _ -> false)
| IdentC -> true
| NullableC c -> c |> converterIsIdentity ~config ~toJS
| ObjectC fieldsC ->
fieldsC
|> List.for_all (fun { lblJS; lblRE; c } ->
Expand All @@ -388,9 +364,8 @@ let rec converterIsIdentity ~config ~toJS converter =
match c with
| OptionC c1 -> c1 |> converterIsIdentity ~config ~toJS
| _ -> c |> converterIsIdentity ~config ~toJS)
| OptionC c -> if toJS then c |> converterIsIdentity ~config ~toJS else false
| OptionC c -> c |> converterIsIdentity ~config ~toJS
| PromiseC c -> c |> converterIsIdentity ~config ~toJS
| RecordC _ -> false
| TupleC innerTypesC ->
innerTypesC |> List.for_all (converterIsIdentity ~config ~toJS)
| VariantC { withPayloads; useVariantTables } ->
Expand Down Expand Up @@ -519,14 +494,6 @@ let rec apply ~config ~converter ~indent ~nameGen ~toJS ~variantTables value =
EmitText.funDef ~bodyArgs ~functionName:componentName ~funParams ~indent
~mkBody ~typeVars
| IdentC -> value
| NullableC c ->
EmitText.parens
[
value ^ " == null ? " ^ value ^ " : "
^ (value
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables
);
]
| ObjectC fieldsC ->
let simplifyFieldConverted fieldConverter =
match fieldConverter with
Expand All @@ -550,62 +517,20 @@ let rec apply ~config ~converter ~indent ~nameGen ~toJS ~variantTables value =
in
"{" ^ fieldValues ^ "}"
| OptionC c ->
if toJS then
EmitText.parens
[
value ^ " == null ? " ^ value ^ " : "
^ (value
|> apply ~config ~converter:c ~indent ~nameGen ~toJS
~variantTables);
]
else
EmitText.parens
[
value ^ " == null ? undefined : "
^ (value
|> apply ~config ~converter:c ~indent ~nameGen ~toJS
~variantTables);
]
EmitText.parens
[
value ^ " == null ? " ^ value ^ " : "
^ (value
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables
);
]
| PromiseC c ->
let x = "$promise" |> EmitText.name ~nameGen in
value ^ ".then(function _element("
^ (x |> EmitType.ofTypeAny ~config)
^ ") { return "
^ (x |> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables)
^ "})"
| RecordC fieldsC ->
let simplifyFieldConverted fieldConverter =
match fieldConverter with
| OptionC converter1
when converter1 |> converterIsIdentity ~config ~toJS ->
IdentC
| _ -> fieldConverter
in
if toJS then
let fieldValues =
fieldsC
|> List.mapi (fun index { lblJS; c = fieldConverter } ->
lblJS ^ ":"
^ (value
|> EmitText.arrayAccess ~index
|> apply ~config
~converter:(fieldConverter |> simplifyFieldConverted)
~indent ~nameGen ~toJS ~variantTables))
|> String.concat ", "
in
"{" ^ fieldValues ^ "}"
else
let fieldValues =
fieldsC
|> List.map (fun { lblJS; c = fieldConverter } ->
value
|> EmitText.fieldAccess ~label:lblJS
|> apply ~config
~converter:(fieldConverter |> simplifyFieldConverted)
~indent ~nameGen ~toJS ~variantTables)
|> String.concat ", "
in
"[" ^ fieldValues ^ "]"
| TupleC innerTypesC ->
"["
^ (innerTypesC
Expand Down
6 changes: 3 additions & 3 deletions jscomp/gentype/EmitJs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ let emitExportType ~emitters ~config ~typeGetNormalized ~typeNameIsInterface
let typeNameIsInterface ~(exportTypeMap : CodeItem.exportTypeMap)
~(exportTypeMapFromOtherFiles : CodeItem.exportTypeMap) typeName =
let typeIsInterface type_ =
match type_ with Object _ | Record _ -> true | _ -> false
match type_ with Object _ -> true | _ -> false
in
match exportTypeMap |> StringMap.find typeName with
| { type_ } -> type_ |> typeIsInterface
Expand Down Expand Up @@ -625,11 +625,11 @@ let propagateAnnotationToSubTypes ~codeItems (typeMap : CodeItem.exportTypeMap)
type1 |> visit
| exception Not_found ->
annotatedSet := !annotatedSet |> StringSet.add typeName)
| Array (t, _) -> t |> visit
| Array (t, _) | Dict t -> t |> visit
| Function { argTypes; retType } ->
argTypes |> List.iter (fun { aType } -> visit aType);
retType |> visit
| GroupOfLabeledArgs fields | Object (_, fields) | Record fields ->
| GroupOfLabeledArgs fields | Object (_, fields) ->
fields |> List.iter (fun { type_ } -> type_ |> visit)
| Option t | Null t | Nullable t | Promise t -> t |> visit
| Tuple innerTypes -> innerTypes |> List.iter visit
Expand Down
18 changes: 16 additions & 2 deletions jscomp/gentype/EmitType.ml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
arrayName ^ "<"
^ (t |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
^ ">"
| Dict type_ ->
"{[id: string]: "
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
^ "}"
| Function
{
argTypes = [ { aType = Object (closedFlag, fields) } ];
Expand All @@ -117,7 +121,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
| Function { argTypes; retType; typeVars } ->
renderFunType ~config ~indent ~inFunType ~typeNameIsInterface ~typeVars
argTypes retType
| GroupOfLabeledArgs fields | Object (_, fields) | Record fields ->
| GroupOfLabeledArgs fields | Object (_, fields) ->
let indent1 = fields |> Indent.heuristicFields ~indent in
fields
|> renderFields ~config ~indent:indent1 ~inFunType ~typeNameIsInterface
Expand All @@ -137,7 +141,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
"(null | "
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
^ ")"
| Nullable type_ | Option type_ ->
| Nullable type_ ->
let useParens x =
match type_ with
| Function _ | Variant _ -> EmitText.parens [ x ]
Expand All @@ -147,6 +151,16 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
^ useParens
(type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
^ ")"
| Option type_ ->
let useParens x =
match type_ with
| Function _ | Variant _ -> EmitText.parens [ x ]
| _ -> x
in
"(undefined | "
^ useParens
(type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
^ ")"
| Promise type_ ->
"Promise" ^ "<"
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
Expand Down
10 changes: 8 additions & 2 deletions jscomp/gentype/GenTypeCommon.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type closedFlag = Open | Closed

type type_ =
| Array of type_ * mutable_
| Dict of type_
| Function of function_
| GroupOfLabeledArgs of fields
| Ident of ident
Expand All @@ -59,7 +60,6 @@ type type_ =
| Object of closedFlag * fields
| Option of type_
| Promise of type_
| Record of fields
| Tuple of type_ list
| TypeVar of string
| Variant of variant
Expand Down Expand Up @@ -100,6 +100,7 @@ and payload = { case : case; inlineRecord : bool; numArgs : int; t : type_ }
let typeIsObject type_ =
match type_ with
| Array _ -> true
| Dict _ -> true
| Function _ -> false
| GroupOfLabeledArgs _ -> false
| Ident _ -> false
Expand All @@ -108,7 +109,6 @@ let typeIsObject type_ =
| Object _ -> true
| Option _ -> false
| Promise _ -> true
| Record _ -> true
| Tuple _ -> true
| TypeVar _ -> false
| Variant _ -> false
Expand Down Expand Up @@ -201,11 +201,17 @@ let ident ?(builtin = true) ?(typeArgs = []) name =

let sanitizeTypeName name = name |> String.map (function '\'' -> '_' | c -> c)
let unknown = ident "unknown"
let bigintT = ident "BigInt"
let booleanT = ident "boolean"
let dateT = ident "Date"
let mapT (x, y) = ident ~typeArgs:[ x; y ] "Map"
let numberT = ident "number"
let regexpT = ident "RegExp"
let setT x = ident ~typeArgs:[ x ] "Set"
let stringT = ident "string"
let unitT = ident "void"
let weakmapT (x, y) = ident ~typeArgs:[ x; y ] "WeakMap"
let weaksetT x = ident ~typeArgs:[ x ] "WeakSet"
let int64T = Tuple [ numberT; numberT ]

module NodeFilename = struct
Expand Down
5 changes: 3 additions & 2 deletions jscomp/gentype/TranslateSignatureFromTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ let translateTypeDeclarationFromTypes ~config ~outputFileRelative ~resolver
Log_.item "Translate Types.type_declaration %s\n" typeName;
let declarationKind =
match type_kind with
| Type_record (labelDeclarations, _) ->
TranslateTypeDeclarations.RecordDeclarationFromTypes labelDeclarations
| Type_record (labelDeclarations, recordRepresentation) ->
TranslateTypeDeclarations.RecordDeclarationFromTypes
(labelDeclarations, recordRepresentation)
| Type_variant constructorDeclarations
when not
(TranslateTypeDeclarations.hasSomeGADTLeaf constructorDeclarations)
Expand Down
27 changes: 19 additions & 8 deletions jscomp/gentype/TranslateTypeDeclarations.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
open GenTypeCommon

type declarationKind =
| RecordDeclarationFromTypes of Types.label_declaration list
| RecordDeclarationFromTypes of
Types.label_declaration list * Types.record_representation
| GeneralDeclaration of Typedtree.core_type option
| GeneralDeclarationFromTypes of Types.type_expr option
(** As the above, but from Types not Typedtree *)
Expand Down Expand Up @@ -78,7 +79,12 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
in
{ CodeItem.importTypes; exportFromTypeDeclaration }
in
let translateLabelDeclarations labelDeclarations =
let translateLabelDeclarations ~recordRepresentation labelDeclarations =
let isOptional l =
match recordRepresentation with
| Types.Record_optional_labels lbls -> List.mem l lbls
| _ -> false
in
let fieldTranslations =
labelDeclarations
|> List.map (fun { Types.ld_id; ld_mutable; ld_type; ld_attributes } ->
Expand Down Expand Up @@ -111,7 +117,7 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
->
let optional, type1 =
match type_ with
| Option type1 -> (Optional, type1)
| Option type1 when isOptional nameRE -> (Optional, type1)
| _ -> (Mandatory, type_)
in
{ mutable_; nameJS; nameRE; optional; type_ = type1 })
Expand Down Expand Up @@ -201,9 +207,10 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
in
{ translation with type_ } |> handleGeneralDeclaration
|> returnTypeDeclaration
| RecordDeclarationFromTypes labelDeclarations, None ->
| RecordDeclarationFromTypes (labelDeclarations, recordRepresentation), None
->
let { TranslateTypeExprFromTypes.dependencies; type_ } =
labelDeclarations |> translateLabelDeclarations
labelDeclarations |> translateLabelDeclarations ~recordRepresentation
in
let importTypes =
dependencies
Expand Down Expand Up @@ -233,7 +240,11 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
|> TranslateTypeExprFromTypes.translateTypeExprsFromTypes
~config ~typeEnv
| Cstr_record labelDeclarations ->
[ labelDeclarations |> translateLabelDeclarations ]
[
labelDeclarations
|> translateLabelDeclarations
~recordRepresentation:Types.Record_regular;
]
in
let inlineRecord =
match constructorArgs with
Expand Down Expand Up @@ -357,8 +368,8 @@ let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver
in
let declarationKind =
match typ_type.type_kind with
| Type_record (labelDeclarations, _) ->
RecordDeclarationFromTypes labelDeclarations
| Type_record (labelDeclarations, recordRepresentation) ->
RecordDeclarationFromTypes (labelDeclarations, recordRepresentation)
| Type_variant constructorDeclarations ->
VariantDeclarationFromTypes constructorDeclarations
| Type_abstract -> GeneralDeclaration typ_manifest
Expand Down
Loading