Skip to content

Commit 9513dcc

Browse files
committed
Process @set annotation for field update as generating an uncurried function.
No need to use method types. This is not user visible, except when hovering on the editor, where now no strange type shows up. Clean up a bunch of infra for object method handling in the compiler front-end.
1 parent 2e8d490 commit 9513dcc

22 files changed

+378
-1321
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ These are only breaking changes for unformatted code.
5252
- Remove class type processing from compiler ppx https://github.com/rescript-lang/rescript-compiler/pull/5842
5353
- Remove method application via operator `##`, which does not exist in `.res` syntax https://github.com/rescript-lang/rescript-compiler/pull/5844
5454
- Treat `@meth` annotation as making the type uncurried for backwards compatibitly with some examples https://github.com/rescript-lang/rescript-compiler/pull/5845
55+
- Process `@set` annotation for field update as generating an uncurried function https://github.com/rescript-lang/rescript-compiler/pull/5846
5556

5657
# 10.1.0-rc.6
5758

jscomp/frontend/ast_core_type_class_type.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ let typ_mapper (self : Bs_ast_mapper.mapper) (ty : Parsetree.core_type) =
120120
| Meth_callback attr, attrs -> (attrs, attr +> ty)
121121
in
122122
Ast_compatible.object_field name attrs
123-
(Ast_typ_uncurry.to_method_type loc self Nolabel core_type
123+
(Ast_typ_uncurry.to_uncurry_type loc self Nolabel core_type
124124
(Ast_literal.type_unit ~loc ()))
125125
in
126126
let not_getter_setter ty =

jscomp/frontend/ast_exp_apply.ml

+9-7
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,16 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp)
182182
| Some { op = "#="; loc; args = [ obj; arg ] } -> (
183183
let gen_assignment obj name name_loc =
184184
sane_property_name_check name_loc name;
185+
let obj = self.expr self obj in
186+
let arg = self.expr self arg in
187+
let fn =
188+
Exp.send ~loc obj { txt = name ^ Literals.setter_suffix; loc }
189+
in
185190
Exp.constraint_ ~loc
186-
{
187-
e with
188-
pexp_desc =
189-
Ast_uncurry_apply.method_apply loc self obj
190-
(name ^ Literals.setter_suffix)
191-
[ (Nolabel, arg) ];
192-
}
191+
(Exp.apply ~loc
192+
~attrs:[ Ast_attributes.res_uapp ]
193+
fn
194+
[ (Nolabel, arg) ])
193195
(Ast_literal.type_unit ~loc ())
194196
in
195197
match obj.pexp_desc with

jscomp/frontend/ast_literal.ml

-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ module Lid = struct
5959

6060
let js_oo : t = Lident "Js_OO"
6161

62-
let js_meth : t = Ldot (js_oo, "Meth")
63-
6462
let js_meth_callback : t = Ldot (js_oo, "Callback")
6563

6664
let ignore_id : t = Ldot (Lident "Pervasives", "ignore")

jscomp/frontend/ast_literal.mli

-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ module Lid : sig
4747

4848
val js_oo : t
4949

50-
val js_meth : t
51-
5250
val js_meth_callback : t
5351

5452
val hidden_field : string -> t

jscomp/frontend/ast_typ_uncurry.ml

-67
Original file line numberDiff line numberDiff line change
@@ -48,73 +48,6 @@ let to_method_callback_type loc (mapper : Bs_ast_mapper.mapper)
4848
[ meth_type ]
4949
| None -> assert false
5050

51-
let self_type_lit = "self_type"
52-
53-
let generate_method_type loc (mapper : Bs_ast_mapper.mapper) ?alias_type
54-
method_name lbl pat e : Parsetree.core_type =
55-
let arity = Ast_pat.arity_of_fun pat e in
56-
let result = Typ.var ~loc method_name in
57-
let self_type loc = Typ.var ~loc self_type_lit in
58-
59-
let self_type =
60-
let v = self_type loc in
61-
match alias_type with
62-
| None -> v
63-
| Some ty -> Typ.alias ~loc ty self_type_lit
64-
in
65-
if arity = 0 then to_method_callback_type loc mapper Nolabel self_type result
66-
else
67-
let tyvars =
68-
Ext_list.mapi (lbl :: Ast_pat.labels_of_fun e) (fun i x ->
69-
(x, Typ.var ~loc (method_name ^ string_of_int i)))
70-
(* Ext_list.init arity (fun i -> Typ.var ~loc (method_name ^ string_of_int i)) *)
71-
in
72-
match tyvars with
73-
| (label, x) :: rest ->
74-
let method_rest =
75-
Ext_list.fold_right rest result (fun (label, v) acc ->
76-
Typ.arrow ~loc label v acc)
77-
in
78-
to_method_callback_type loc mapper Nolabel self_type
79-
(Typ.arrow ~loc label x method_rest)
80-
| _ -> assert false
81-
82-
let to_method_type loc (mapper : Bs_ast_mapper.mapper)
83-
(label : Asttypes.arg_label) (first_arg : Parsetree.core_type)
84-
(typ : Parsetree.core_type) =
85-
let first_arg = mapper.typ mapper first_arg in
86-
let typ = mapper.typ mapper typ in
87-
let meth_type = Typ.arrow ~loc label first_arg typ in
88-
let arity = Ast_core_type.get_uncurry_arity meth_type in
89-
match arity with
90-
| Some 0 ->
91-
Typ.constr { txt = Ldot (Ast_literal.Lid.js_meth, "arity0"); loc } [ typ ]
92-
| Some n ->
93-
Typ.constr
94-
{ txt = Ldot (Ast_literal.Lid.js_meth, "arity" ^ string_of_int n); loc }
95-
[ meth_type ]
96-
| None -> assert false
97-
98-
let generate_arg_type loc (mapper : Bs_ast_mapper.mapper) method_name label pat
99-
body : Ast_core_type.t =
100-
let arity = Ast_pat.arity_of_fun pat body in
101-
let result = Typ.var ~loc method_name in
102-
if arity = 0 then
103-
to_method_type loc mapper Nolabel (Ast_literal.type_unit ~loc ()) result
104-
else
105-
let tyvars =
106-
Ext_list.mapi (label :: Ast_pat.labels_of_fun body) (fun i x ->
107-
(x, Typ.var ~loc (method_name ^ string_of_int i)))
108-
in
109-
match tyvars with
110-
| (label, x) :: rest ->
111-
let method_rest =
112-
Ext_list.fold_right rest result (fun (label, v) acc ->
113-
Typ.arrow ~loc label v acc)
114-
in
115-
to_method_type loc mapper label x method_rest
116-
| _ -> assert false
117-
11851
let to_uncurry_type loc (mapper : Bs_ast_mapper.mapper)
11952
(label : Asttypes.arg_label) (first_arg : Parsetree.core_type)
12053
(typ : Parsetree.core_type) =

jscomp/frontend/ast_typ_uncurry.mli

-24
Original file line numberDiff line numberDiff line change
@@ -54,31 +54,7 @@ val to_uncurry_type : uncurry_type_gen
5454
{[ int -> int -> int [@bs]]}
5555
*)
5656

