Skip to content

Commit cdbaeac

Browse files
committed
Port PR #6021 to compiler v10.1
1 parent 658b85c commit cdbaeac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+586
-282
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
1313
# 10.1.3
1414

15+
#### :boom: Breaking Change
16+
17+
- `genType`: streamline the treatment of optionals as undefined https://github.com/rescript-lang/rescript-compiler/pull/6024
18+
- 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.
19+
- 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}`.
20+
1521
#### :nail_care: Polish
1622
- Add the gap property to jsxDOMStyle https://github.com/rescript-lang/rescript-compiler/pull/5956
1723

@@ -36,6 +42,7 @@
3642
#### :rocket: New Feature
3743

3844
- 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
45+
- `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
3946

4047
# 10.1.2
4148

jscomp/gentype/Converter.ml

+12-87
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ type t =
55
| CircularC of string * t
66
| FunctionC of functionC
77
| IdentC
8-
| NullableC of t
98
| ObjectC of fieldsC
109
| OptionC of t
1110
| PromiseC of t
12-
| RecordC of fieldsC
1311
| TupleC of t list
1412
| VariantC of variantC
1513

@@ -66,8 +64,7 @@ let rec toString converter =
6664
|> String.concat ", ")
6765
^ " -> " ^ toString retConverter ^ ")"
6866
| IdentC -> "id"
69-
| NullableC c -> "nullable(" ^ toString c ^ ")"
70-
| ObjectC fieldsC | RecordC fieldsC ->
67+
| ObjectC fieldsC ->
7168
let dot = match converter with ObjectC _ -> ". " | _ -> "" in
7269
"{" ^ dot
7370
^ (fieldsC
@@ -114,6 +111,7 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
114111
| Array (t, mutable_) ->
115112
let tConverter, tNormalized = t |> visit ~visited in
116113
(ArrayC tConverter, Array (tNormalized, mutable_))
114+
| Dict _ -> (IdentC, normalized_)
117115
| Function
118116
({ argTypes; componentName; retType; typeVars; uncurried } as function_)
119117
->
@@ -182,10 +180,10 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
182180
else (IdentC, normalized_))
183181
| Null t ->
184182
let tConverter, tNormalized = t |> visit ~visited in
185-
(NullableC tConverter, Null tNormalized)
183+
(OptionC tConverter, Null tNormalized)
186184
| Nullable t ->
187185
let tConverter, tNormalized = t |> visit ~visited in
188-
(NullableC tConverter, Nullable tNormalized)
186+
(OptionC tConverter, Nullable tNormalized)
189187
| Object (closedFlag, fields) ->
190188
let fieldsConverted =
191189
fields
@@ -214,27 +212,6 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
214212
| Promise t ->
215213
let tConverter, tNormalized = t |> visit ~visited in
216214
(PromiseC tConverter, Promise tNormalized)
217-
| Record fields ->
218-
let fieldsConverted =
219-
fields
220-
|> List.map (fun ({ type_ } as field) ->
221-
(field, type_ |> visit ~visited))
222-
in
223-
( RecordC
224-
(fieldsConverted
225-
|> List.map (fun ({ nameJS; nameRE; optional }, (converter, _)) ->
226-
{
227-
lblJS = nameJS;
228-
lblRE = nameRE;
229-
c =
230-
(match optional = Mandatory with
231-
| true -> converter
232-
| false -> OptionC converter);
233-
})),
234-
Record
235-
(fieldsConverted
236-
|> List.map (fun (field, (_, tNormalized)) ->
237-
{ field with type_ = tNormalized })) )
238215
| Tuple innerTypes ->
239216
let innerConversions, normalizedList =
240217
innerTypes |> List.map (visit ~visited) |> List.split
@@ -379,7 +356,6 @@ let rec converterIsIdentity ~config ~toJS converter =
379356
argConverter |> converterIsIdentity ~config ~toJS:(not toJS)
380357
| GroupConverter _ -> false)
381358
| IdentC -> true
382-
| NullableC c -> c |> converterIsIdentity ~config ~toJS
383359
| ObjectC fieldsC ->
384360
fieldsC
385361
|> List.for_all (fun { lblJS; lblRE; c } ->
@@ -388,9 +364,8 @@ let rec converterIsIdentity ~config ~toJS converter =
388364
match c with
389365
| OptionC c1 -> c1 |> converterIsIdentity ~config ~toJS
390366
| _ -> c |> converterIsIdentity ~config ~toJS)
391-
| OptionC c -> if toJS then c |> converterIsIdentity ~config ~toJS else false
367+
| OptionC c -> c |> converterIsIdentity ~config ~toJS
392368
| PromiseC c -> c |> converterIsIdentity ~config ~toJS
393-
| RecordC _ -> false
394369
| TupleC innerTypesC ->
395370
innerTypesC |> List.for_all (converterIsIdentity ~config ~toJS)
396371
| VariantC { withPayloads; useVariantTables } ->
@@ -519,14 +494,6 @@ let rec apply ~config ~converter ~indent ~nameGen ~toJS ~variantTables value =
519494
EmitText.funDef ~bodyArgs ~functionName:componentName ~funParams ~indent
520495
~mkBody ~typeVars
521496
| IdentC -> value
522-
| NullableC c ->
523-
EmitText.parens
524-
[
525-
value ^ " == null ? " ^ value ^ " : "
526-
^ (value
527-
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables
528-
);
529-
]
530497
| ObjectC fieldsC ->
531498
let simplifyFieldConverted fieldConverter =
532499
match fieldConverter with
@@ -550,62 +517,20 @@ let rec apply ~config ~converter ~indent ~nameGen ~toJS ~variantTables value =
550517
in
551518
"{" ^ fieldValues ^ "}"
552519
| OptionC c ->
553-
if toJS then
554-
EmitText.parens
555-
[
556-
value ^ " == null ? " ^ value ^ " : "
557-
^ (value
558-
|> apply ~config ~converter:c ~indent ~nameGen ~toJS
559-
~variantTables);
560-
]
561-
else
562-
EmitText.parens
563-
[
564-
value ^ " == null ? undefined : "
565-
^ (value
566-
|> apply ~config ~converter:c ~indent ~nameGen ~toJS
567-
~variantTables);
568-
]
520+
EmitText.parens
521+
[
522+
value ^ " == null ? " ^ value ^ " : "
523+
^ (value
524+
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables
525+
);
526+
]
569527
| PromiseC c ->
570528
let x = "$promise" |> EmitText.name ~nameGen in
571529
value ^ ".then(function _element("
572530
^ (x |> EmitType.ofTypeAny ~config)
573531
^ ") { return "
574532
^ (x |> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables)
575533
^ "})"
576-
| RecordC fieldsC ->
577-
let simplifyFieldConverted fieldConverter =
578-
match fieldConverter with
579-
| OptionC converter1
580-
when converter1 |> converterIsIdentity ~config ~toJS ->
581-
IdentC
582-
| _ -> fieldConverter
583-
in
584-
if toJS then
585-
let fieldValues =
586-
fieldsC
587-
|> List.mapi (fun index { lblJS; c = fieldConverter } ->
588-
lblJS ^ ":"
589-
^ (value
590-
|> EmitText.arrayAccess ~index
591-
|> apply ~config
592-
~converter:(fieldConverter |> simplifyFieldConverted)
593-
~indent ~nameGen ~toJS ~variantTables))
594-
|> String.concat ", "
595-
in
596-
"{" ^ fieldValues ^ "}"
597-
else
598-
let fieldValues =
599-
fieldsC
600-
|> List.map (fun { lblJS; c = fieldConverter } ->
601-
value
602-
|> EmitText.fieldAccess ~label:lblJS
603-
|> apply ~config
604-
~converter:(fieldConverter |> simplifyFieldConverted)
605-
~indent ~nameGen ~toJS ~variantTables)
606-
|> String.concat ", "
607-
in
608-
"[" ^ fieldValues ^ "]"
609534
| TupleC innerTypesC ->
610535
"["
611536
^ (innerTypesC

jscomp/gentype/EmitJs.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ let emitExportType ~emitters ~config ~typeGetNormalized ~typeNameIsInterface
9898
let typeNameIsInterface ~(exportTypeMap : CodeItem.exportTypeMap)
9999
~(exportTypeMapFromOtherFiles : CodeItem.exportTypeMap) typeName =
100100
let typeIsInterface type_ =
101-
match type_ with Object _ | Record _ -> true | _ -> false
101+
match type_ with Object _ -> true | _ -> false
102102
in
103103
match exportTypeMap |> StringMap.find typeName with
104104
| { type_ } -> type_ |> typeIsInterface
@@ -625,11 +625,11 @@ let propagateAnnotationToSubTypes ~codeItems (typeMap : CodeItem.exportTypeMap)
625625
type1 |> visit
626626
| exception Not_found ->
627627
annotatedSet := !annotatedSet |> StringSet.add typeName)
628-
| Array (t, _) -> t |> visit
628+
| Array (t, _) | Dict t -> t |> visit
629629
| Function { argTypes; retType } ->
630630
argTypes |> List.iter (fun { aType } -> visit aType);
631631
retType |> visit
632-
| GroupOfLabeledArgs fields | Object (_, fields) | Record fields ->
632+
| GroupOfLabeledArgs fields | Object (_, fields) ->
633633
fields |> List.iter (fun { type_ } -> type_ |> visit)
634634
| Option t | Null t | Nullable t | Promise t -> t |> visit
635635
| Tuple innerTypes -> innerTypes |> List.iter visit

