Skip to content

Commit 91afcb8

Browse files
committed
handle instanceof for untagged variants in code generator
1 parent ef5eead commit 91afcb8

File tree

3 files changed

+108
-13
lines changed

3 files changed

+108
-13
lines changed

jscomp/core/lam_compile.ml

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -762,18 +762,23 @@ and compile_untagged_cases ~cxt ~switch_exp ~default ~block_cases cases =
762762
in
763763
E.emit_check check
764764
in
765-
let is_array (l, _) = l = Ast_untagged_variants.Untagged (InstanceType Array) in
765+
let is_not_typeof (l, _) = match l with
766+
| Ast_untagged_variants.Untagged (InstanceType _) -> true
767+
| _ -> false in
766768
let switch ?default ?declaration e clauses =
767-
let array_clauses = Ext_list.filter clauses is_array in
768-
match array_clauses with
769-
| [(l, {J.switch_body})] when List.length clauses > 1 ->
770-
let rest = Ext_list.filter clauses (fun c -> not (is_array c)) in
769+
let not_typeof_clauses = Ext_list.filter clauses is_not_typeof in
770+
let typeof_clauses = Ext_list.filter clauses (fun c -> not (is_not_typeof c)) in
771+
let rec build_if_chain remaining_clauses = (match remaining_clauses with
772+
| (Ast_untagged_variants.Untagged (InstanceType Array), {J.switch_body}) :: rest ->
771773
S.if_ (E.is_array e)
772774
(switch_body)
773-
~else_:([S.string_switch ?default ?declaration (E.typeof e) rest])
774-
| _ :: _ :: _ -> assert false (* at most 1 array case *)
775-
| _ ->
776-
S.string_switch ?default ?declaration (E.typeof e) clauses in
775+
~else_:([build_if_chain rest])
776+
| (Ast_untagged_variants.Untagged (InstanceType instanceType), {J.switch_body}) :: rest ->
777+
S.if_ (E.instanceof e (E.js_global (Ast_untagged_variants.Instance.to_string instanceType)))
778+
(switch_body)
779+
~else_:([build_if_chain rest])
780+
| _ -> S.string_switch ?default ?declaration (E.typeof e) typeof_clauses) in
781+
build_if_chain not_typeof_clauses in
777782
cases |> compile_general_cases
778783
~make_exp: E.tag_type
779784
~eq_exp: mk_eq

jscomp/test/UntaggedVariants.js

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/test/UntaggedVariants.res

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,16 +296,16 @@ module OptionUnboxingHeuristic = {
296296

297297
module TestFunctionCase = {
298298
@unboxed
299-
type t = Array(array<int>) | Record({x:int}) | Function((. int) => int)
299+
type t = Array(array<int>) | Record({x: int}) | Function((. int) => int)
300300

301301
let classify = v =>
302302
switch v {
303303
| Record({x}) => x
304304
| Array(a) => a[0]
305-
| Function(f) => f(. 3)
305+
| Function(f) => f(. 3)
306306
}
307307

308-
let ff = Function((. x) => x+1)
308+
let ff = Function((. x) => x + 1)
309309
}
310310

311311
module ComplexPattern = {
@@ -336,4 +336,38 @@ module ComplexPattern = {
336336
| Array([True, False, Array([String("My name is"), Number(10.)])]) => Js.log("yup")
337337
| _ => Js.log("Nope...")
338338
}
339-
}
339+
}
340+
341+
module PromiseSync = {
342+
type user = {name: string}
343+
344+
@unboxed type value = Sync(user) | Async(promise<user>) | Name(string)
345+
346+
let getUserName = async (u: value) =>
347+
switch u {
348+
| Sync(user) => user.name
349+
| Async(userPromise) =>
350+
let user = await userPromise
351+
user.name
352+
| Name(name) => name
353+
}
354+
355+
let awaitUser = async (u: value) =>
356+
switch u {
357+
| Async(userPromise) =>
358+
let user = await userPromise
359+
user.name
360+
| _ => "dummy"
361+
}
362+
}
363+
364+
module Arr = {
365+
@unboxed type arr = Array(array<string>) | String(string) | Promise(promise<string>)
366+
367+
let classify = async (a: arr) =>
368+
switch a {
369+
| Array(arr) => Js.log(arr->Belt.Array.joinWith("-"))
370+
| String(s) => Js.log(s)
371+
| Promise(p) => Js.log(await p)
372+
}
373+
}

0 commit comments

Comments
 (0)