Skip to content

Commit 83404c1

Browse files
committed
genType: treat option<t> as t | undefined
This produces strictly fewer conversion functions, as it does not need to transform `null` to `undefined`.
1 parent 65fe259 commit 83404c1

16 files changed

+75
-72
lines changed

jscomp/gentype/Converter.ml

+10-34
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ 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
@@ -67,7 +66,6 @@ let rec toString converter =
6766
|> String.concat ", ")
6867
^ " -> " ^ toString retConverter ^ ")"
6968
| IdentC -> "id"
70-
| NullableC c -> "nullable(" ^ toString c ^ ")"
7169
| ObjectC fieldsC ->
7270
let dot =
7371
match converter with
@@ -119,8 +117,7 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
119117
| Array (t, mutable_) ->
120118
let tConverter, tNormalized = t |> visit ~visited in
121119
(ArrayC tConverter, Array (tNormalized, mutable_))
122-
| Dict _ ->
123-
(IdentC, normalized_)
120+
| Dict _ -> (IdentC, normalized_)
124121
| Function
125122
({argTypes; componentName; retType; typeVars; uncurried} as function_)
126123
->
@@ -190,10 +187,10 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
190187
else (IdentC, normalized_))
191188
| Null t ->
192189
let tConverter, tNormalized = t |> visit ~visited in
193-
(NullableC tConverter, Null tNormalized)
190+
(OptionC tConverter, Null tNormalized)
194191
| Nullable t ->
195192
let tConverter, tNormalized = t |> visit ~visited in
196-
(NullableC tConverter, Nullable tNormalized)
193+
(OptionC tConverter, Nullable tNormalized)
197194
| Object (closedFlag, fields) ->
198195
let fieldsConverted =
199196
fields
@@ -227,9 +224,6 @@ let typeGetConverterNormalized ~config ~inline ~lookupId ~typeNameIsInterface
227224
in
228225
(TupleC innerConversions, Tuple normalizedList)
229226
| TypeVar _ -> (IdentC, normalized_)
230-
| Undefined t ->
231-
let tConverter, tNormalized = t |> visit ~visited in
232-
(NullableC tConverter, Undefined tNormalized)
233227
| Variant variant ->
234228
let allowUnboxed = not variant.polymorphic in
235229
let withPayloads, normalized, unboxed =
@@ -363,7 +357,6 @@ let rec converterIsIdentity ~config ~toJS converter =
363357
argConverter |> converterIsIdentity ~config ~toJS:(not toJS)
364358
| GroupConverter _ -> false)
365359
| IdentC -> true
366-
| NullableC c -> c |> converterIsIdentity ~config ~toJS
367360
| ObjectC fieldsC ->
368361
fieldsC
369362
|> List.for_all (fun {lblJS; lblRE; c} ->
@@ -372,7 +365,7 @@ let rec converterIsIdentity ~config ~toJS converter =
372365
match c with
373366
| OptionC c1 -> c1 |> converterIsIdentity ~config ~toJS
374367
| _ -> c |> converterIsIdentity ~config ~toJS)
375-
| OptionC c -> if toJS then c |> converterIsIdentity ~config ~toJS else false
368+
| OptionC c -> c |> converterIsIdentity ~config ~toJS
376369
| PromiseC c -> c |> converterIsIdentity ~config ~toJS
377370
| TupleC innerTypesC ->
378371
innerTypesC |> List.for_all (converterIsIdentity ~config ~toJS)
@@ -501,13 +494,6 @@ let rec apply ~config ~converter ~indent ~nameGen ~toJS ~variantTables value =
501494
EmitText.funDef ~bodyArgs ~functionName:componentName ~funParams ~indent
502495
~mkBody ~typeVars
503496
| IdentC -> value
504-
| NullableC c ->
505-
EmitText.parens
506-
[
507-
value ^ " == null ? " ^ value ^ " : "
508-
^ (value
509-
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables);
510-
]
511497
| ObjectC fieldsC ->
512498
let simplifyFieldConverted fieldConverter =
513499
match fieldConverter with
@@ -536,22 +522,12 @@ let rec apply ~config ~converter ~indent ~nameGen ~toJS ~variantTables value =
536522
in
537523
"{" ^ fieldValues ^ "}"
538524
| OptionC c ->
539-
if toJS then
540-
EmitText.parens
541-
[
542-
value ^ " == null ? " ^ value ^ " : "
543-
^ (value
544-
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables
545-
);
546-
]
547-
else
548-
EmitText.parens
549-
[
550-
value ^ " == null ? undefined : "
551-
^ (value
552-
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables
553-
);
554-
]
525+
EmitText.parens
526+
[
527+
value ^ " == null ? " ^ value ^ " : "
528+
^ (value
529+
|> apply ~config ~converter:c ~indent ~nameGen ~toJS ~variantTables);
530+
]
555531
| PromiseC c ->
556532
let x = "$promise" |> EmitText.name ~nameGen in
557533
value ^ ".then(function _element("