jscomp/gentype/EmitType.ml

+16-2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
9191
arrayName ^ "<"
9292
^ (t |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
9393
^ ">"
94+
| Dict type_ ->
95+
"{[id: string]: "
96+
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
97+
^ "}"
9498
| Function
9599
{
96100
argTypes = [ { aType = Object (closedFlag, fields) } ];
@@ -117,7 +121,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
117121
| Function { argTypes; retType; typeVars } ->
118122
renderFunType ~config ~indent ~inFunType ~typeNameIsInterface ~typeVars
119123
argTypes retType
120-
| GroupOfLabeledArgs fields | Object (_, fields) | Record fields ->
124+
| GroupOfLabeledArgs fields | Object (_, fields) ->
121125
let indent1 = fields |> Indent.heuristicFields ~indent in
122126
fields
123127
|> renderFields ~config ~indent:indent1 ~inFunType ~typeNameIsInterface
@@ -137,7 +141,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
137141
"(null | "
138142
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
139143
^ ")"
140-
| Nullable type_ | Option type_ ->
144+
| Nullable type_ ->
141145
let useParens x =
142146
match type_ with
143147
| Function _ | Variant _ -> EmitText.parens [ x ]
@@ -147,6 +151,16 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
147151
^ useParens
148152
(type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
149153
^ ")"
154+
| Option type_ ->
155+
let useParens x =
156+
match type_ with
157+
| Function _ | Variant _ -> EmitText.parens [ x ]
158+
| _ -> x
159+
in
160+
"(undefined | "
161+
^ useParens
162+
(type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
163+
^ ")"
150164
| Promise type_ ->
151165
"Promise" ^ "<"
152166
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)

jscomp/gentype/GenTypeCommon.ml

+8-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type closedFlag = Open | Closed
5151

5252
type type_ =
5353
| Array of type_ * mutable_
54+
| Dict of type_
5455
| Function of function_
5556
| GroupOfLabeledArgs of fields
5657
| Ident of ident
@@ -59,7 +60,6 @@ type type_ =
5960
| Object of closedFlag * fields
6061
| Option of type_
6162
| Promise of type_
62-
| Record of fields
6363
| Tuple of type_ list
6464
| TypeVar of string
6565
| Variant of variant
@@ -100,6 +100,7 @@ and payload = { case : case; inlineRecord : bool; numArgs : int; t : type_ }
100100
let typeIsObject type_ =
101101
match type_ with
102102
| Array _ -> true
103+
| Dict _ -> true
103104
| Function _ -> false
104105
| GroupOfLabeledArgs _ -> false
105106
| Ident _ -> false
@@ -108,7 +109,6 @@ let typeIsObject type_ =
108109
| Object _ -> true
109110
| Option _ -> false
110111
| Promise _ -> true
111-
| Record _ -> true
112112
| Tuple _ -> true
113113
| TypeVar _ -> false
114114
| Variant _ -> false
@@ -201,11 +201,17 @@ let ident ?(builtin = true) ?(typeArgs = []) name =
201201

202202
let sanitizeTypeName name = name |> String.map (function '\'' -> '_' | c -> c)
203203
let unknown = ident "unknown"
204+
let bigintT = ident "BigInt"
204205
let booleanT = ident "boolean"
205206
let dateT = ident "Date"
207+
let mapT (x, y) = ident ~typeArgs:[ x; y ] "Map"
206208
let numberT = ident "number"
209+
let regexpT = ident "RegExp"
210+
let setT x = ident ~typeArgs:[ x ] "Set"
207211
let stringT = ident "string"
208212
let unitT = ident "void"
213+
let weakmapT (x, y) = ident ~typeArgs:[ x; y ] "WeakMap"
214+
let weaksetT x = ident ~typeArgs:[ x ] "WeakSet"
209215
let int64T = Tuple [ numberT; numberT ]
210216

211217
module NodeFilename = struct

jscomp/gentype/TranslateSignatureFromTypes.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ let translateTypeDeclarationFromTypes ~config ~outputFileRelative ~resolver
1212
Log_.item "Translate Types.type_declaration %s\n" typeName;
1313
let declarationKind =
1414
match type_kind with
15-
| Type_record (labelDeclarations, _) ->
16-
TranslateTypeDeclarations.RecordDeclarationFromTypes labelDeclarations
15+
| Type_record (labelDeclarations, recordRepresentation) ->
16+
TranslateTypeDeclarations.RecordDeclarationFromTypes
17+
(labelDeclarations, recordRepresentation)
1718
| Type_variant constructorDeclarations
1819
when not
1920
(TranslateTypeDeclarations.hasSomeGADTLeaf constructorDeclarations)

jscomp/gentype/TranslateTypeDeclarations.ml

+19-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
open GenTypeCommon
22

33
type declarationKind =
4-
| RecordDeclarationFromTypes of Types.label_declaration list
4+
| RecordDeclarationFromTypes of
5+
Types.label_declaration list * Types.record_representation
56
| GeneralDeclaration of Typedtree.core_type option
67
| GeneralDeclarationFromTypes of Types.type_expr option
78
(** As the above, but from Types not Typedtree *)
@@ -78,7 +79,12 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
7879
in
7980
{ CodeItem.importTypes; exportFromTypeDeclaration }
8081
in
81-
let translateLabelDeclarations labelDeclarations =
82+
let translateLabelDeclarations ~recordRepresentation labelDeclarations =
83+
let isOptional l =
84+
match recordRepresentation with
85+
| Types.Record_optional_labels lbls -> List.mem l lbls
86+
| _ -> false
87+
in
8288
let fieldTranslations =
8389
labelDeclarations
8490
|> List.map (fun { Types.ld_id; ld_mutable; ld_type; ld_attributes } ->
@@ -111,7 +117,7 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
111117
->
112118
let optional, type1 =
113119
match type_ with
114-
| Option type1 -> (Optional, type1)
120+
| Option type1 when isOptional nameRE -> (Optional, type1)
115121
| _ -> (Mandatory, type_)
116122
in
117123
{ mutable_; nameJS; nameRE; optional; type_ = type1 })
@@ -201,9 +207,10 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
201207
in
202208
{ translation with type_ } |> handleGeneralDeclaration
203209
|> returnTypeDeclaration
204-
| RecordDeclarationFromTypes labelDeclarations, None ->
210+
| RecordDeclarationFromTypes (labelDeclarations, recordRepresentation), None
211+
->
205212
let { TranslateTypeExprFromTypes.dependencies; type_ } =
206-
labelDeclarations |> translateLabelDeclarations
213+
labelDeclarations |> translateLabelDeclarations ~recordRepresentation
207214
in
208215
let importTypes =
209216
dependencies
@@ -233,7 +240,11 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
233240
|> TranslateTypeExprFromTypes.translateTypeExprsFromTypes
234241
~config ~typeEnv
235242
| Cstr_record labelDeclarations ->
236-
[ labelDeclarations |> translateLabelDeclarations ]
243+
[
244+
labelDeclarations
245+
|> translateLabelDeclarations
246+
~recordRepresentation:Types.Record_regular;
247+
]
237248
in
238249
let inlineRecord =
239250
match constructorArgs with
@@ -357,8 +368,8 @@ let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver
357368
in
358369
let declarationKind =
359370
match typ_type.type_kind with
360-
| Type_record (labelDeclarations, _) ->
361-
RecordDeclarationFromTypes labelDeclarations
371+
| Type_record (labelDeclarations, recordRepresentation) ->
372+
RecordDeclarationFromTypes (labelDeclarations, recordRepresentation)
362373
| Type_variant constructorDeclarations ->
363374
VariantDeclarationFromTypes constructorDeclarations
364375
| Type_abstract -> GeneralDeclaration typ_manifest

0 commit comments

Comments
 (0)