@@ -60,7 +60,7 @@ let handle_config (config : Parsetree.expression option) =
60
60
| None -> false
61
61
let noloc = Location. none
62
62
(* [eraseType] will be instrumented, be careful about the name conflict*)
63
- let eraseTypeLit = " jsMapperEraseType "
63
+ let eraseTypeLit = " _eraseType "
64
64
let eraseTypeExp = Exp. ident {loc = noloc; txt = Lident eraseTypeLit}
65
65
let eraseType x =
66
66
Ast_compatible. app1 eraseTypeExp x
@@ -70,7 +70,57 @@ let eraseTypeStr =
70
70
(Val. mk ~prim: [" %identity" ] {loc = noloc; txt = eraseTypeLit}
71
71
(Ast_compatible. arrow any any)
72
72
)
73
+ let unsafeIndex = " _index"
74
+ let unsafeIndexGet =
75
+ Str. primitive
76
+ (Val. mk ~prim: [" " ] {loc = noloc; txt = unsafeIndex} ~attrs: [Ast_attributes. bs_get_index]
77
+ (Ast_compatible. arrow (Typ. var " b" ) (Ast_compatible. arrow (Typ. var " a" ) (Typ. var " c" )))
78
+ )
79
+
80
+ (* JavaScript has allowed trailing commas in array literals since the beginning,
81
+ and later added them to object literals (ECMAScript 5) and most recently (ECMAScript 2017)
82
+ to function parameters. *)
83
+ let add_key_value buf key value last =
84
+ Ext_buffer. add_char_string buf '"' key;
85
+ Ext_buffer. add_string buf " \" :\" " ;
86
+ Ext_buffer. add_string buf value;
87
+ if last then
88
+ Ext_buffer. add_string buf " \" "
89
+ else
90
+ Ext_buffer. add_string buf " \" ,"
73
91
92
+ let buildMap (row_fields : Parsetree.row_field list ) =
93
+ let has_bs_as = ref false in
94
+ let data, revData =
95
+ let buf = Ext_buffer. create 50 in
96
+ let revBuf = Ext_buffer. create 50 in
97
+ Ext_buffer. add_string buf " {" ;
98
+ Ext_buffer. add_string revBuf " {" ;
99
+ let rec aux (row_fields : Parsetree.row_field list ) =
100
+ match row_fields with
101
+ | [] -> ()
102
+ | tag :: rest ->
103
+ (match tag with
104
+ | Rtag ({txt} , attrs , _ , [] ) ->
105
+ let name : string =
106
+ match Ast_attributes. iter_process_bs_string_as attrs with
107
+ | Some name ->
108
+ has_bs_as := true ;
109
+ name
110
+ | None -> txt in
111
+ let last = rest = [] in
112
+ add_key_value buf txt name last ;
113
+ add_key_value revBuf name txt last
114
+ | _ -> assert false (* checked by [is_enum_polyvar] *)
115
+ ); aux rest
116
+ in
117
+ aux row_fields;
118
+ Ext_buffer. add_string buf " }" ;
119
+ Ext_buffer. add_string revBuf " }" ;
120
+ Ext_buffer. contents buf, Ext_buffer. contents revBuf
121
+ in
122
+ data,revData, ! has_bs_as
123
+ let app1 = Ast_compatible. app1
74
124
let app2 = Ast_compatible. app2
75
125
let app3 = Ast_compatible. app3
76
126
@@ -222,89 +272,36 @@ let init () =
222
272
| Ptype_abstract ->
223
273
(match Ast_polyvar. is_enum_polyvar tdcl with
224
274
| Some row_fields ->
225
- let expConstantArray =
226
- Exp. ident {loc; txt = Longident. Lident constantArray} in
227
- (* let has_bs_as = ref false in *)
228
- let result : _ list =
229
- Ext_list. map row_fields (fun tag ->
230
- match tag with
231
- | Rtag ({txt} , attrs , _ , [] ) ->
232
- (txt,
233
- match Ast_attributes. iter_process_bs_string_as_ast attrs with
234
- | Some name ->
235
- name
236
- | None ->
237
- Ast_compatible. const_exp_string txt
238
- )
239
- | _ -> assert false (* checked by [is_enum_polyvar] *)
240
- ) in
241
- let result_len = List. length result in
242
- let exp_len = Ast_compatible. const_exp_int result_len in
243
- let search upper polyvar array =
244
- app3
245
- (Exp. ident ({loc = noloc;
246
- txt = Longident. Ldot (jsMapperRt," binarySearch" ) })
247
- )
248
- upper
249
- (eraseType polyvar)
250
- array in
251
- let revSearch len constantArray exp =
252
- app3
253
- (Exp. ident
254
- {loc= noloc;
255
- txt = Longident. Ldot (jsMapperRt, " revSearch" )})
256
- len
257
- constantArray
258
- exp in
259
- let revSearchAssert len constantArray exp =
260
- app3
261
- (Exp. ident
262
- {loc= noloc;
263
- txt = Longident. Ldot (jsMapperRt, " revSearchAssert" )})
264
- len
265
- constantArray
266
- exp in
267
-
275
+ let map, revMap = " _map" , " _revMap" in
276
+ let expMap = Exp. ident {loc; txt = Lident map} in
277
+ let revExpMap = Exp. ident {loc ; txt = Lident revMap} in
278
+ let data, revData, has_bs_as = buildMap row_fields in
279
+ let exp_get = (Exp. ident {loc ; txt = Lident unsafeIndex}) in
268
280
let v = [
269
- eraseTypeStr;
281
+ eraseTypeStr;
282
+ unsafeIndexGet;
283
+ Ast_comb. single_non_rec_value
284
+ {loc; txt = map}
285
+ (Exp. extension ({txt = " raw" ;loc}, PStr [Str. eval (Exp. constant(Const. string data))]));
270
286
Ast_comb. single_non_rec_value
271
- {loc; txt = constantArray}
272
- (Exp. array
273
- (Ext_list. map (List. sort (fun (a ,_ ) (b ,_ ) -> compare (a: Ast_compatible.hash_label ) b) result)
274
- (fun (i ,str ) ->
275
- Exp. tuple
276
- [
277
- Ast_compatible. const_hash_label i;
278
- str
279
- ]
280
- ) ));
281
- (
282
- toJsBody
283
- (coerceResultToNewType
284
- (search
285
- exp_len
286
- exp_param
287
- expConstantArray
288
- ))
289
- );
287
+ {loc; txt = revMap}
288
+ (if has_bs_as then
289
+ (Exp. extension ({txt = " raw" ;loc}, PStr [Str. eval (Exp. constant(Const. string revData))]))
290
+ else expMap);
291
+ toJsBody
292
+ (if has_bs_as then
293
+ app2 exp_get expMap exp_param
294
+ else app1 eraseTypeExp exp_param)
295
+ ;
290
296
Ast_comb. single_non_rec_value
291
297
patFromJs
292
298
(Ast_compatible. fun_
293
299
(Pat. var pat_param)
294
- (if createType then
295
- revSearchAssert
296
- exp_len
297
- expConstantArray
298
- (exp_param +: newType)
299
- +>
300
- core_type
301
- else
302
- revSearch
303
- exp_len
304
- expConstantArray
300
+ (
301
+ app2
302
+ exp_get
303
+ revExpMap
305
304
exp_param
306
- +>
307
- Ast_core_type. lift_option_type core_type
308
305
)
309
306
)
310
307
] in
0 commit comments