jscomp/gentype/EmitJs.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ let propagateAnnotationToSubTypes ~codeItems (typeMap : CodeItem.exportTypeMap)
626626
retType |> visit
627627
| GroupOfLabeledArgs fields | Object (_, fields) ->
628628
fields |> List.iter (fun {type_} -> type_ |> visit)
629-
| Option t | Null t | Nullable t | Promise t | Undefined t -> t |> visit
629+
| Option t | Null t | Nullable t | Promise t -> t |> visit
630630
| Tuple innerTypes -> innerTypes |> List.iter visit
631631
| TypeVar _ -> ()
632632
| Variant {inherits; payloads} ->

jscomp/gentype/EmitType.ml

+11-5
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
140140
"(null | "
141141
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
142142
^ ")"
143-
| Nullable type_ | Option type_ ->
143+
| Nullable type_ ->
144144
let useParens x =
145145
match type_ with
146146
| Function _ | Variant _ -> EmitText.parens [x]
@@ -150,6 +150,16 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
150150
^ useParens
151151
(type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
152152
^ ")"
153+
| Option type_ ->
154+
let useParens x =
155+
match type_ with
156+
| Function _ | Variant _ -> EmitText.parens [x]
157+
| _ -> x
158+
in
159+
"(undefined | "
160+
^ useParens
161+
(type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
162+
^ ")"
153163
| Promise type_ ->
154164
"Promise" ^ "<"
155165
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
@@ -161,10 +171,6 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
161171
|> String.concat ", ")
162172
^ "]"
163173
| TypeVar s -> s
164-
| Undefined type_ ->
165-
"(undefined | "
166-
^ (type_ |> renderType ~config ~indent ~typeNameIsInterface ~inFunType)
167-
^ ")"
168174
| Variant {inherits; noPayloads; payloads; polymorphic; unboxed} ->
169175
let inheritsRendered =
170176
inherits

jscomp/gentype/GenTypeCommon.ml

-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ type type_ =
7070
| Promise of type_
7171
| Tuple of type_ list
7272
| TypeVar of string
73-
| Undefined of type_
7473
| Variant of variant
7574

7675
and fields = field list
@@ -120,7 +119,6 @@ let typeIsObject type_ =
120119
| Promise _ -> true
121120
| Tuple _ -> true
122121
| TypeVar _ -> false
123-
| Undefined _ -> false
124122
| Variant _ -> false
125123

126124
type label = Nolabel | Label of string | OptLabel of string

jscomp/gentype/TranslateTypeExprFromTypes.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ let translateConstr ~config ~paramsTranslation ~(path : Path.t) ~typeEnv =
230230
{paramTranslation with type_ = Option paramTranslation.type_}
231231
| ( (["Js"; "Undefined"; "t"] | ["Undefined"; "t"] | ["Js"; "undefined"]),
232232
[paramTranslation] ) ->
233-
{paramTranslation with type_ = Undefined paramTranslation.type_}
233+
{paramTranslation with type_ = Option paramTranslation.type_}
234234
| (["Js"; "Null"; "t"] | ["Null"; "t"] | ["Js"; "null"]), [paramTranslation]
235235
->
236236
{paramTranslation with type_ = Null paramTranslation.type_}

jscomp/gentype/TypeVars.ml

+1-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ let rec substitute ~f type0 =
6363
match f s with
6464
| None -> type0
6565
| Some type1 -> type1)
66-
| Undefined type_ -> Undefined (type_ |> substitute ~f)
6766
| Variant variant ->
6867
Variant
6968
{
@@ -91,7 +90,7 @@ let rec free_ type0 : StringSet.t =
9190
|> List.fold_left
9291
(fun s typeArg -> StringSet.union s (typeArg |> free_))
9392
StringSet.empty
94-
| Dict type_ | Null type_ | Nullable type_ | Undefined type_ -> type_ |> free_
93+
| Dict type_ | Null type_ | Nullable type_ -> type_ |> free_
9594
| Option type_ | Promise type_ -> type_ |> free_
9695
| Tuple innerTypes ->
9796
innerTypes

jscomp/gentype_tests/typescript-react-example/src/Core.bs.js

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/gentype_tests/typescript-react-example/src/Core.gen.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
/* eslint-disable import/first */
33

44

5+
const $$toJS552311971: { [key: string]: any } = {"0": "A"};
6+
7+
const $$toRE552311971: { [key: string]: any } = {"A": 0};
8+
59
// @ts-ignore: Implicit any on import
610
import * as CoreBS__Es6Import from './Core.bs';
711
const CoreBS: any = CoreBS__Es6Import;
812

13+
// tslint:disable-next-line:interface-over-type-literal
14+
export type variant = "A" | { tag: "B"; value: string };
15+
916
export const null0: (x:(null | number)) => (null | number) = CoreBS.null0;
1017

1118
export const null1: (x:(null | number)) => (null | number) = CoreBS.null1;
@@ -45,3 +52,14 @@ export const weakmap1: (x:WeakMap<number[],number>) => WeakMap<number[],number>
4552
export const set1: (x:Set<string>) => Set<string> = CoreBS.set1;
4653

4754
export const weakset1: (x:WeakSet<number[]>) => WeakSet<number[]> = CoreBS.weakset1;
55+
56+
export const option0: (x:(undefined | string)) => (undefined | string) = CoreBS.option0;
57+
58+
export const option1: (x:(undefined | variant)) => (undefined | variant) = function (Arg1: any) {
59+
const result = CoreBS.option1((Arg1 == null ? Arg1 : typeof(Arg1) === 'object'
60+
? {TAG: 0, _0:Arg1.value} as any
61+
: $$toRE552311971[Arg1]));
62+
return (result == null ? result : typeof(result) === 'object'
63+
? {tag:"B", value:result._0}
64+
: $$toJS552311971[result])
65+
};

jscomp/gentype_tests/typescript-react-example/src/Core.res

+8
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,11 @@ let set1 = (x: Set.t<string>) => x
6060

6161
@genType
6262
let weakset1 = (x: WeakSet.t<array<int>>) => x
63+
64+
type variant = A | B(string)
65+
66+
@genType
67+
let option0 = (x: option<string>) => x
68+
69+
@genType
70+
let option1 = (x: option<variant>) => x

jscomp/gentype_tests/typescript-react-example/src/TestImmutableArray.gen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
import * as TestImmutableArrayBS__Es6Import from './TestImmutableArray.bs';
77
const TestImmutableArrayBS: any = TestImmutableArrayBS__Es6Import;
88

9-
export const testImmutableArrayGet: <T1>(arr:ReadonlyArray<T1>) => (null | undefined | T1) = TestImmutableArrayBS.testImmutableArrayGet;
9+
export const testImmutableArrayGet: <T1>(arr:ReadonlyArray<T1>) => (undefined | T1) = TestImmutableArrayBS.testImmutableArrayGet;

jscomp/gentype_tests/typescript-react-example/src/TestPromise.gen.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export type toPayload = { readonly result: string };
2121

2222
export const convert: (_1:Promise<fromPayload>) => Promise<toPayload> = TestPromiseBS.convert;
2323

24-
export const barx: (_1:{ readonly x?: Promise<(null | undefined | string)> }, _2:void) => boolean = function (Arg1: any, Arg2: any) {
25-
const result = Curry._2(TestPromiseBS.barx, (Arg1.x == null ? undefined : Arg1.x.then(function _element($promise: any) { return ($promise == null ? undefined : $promise)})), Arg2);
24+
export const barx: (_1:{ readonly x?: Promise<(undefined | string)> }, _2:void) => boolean = function (Arg1: any, Arg2: any) {
25+
const result = Curry._2(TestPromiseBS.barx, Arg1.x, Arg2);
2626
return result
2727
};

jscomp/gentype_tests/typescript-react-example/src/TransitiveType1.gen.tsx

+2-8
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ import type {t2Alias as TransitiveType2_t2Alias} from './TransitiveType2.gen';
1010

1111
import type {t2 as TransitiveType2_t2} from './TransitiveType2.gen';
1212

13-
export const convert: (x:TransitiveType2_t2) => TransitiveType2_t2 = function (Arg1: any) {
14-
const result = TransitiveType1BS.convert((Arg1 == null ? undefined : Arg1));
15-
return result
16-
};
13+
export const convert: (x:TransitiveType2_t2) => TransitiveType2_t2 = TransitiveType1BS.convert;
1714

18-
export const convertAlias: (x:TransitiveType2_t2Alias) => TransitiveType2_t2Alias = function (Arg1: any) {
19-
const result = TransitiveType1BS.convertAlias((Arg1 == null ? undefined : Arg1));
20-
return result
21-
};
15+
export const convertAlias: (x:TransitiveType2_t2Alias) => TransitiveType2_t2Alias = TransitiveType1BS.convertAlias;

jscomp/gentype_tests/typescript-react-example/src/TransitiveType2.gen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import type {t3 as TransitiveType3_t3} from './TransitiveType3.gen';
66

77
// tslint:disable-next-line:interface-over-type-literal
8-
export type t2 = (null | undefined | TransitiveType3_t3);
8+
export type t2 = (undefined | TransitiveType3_t3);
99

1010
// tslint:disable-next-line:interface-over-type-literal
1111
export type t2Alias = t2;

jscomp/gentype_tests/typescript-react-example/src/Variants.gen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export const id2: (x:x2) => x2 = function (Arg1: any) {
112112
return $$toJS1061900109[result]
113113
};
114114

115-
export const polyWithOpt: (foo:string) => (null | undefined | (
115+
export const polyWithOpt: (foo:string) => (undefined | (
116116
{ NAME: "One"; VAL: string }
117117
| { NAME: "Two"; VAL: number })) = VariantsBS.polyWithOpt;
118118

jscomp/gentype_tests/typescript-react-example/src/nested/Tuples.gen.tsx

+5-11
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import * as TuplesBS__Es6Import from './Tuples.bs';
1111
const TuplesBS: any = TuplesBS__Es6Import;
1212

1313
// tslint:disable-next-line:interface-over-type-literal
14-
export type coord = [number, number, (null | undefined | number)];
14+
export type coord = [number, number, (undefined | number)];
1515

1616
// tslint:disable-next-line:interface-over-type-literal
1717
export type coord2 = [number, number, (null | undefined | number)];
@@ -24,21 +24,15 @@ export type couple = [person, person];
2424

2525
export const testTuple: (param:[number, number]) => number = TuplesBS.testTuple;
2626

27-
export const origin: [number, number, (null | undefined | number)] = TuplesBS.origin;
27+
export const origin: [number, number, (undefined | number)] = TuplesBS.origin;
2828

29-
export const computeArea: (param:[number, number, (null | undefined | number)]) => number = function (Arg1: any) {
30-
const result = TuplesBS.computeArea([Arg1[0], Arg1[1], (Arg1[2] == null ? undefined : Arg1[2])]);
31-
return result
32-
};
29+
export const computeArea: (param:[number, number, (undefined | number)]) => number = TuplesBS.computeArea;
3330

34-
export const computeAreaWithIdent: (param:coord) => number = function (Arg1: any) {
35-
const result = TuplesBS.computeAreaWithIdent([Arg1[0], Arg1[1], (Arg1[2] == null ? undefined : Arg1[2])]);
36-
return result
37-
};
31+
export const computeAreaWithIdent: (param:coord) => number = TuplesBS.computeAreaWithIdent;
3832

3933
export const computeAreaNoConverters: (param:[number, number]) => number = TuplesBS.computeAreaNoConverters;
4034

41-
export const coord2d: <T1,T2,T3>(x:T1, y:T2) => [T1, T2, (null | undefined | T3)] = function <T1,T2,T3>(Arg1: any, Arg2: any) {
35+
export const coord2d: <T1,T2,T3>(x:T1, y:T2) => [T1, T2, (undefined | T3)] = function <T1,T2,T3>(Arg1: any, Arg2: any) {
4236
const result = Curry._2(TuplesBS.coord2d, Arg1, Arg2);
4337
return result
4438
};

jscomp/gentype_tests/typescript-react-example/src/nested/Types.gen.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ export const selfRecursiveConverter: (param:selfRecursive) => selfRecursive = Ty
126126

127127
export const mutuallyRecursiveConverter: (param:mutuallyRecursiveA) => mutuallyRecursiveB = TypesBS.mutuallyRecursiveConverter;
128128

129-
export const testFunctionOnOptionsAsArgument: <T1,a>(a:(null | undefined | a), foo:((_1:(null | undefined | a)) => T1)) => T1 = function <T1,a>(Arg1: any, Arg2: any) {
130-
const result = Curry._2(TypesBS.testFunctionOnOptionsAsArgument, (Arg1 == null ? undefined : Arg1), Arg2);
129+
export const testFunctionOnOptionsAsArgument: <T1,a>(a:(undefined | a), foo:((_1:(undefined | a)) => T1)) => T1 = function <T1,a>(Arg1: any, Arg2: any) {
130+
const result = Curry._2(TypesBS.testFunctionOnOptionsAsArgument, Arg1, Arg2);
131131
return result
132132
};
133133

@@ -153,4 +153,4 @@ export const currentTime: Date = TypesBS.currentTime;
153153

154154
export const i64Const: i64B = TypesBS.i64Const;
155155

156-
export const optFunction: (null | undefined | (() => number)) = TypesBS.optFunction;
156+
export const optFunction: (undefined | (() => number)) = TypesBS.optFunction;

0 commit comments

Comments
 (0)