57-
val to_method_type : uncurry_type_gen
58-
(** syntax
59-
{[ method : int -> itn -> int ]}
60-
*)
61-
6257
val to_method_callback_type : uncurry_type_gen
6358
(** syntax:
6459
{[ 'obj -> int -> int [@bs.this] ]}
6560
*)
66-
67-
val generate_method_type :
68-
Location.t ->
69-
Bs_ast_mapper.mapper ->
70-
?alias_type:Parsetree.core_type ->
71-
string ->
72-
Asttypes.arg_label ->
73-
Parsetree.pattern ->
74-
Parsetree.expression ->
75-
Parsetree.core_type
76-
77-
val generate_arg_type :
78-
Location.t ->
79-
Bs_ast_mapper.mapper ->
80-
string ->
81-
Asttypes.arg_label ->
82-
Parsetree.pattern ->
83-
Parsetree.expression ->
84-
Parsetree.core_type

jscomp/frontend/ast_uncurry_apply.ml

-82
This file was deleted.

jscomp/frontend/ast_uncurry_apply.mli

-34
This file was deleted.

jscomp/main/builtin_cmi_datasets.ml

+3-3
Large diffs are not rendered by default.

jscomp/others/js_OO.ml

-84
Original file line numberDiff line numberDiff line change
@@ -94,87 +94,3 @@ module Callback = struct
9494
i22 : 'a [@internal]
9595
}
9696
end
97-
module Meth = struct
98-
type + 'a arity0
99-
type 'a arity1 = {
100-
i1 : 'a [@internal]
101-
}
102-
type 'a arity2 = {
103-
i2 : 'a [@internal]
104-
}
105-
type 'a arity3 = {
106-
i3 : 'a [@internal]
107-
}
108-
type 'a arity4 = {
109-
i4 : 'a [@internal]
110-
}
111-
type 'a arity5 = {
112-
i5 : 'a [@internal]
113-
}
114-
type 'a arity6 = {
115-
i6 : 'a [@internal]
116-
}
117-
type 'a arity7 = {
118-
i7 : 'a [@internal]
119-
}
120-
type 'a arity8 = {
121-
i8 : 'a [@internal]
122-
}
123-
type 'a arity9 = {
124-
i9 : 'a [@internal]
125-
}
126-
type 'a arity10 = {
127-
i10 : 'a [@internal]
128-
}
129-
type 'a arity11 = {
130-
i11 : 'a [@internal]
131-
}
132-
type 'a arity12 = {
133-
i12 : 'a [@internal]
134-
}
135-
type 'a arity13 = {
136-
i13 : 'a [@internal]
137-
}
138-
type 'a arity14 = {
139-
i14 : 'a [@internal]
140-
}
141-
type 'a arity15 = {
142-
i15 : 'a [@internal]
143-
}
144-
type 'a arity16 = {
145-
i16 : 'a [@internal]
146-
}
147-
type 'a arity17 = {
148-
i17 : 'a [@internal]
149-
}
150-
type 'a arity18 = {
151-
i18 : 'a [@internal]
152-
}
153-
type 'a arity19 = {
154-
i19 : 'a [@internal]
155-
}
156-
type 'a arity20 = {
157-
i20 : 'a [@internal]
158-
}
159-
type 'a arity21 = {
160-
i21 : 'a [@internal]
161-
}
162-
type 'a arity22 = {
163-
i22 : 'a [@internal]
164-
}
165-
end
166-
167-
(**/**)
168-
module Internal = struct
169-
open Meth
170-
(* Use opaque instead of `._n` to prevent some optimizations happening *)
171-
172-
external run : 'a arity0 -> 'a = "#run" "0"
173-
(* FIXME: remove the need for native string
174-
x##meth a b -->
175-
fullApppy (
176-
(id (unsafe_downgrade x)#meth).I_2)
177-
a b)
178-
*)
179-
end
180-
(**/**)

jscomp/test/build.ninja

+2-1
Large diffs are not rendered by default.

jscomp/test/set_annotation.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
var MyJSFile = require("MyJSFile");
4+
5+
MyJSFile.student1.name = "Mary";
6+
7+
/* Not a pure module */

jscomp/test/set_annotation.res

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type student = {
2+
@set "age": int,
3+
@set "name": string,
4+
}
5+
@module("MyJSFile") external student1: student = "student1"
6+
7+
student1["name"] = "Mary"

0 commit comments

Comments
 (0)