Skip to content

Commit cabf9ee

Browse files
committed
Add Json example.
And add built-in knowledge that Js.Dict.t is an object.
1 parent afc960e commit cabf9ee

File tree

4 files changed

+117
-18
lines changed

4 files changed

+117
-18
lines changed

jscomp/core/js_exp_make.ml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -772,31 +772,29 @@ let is_type_number ?comment (e : t) : t =
772772
string_equal ?comment (typeof e) (str "number")
773773

774774
let rec is_a_literal_case ~(literal_cases : Lambda.literal list) ~block_cases (e:t) : t =
775-
let is_literal_case (l:Lambda.literal) : t =
776-
{ expression_desc = Bin (EqEqEq, e, literal l); comment=None }
777-
in
775+
let is_literal_case (l:Lambda.literal) : t = bin EqEqEq e (literal l) in
778776
let is_block_case (c:Lambda.block_type) : t = match c with
779-
| Lambda.StringType -> { expression_desc = Bin (NotEqEq, typeof e, str "string"); comment=None }
780-
| IntType -> { expression_desc = Bin (NotEqEq, typeof e, str "number"); comment=None }
781-
| FloatType -> { expression_desc = Bin (NotEqEq, typeof e, str "number"); comment=None }
782-
| Array -> { expression_desc = Bin (InstanceOf, e, str "object"); comment=None }
777+
| StringType -> bin NotEqEq (typeof e) (str "string")
778+
| IntType -> bin NotEqEq (typeof e) (str "number")
779+
| FloatType -> bin NotEqEq (typeof e) (str "number")
780+
| Array -> not (bin InstanceOf e (str "Array" ~delim:DNoQuotes))
783781
| Object -> { expression_desc = Bin (NotEqEq, typeof e, str "object"); comment=None }
784782
| Unknown ->
785783
(* We don't know the type of unknown, so we need to express:
786784
this is not one of the literals *)
787785
(match literal_cases with
788786
| [] -> { expression_desc = Bool true; comment=None}
789787
| l1 :: others ->
790-
let is_litera_1 = is_literal_case l1 in
791-
Ext_list.fold_right others is_litera_1 (fun literal_n acc ->
792-
{ J.expression_desc = Bin (Or, is_literal_case literal_n, acc); comment = None }
788+
let is_literal_1 = is_literal_case l1 in
789+
Ext_list.fold_right others is_literal_1 (fun literal_n acc ->
790+
bin Or (is_literal_case literal_n) acc
793791
)
794792
)
795793
in
796794
match block_cases with
797795
| [c] -> is_block_case c
798796
| c1 :: (_::_ as rest) ->
799-
{ J.expression_desc = Bin (And, is_block_case c1, is_a_literal_case ~literal_cases ~block_cases:rest e ); comment = None }
797+
bin And (is_block_case c1) (is_a_literal_case ~literal_cases ~block_cases:rest e)
800798
| [] -> assert false
801799

802800
let is_tag ?(has_null_undefined_other=(false, false, false)) (e : t) : t =

jscomp/core/matching_polyfill.ml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,33 @@ let names_from_construct_pattern (pat : Typedtree.pattern) =
5454
literal = Ast_attributes.process_as_value cstr.cd_attributes } in
5555
let get_tag_name (cstr: Types.constructor_declaration) =
5656
Ast_attributes.process_tag_name cstr.cd_attributes in
57-
let get_untagged (cstr: Types.constructor_declaration) =
57+
let get_untagged (cstr: Types.constructor_declaration) : Lambda.block_type option =
5858
match Ast_attributes.process_untagged cstr.cd_attributes, cstr.cd_args with
5959
| false, _ -> None
6060
| true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_string ->
61-
Some Lambda.StringType
61+
Some StringType
6262
| true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_int ->
6363
Some IntType
6464
| true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_float ->
6565
Some FloatType
6666
| true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path.same path Predef.path_array ->
6767
Some Array
68+
| true, Cstr_tuple [{desc = Tconstr (path, _, _)}] when Path. same path Predef.path_string ->
69+
Some StringType
70+
| true, Cstr_tuple [{desc = Tconstr (path, _, _)}] ->
71+
(match Path.name path with
72+
| "Js.Dict.t"
73+
| "Js_dict.t" -> Some Object
74+
| _ -> Some Unknown)
6875
| true, Cstr_tuple (_ :: _ :: _) ->
6976
(* C(_, _) with at least 2 args is an object *)
7077
Some Object
71-
| true, Cstr_record _ ->
72-
(* inline record is an object *)
73-
Some Object
7478
| true, Cstr_tuple [_] ->
7579
(* Every other single payload is unknown *)
7680
Some Unknown
81+
| true, Cstr_record _ ->
82+
(* inline record is an object *)
83+
Some Object
7784
| true, _ -> None (* TODO: add restrictions here *)
7885
in
7986
let get_block cstr : Lambda.block =

