Skip to content

Commit

Permalink
Port PR #6021 to compiler v10.1
Browse files Browse the repository at this point in the history
  • Loading branch information
cristianoc committed Mar 2, 2023
1 parent 658b85c commit 619ebb1
Show file tree
Hide file tree
Showing 274 changed files with 586 additions and 282 deletions.
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

0 comments on commit 619ebb1

Please sign in to comment.