|
22 | 22 | * along with this program; if not, write to the Free Software
|
23 | 23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
|
24 | 24 |
|
25 |
| -open Ast_helper |
26 |
| - |
27 | 25 | type label_exprs = (Longident.t Asttypes.loc * Parsetree.expression) list
|
28 | 26 |
|
29 | 27 | let js_property loc obj (name : string) =
|
30 | 28 | Parsetree.Pexp_send (obj, { loc; txt = name })
|
31 | 29 |
|
32 |
| -let ocaml_obj_as_js_object loc (mapper : Bs_ast_mapper.mapper) |
33 |
| - (self_pat : Parsetree.pattern) (clfs : Parsetree.class_field list) = |
34 |
| - (* Attention: we should avoid type variable conflict for each method |
35 |
| - Since the method name is unique, there would be no conflict |
36 |
| - OCaml does not allow duplicate instance variable and duplicate methods, |
37 |
| - but it does allow duplicates between instance variable and method name, |
38 |
| - we should enforce such rules |
39 |
| - {[ |
40 |
| - object [@bs] |
41 |
| - val x = 3 |
42 |
| - method x = 3 |
43 |
| - end |
44 |
| - ]} should not compile with a meaningful error message |
45 |
| - *) |
46 |
| - let generate_val_method_pair loc (mapper : Bs_ast_mapper.mapper) |
47 |
| - (val_name : string Asttypes.loc) is_mutable = |
48 |
| - let result = Typ.var ~loc val_name.txt in |
49 |
| - ( result, |
50 |
| - Parsetree.Otag (val_name, [], result) |
51 |
| - :: |
52 |
| - (if is_mutable then |
53 |
| - [ |
54 |
| - Otag |
55 |
| - ( { val_name with txt = val_name.txt ^ Literals.setter_suffix }, |
56 |
| - [], |
57 |
| - Ast_typ_uncurry.to_method_type loc mapper Nolabel result |
58 |
| - (Ast_literal.type_unit ~loc ()) ); |
59 |
| - ] |
60 |
| - else []) ) |
61 |
| - in |
62 |
| - |
63 |
| - (* Note mapper is only for API compatible |
64 |
| - * TODO: we should check label name to avoid conflict |
65 |
| - *) |
66 |
| - |
67 |
| - (* we need calculate the real object type |
68 |
| - and exposed object type, in some cases there are equivalent |
69 |
| -
|
70 |
| - for public object type its [@meth] it does not depend on itself |
71 |
| - while for label argument it is [@this] which depends internal object |
72 |
| - *) |
73 |
| - let ( (internal_label_attr_types : Parsetree.object_field list), |
74 |
| - (public_label_attr_types : Parsetree.object_field list) ) = |
75 |
| - Ext_list.fold_right clfs ([], []) |
76 |
| - (fun |
77 |
| - ({ pcf_loc = loc } as x : Parsetree.class_field) |
78 |
| - (label_attr_types, public_label_attr_types) |
79 |
| - -> |
80 |
| - match x.pcf_desc with |
81 |
| - | Pcf_method (label, public_flag, Cfk_concrete (Fresh, e)) -> ( |
82 |
| - match e.pexp_desc with |
83 |
| - | Pexp_poly ({ pexp_desc = Pexp_fun (lbl, _, pat, e) }, None) -> |
84 |
| - let method_type = |
85 |
| - Ast_typ_uncurry.generate_arg_type x.pcf_loc mapper label.txt |
86 |
| - lbl pat e |
87 |
| - in |
88 |
| - ( Parsetree.Otag (label, [], method_type) :: label_attr_types, |
89 |
| - if public_flag = Public then |
90 |
| - Parsetree.Otag (label, [], method_type) |
91 |
| - :: public_label_attr_types |
92 |
| - else public_label_attr_types ) |
93 |
| - | Pexp_poly (_, Some _) -> |
94 |
| - Location.raise_errorf ~loc |
95 |
| - "polymorphic type annotation not supported yet" |
96 |
| - | Pexp_poly (_, None) -> |
97 |
| - Location.raise_errorf ~loc |
98 |
| - "Unsupported syntax, expect syntax like `method x () = x ` " |
99 |
| - | _ -> Location.raise_errorf ~loc "Unsupported syntax in js object") |
100 |
| - | Pcf_val (label, mutable_flag, Cfk_concrete (Fresh, _)) -> |
101 |
| - let _, label_attr = |
102 |
| - generate_val_method_pair x.pcf_loc mapper label |
103 |
| - (mutable_flag = Mutable) |
104 |
| - in |
105 |
| - ( Ext_list.append label_attr label_attr_types, |
106 |
| - public_label_attr_types ) |
107 |
| - | Pcf_val (_, _, Cfk_concrete (Override, _)) -> |
108 |
| - Location.raise_errorf ~loc "override flag not support currently" |
109 |
| - | Pcf_val (_, _, Cfk_virtual _) -> |
110 |
| - Location.raise_errorf ~loc "virtual flag not support currently" |
111 |
| - | Pcf_method (_, _, Cfk_concrete (Override, _)) -> |
112 |
| - Location.raise_errorf ~loc "override flag not supported" |
113 |
| - | Pcf_method (_, _, Cfk_virtual _) -> |
114 |
| - Location.raise_errorf ~loc "virtural method not supported" |
115 |
| - | Pcf_inherit _ | Pcf_initializer _ | Pcf_attribute _ | Pcf_extension _ |
116 |
| - | Pcf_constraint _ -> |
117 |
| - Location.raise_errorf ~loc "Only method support currently") |
118 |
| - in |
119 |
| - let internal_obj_type = |
120 |
| - Ast_core_type.make_obj ~loc internal_label_attr_types |
121 |
| - in |
122 |
| - let public_obj_type = Ast_core_type.make_obj ~loc public_label_attr_types in |
123 |
| - let labels, label_types, exprs, _ = |
124 |
| - Ext_list.fold_right clfs ([], [], [], false) |
125 |
| - (fun (x : Parsetree.class_field) (labels, label_types, exprs, aliased) -> |
126 |
| - match x.pcf_desc with |
127 |
| - | Pcf_method (label, _public_flag, Cfk_concrete (Fresh, e)) -> ( |
128 |
| - match e.pexp_desc with |
129 |
| - | Pexp_poly |
130 |
| - (({ pexp_desc = Pexp_fun (ll, None, pat, e) } as f), None) -> |
131 |
| - let alias_type = |
132 |
| - if aliased then None else Some internal_obj_type |
133 |
| - in |
134 |
| - let label_type = |
135 |
| - Ast_typ_uncurry.generate_method_type ?alias_type x.pcf_loc |
136 |
| - mapper label.txt ll pat e |
137 |
| - in |
138 |
| - ( label :: labels, |
139 |
| - label_type :: label_types, |
140 |
| - { |
141 |
| - f with |
142 |
| - pexp_desc = |
143 |
| - (let f = Ast_pat.is_unit_cont pat ~yes:e ~no:f in |
144 |
| - Ast_uncurry_gen.to_method_callback loc mapper Nolabel |
145 |
| - self_pat f) |
146 |
| - (* the first argument is this*); |
147 |
| - } |
148 |
| - :: exprs, |
149 |
| - true ) |
150 |
| - | Pexp_poly (_, Some _) -> |
151 |
| - Location.raise_errorf ~loc |
152 |
| - "polymorphic type annotation not supported yet" |
153 |
| - | Pexp_poly (_, None) -> |
154 |
| - Location.raise_errorf ~loc |
155 |
| - "Unsupported syntax, expect syntax like `method x () = x ` " |
156 |
| - | _ -> Location.raise_errorf ~loc "Unsupported syntax in js object") |
157 |
| - | Pcf_val (label, mutable_flag, Cfk_concrete (Fresh, val_exp)) -> |
158 |
| - let label_type, _ = |
159 |
| - generate_val_method_pair x.pcf_loc mapper label |
160 |
| - (mutable_flag = Mutable) |
161 |
| - in |
162 |
| - ( label :: labels, |
163 |
| - label_type :: label_types, |
164 |
| - mapper.expr mapper val_exp :: exprs, |
165 |
| - aliased ) |
166 |
| - | Pcf_val (_, _, Cfk_concrete (Override, _)) -> |
167 |
| - Location.raise_errorf ~loc "override flag not support currently" |
168 |
| - | Pcf_val (_, _, Cfk_virtual _) -> |
169 |
| - Location.raise_errorf ~loc "virtual flag not support currently" |
170 |
| - | Pcf_method (_, _, Cfk_concrete (Override, _)) -> |
171 |
| - Location.raise_errorf ~loc "override flag not supported" |
172 |
| - | Pcf_method (_, _, Cfk_virtual _) -> |
173 |
| - Location.raise_errorf ~loc "virtural method not supported" |
174 |
| - | Pcf_inherit _ | Pcf_initializer _ | Pcf_attribute _ | Pcf_extension _ |
175 |
| - | Pcf_constraint _ -> |
176 |
| - Location.raise_errorf ~loc "Only method support currently") |
177 |
| - in |
178 |
| - let pval_type = |
179 |
| - Ext_list.fold_right2 labels label_types public_obj_type |
180 |
| - (fun label label_type acc -> |
181 |
| - Ast_compatible.label_arrow ~loc:label.Asttypes.loc label.Asttypes.txt |
182 |
| - label_type acc) |
183 |
| - in |
184 |
| - Ast_external_mk.local_extern_cont_to_obj loc |
185 |
| - ~pval_prim:(Ast_external_process.pval_prim_of_labels labels) |
186 |
| - (fun e -> |
187 |
| - Ast_compatible.apply_labels ~loc e |
188 |
| - (Ext_list.map2 labels exprs (fun l expr -> (l.txt, expr)))) |
189 |
| - ~pval_type |
190 |
| - |
191 | 30 | let record_as_js_object loc (self : Bs_ast_mapper.mapper)
|
192 | 31 | (label_exprs : label_exprs) : Parsetree.expression_desc =
|
193 | 32 | let labels, args, arity =
|
|
0 commit comments