jscomp/test/UntaggedVariants.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,49 @@ var WithArray = {
168168
classify: classify$5
169169
};
170170

171+
function classify$6(x) {
172+
if (!(x instanceof Array) && typeof x !== "object" && typeof x !== "number" && typeof x !== "string") {
173+
switch (x) {
174+
case false :
175+
return "JSONFalse";
176+
case true :
177+
return "JSONTrue";
178+
case null :
179+
return "JSONNull";
180+
181+
}
182+
} else {
183+
if (x instanceof Array) {
184+
return {
185+
TAG: "JSONArray",
186+
_0: x
187+
};
188+
}
189+
switch (typeof x) {
190+
case "string" :
191+
return {
192+
TAG: "JSONString",
193+
_0: x
194+
};
195+
case "number" :
196+
return {
197+
TAG: "JSONNumber",
198+
_0: x
199+
};
200+
case "object" :
201+
return {
202+
TAG: "JSONObject",
203+
_0: x
204+
};
205+
206+
}
207+
}
208+
}
209+
210+
var Json = {
211+
classify: classify$6
212+
};
213+
171214
var i = 42;
172215

173216
var i2 = 42.5;
@@ -200,4 +243,5 @@ exports.Unknown = Unknown;
200243
exports.MultipleBlocks = MultipleBlocks;
201244
exports.OnlyBlocks = OnlyBlocks;
202245
exports.WithArray = WithArray;
246+
exports.Json = Json;
203247
/* l2 Not a pure module */

jscomp/test/UntaggedVariants.res

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,64 @@ module OnlyBlocks = {
122122

123123
module WithArray = {
124124
@unboxed
125-
type t<'a> = String(string) | Float(float) | Array(array<string>)| Object({name: string})
125+
type t<'a> = String(string) | Float(float) | Array(array<string>) | Object({name: string})
126126

127127
let classify = x =>
128128
switch x {
129129
| String(_) => "string"
130130
| Float(_) => "int"
131-
| Array(_) when true => "array"
131+
| Array(_) if true => "array"
132132
| Array(_) => "array"
133133
| Object({name}) => "Object" ++ name
134134
}
135135
}
136+
137+
module Json = {
138+
@unboxed
139+
type rec t =
140+
| @as(false) False
141+
| @as(true) True
142+
| @as(null) Null
143+
| String(string)
144+
| Number(float)
145+
| Object(Js.Dict.t<t>)
146+
| Array(array<t>)
147+
148+
type tagged_t =
149+
| JSONFalse
150+
| JSONTrue
151+
| JSONNull
152+
| JSONString(string)
153+
| JSONNumber(float)
154+
| JSONObject(Js.Dict.t<t>)
155+
| JSONArray(array<t>)
156+
157+
let classify = (x: t) =>
158+
switch x {
159+
| False => JSONFalse
160+
| True => JSONTrue
161+
| Null => JSONNull
162+
| String(s) => JSONString(s)
163+
| Number(n) => JSONNumber(n)
164+
| Object(o) => JSONObject(o)
165+
| Array(a) => JSONArray(a)
166+
}
167+
168+
/* from js_json.ml
169+
let classify (x : t) : tagged_t =
170+
let ty = Js.typeof x in
171+
if ty = "string" then
172+
JSONString (Obj.magic x)
173+
else if ty = "number" then
174+
JSONNumber (Obj.magic x )
175+
else if ty = "boolean" then
176+
if (Obj.magic x) = true then JSONTrue
177+
else JSONFalse
178+
else if (Obj.magic x) == Js.null then
179+
JSONNull
180+
else if Js_array2.isArray x then
181+
JSONArray (Obj.magic x)
182+
else
183+
JSONObject (Obj.magic x)
184+
*/
185+
}

0 commit comments

Comments
 (0)