Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Omit dynamic imported module from require, import statement #6232

Merged
merged 9 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

- `-bs-super-errors` flag has been removed along with Super_errors. https://github.com/rescript-lang/rescript-compiler/pull/6199

#### :bug: Bug Fix

- Remove unnecessary require and import statements when using dynamic imports. https://github.com/rescript-lang/rescript-compiler/pull/6232

#### :nail_care: Polish

- In uncurried mode, outcome printer swaps curried and uncurries function printing compared to legacy.
Expand Down
2 changes: 1 addition & 1 deletion jscomp/core/j.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ and ident = Ident.t
currently we always use quote
*)

and module_id = { id : ident; kind : Js_op.kind }
and module_id = { id : ident; kind : Js_op.kind ; dynamic_import : bool }

and required_modules = module_id list
and vident = Id of ident | Qualified of module_id * string option
Expand Down
16 changes: 12 additions & 4 deletions jscomp/core/js_dump_program.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ let node_program ~output_dir f (x : J.deps_program) =
P.newline f;
let cxt =
Js_dump_import_export.requires L.require Ext_pp_scope.empty f
(Ext_list.map x.modules (fun x ->
( x.id,
(* Not be emitted in require statements *)
(Ext_list.filter_map x.modules (fun x ->
match x.dynamic_import with
| true -> None
| false ->
Some ( x.id,
Js_name_of_module_id.string_of_module_id x ~output_dir NodeJS,
is_default x.kind )))
in
Expand All @@ -83,8 +87,12 @@ let node_program ~output_dir f (x : J.deps_program) =
let es6_program ~output_dir fmt f (x : J.deps_program) =
let cxt =
Js_dump_import_export.imports Ext_pp_scope.empty f
(Ext_list.map x.modules (fun x ->
( x.id,
(* Not be emitted in import statements *)
(Ext_list.filter_map x.modules (fun x ->
match x.dynamic_import with
| true -> None
| false ->
Some ( x.id,
Js_name_of_module_id.string_of_module_id x ~output_dir fmt,
is_default x.kind )))
in
Expand Down
14 changes: 7 additions & 7 deletions jscomp/core/js_exp_make.ml
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ let runtime_var_dot ?comment (x : string) (e1 : string) : J.expression =
{
expression_desc =
Var
(Qualified ({ id = Ident.create_persistent x; kind = Runtime }, Some e1));
(Qualified ({ id = Ident.create_persistent x; kind = Runtime; dynamic_import = false }, Some e1));
comment;
}

let ml_var_dot ?comment (id : Ident.t) e : J.expression =
{ expression_desc = Var (Qualified ({ id; kind = Ml }, Some e)); comment }
let ml_var_dot ?comment ?(dynamic_import = false) (id : Ident.t) e : J.expression =
{ expression_desc = Var (Qualified ({ id; kind = Ml; dynamic_import }, Some e)); comment }

(**
module as a value
Expand All @@ -93,7 +93,7 @@ let external_var_field ?comment ~external_name:name (id : Ident.t) ~field
~default : t =
{
expression_desc =
Var (Qualified ({ id; kind = External { name; default } }, Some field));
Var (Qualified ({ id; kind = External { name; default }; dynamic_import = false }, Some field));
comment;
}

Expand All @@ -102,13 +102,13 @@ let external_var ?comment ~external_name (id : Ident.t) : t =
expression_desc =
Var
(Qualified
( { id; kind = External { name = external_name; default = false } },
( { id; kind = External { name = external_name; default = false }; dynamic_import = false },
None ));
comment;
}

let ml_module_as_var ?comment (id : Ident.t) : t =
{ expression_desc = Var (Qualified ({ id; kind = Ml }, None)); comment }
let ml_module_as_var ?comment ?(dynamic_import = false) (id : Ident.t) : t =
{ expression_desc = Var (Qualified ({ id; kind = Ml; dynamic_import }, None)); comment }

(* Static_index .....................**)
let runtime_call module_name fn_name args =
Expand Down
4 changes: 2 additions & 2 deletions jscomp/core/js_exp_make.mli
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ val runtime_var_dot : ?comment:string -> string -> string -> t

(* val runtime_var_vid : string -> string -> J.vident *)

val ml_var_dot : ?comment:string -> Ident.t -> string -> t
val ml_var_dot : ?comment:string -> ?dynamic_import:bool -> Ident.t -> string -> t
(** [ml_var_dot ocaml_module name]
*)

Expand All @@ -66,7 +66,7 @@ val external_var_field :

val external_var : ?comment:string -> external_name:string -> Ident.t -> t

val ml_module_as_var : ?comment:string -> Ident.t -> t
val ml_module_as_var : ?comment:string -> ?dynamic_import:bool -> Ident.t -> t

val runtime_call :
string -> (* module_name *)
Expand Down
4 changes: 2 additions & 2 deletions jscomp/core/js_record_map.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ let label : label fn = unknown
let ident : ident fn = unknown

let module_id : module_id fn =
fun _self { id = _x0; kind = _x1 } ->
fun _self { id = _x0; kind = _x1; dynamic_import = _x2 } ->
let _x0 = _self.ident _self _x0 in
{ id = _x0; kind = _x1 }
{ id = _x0; kind = _x1; dynamic_import = _x2 }

let required_modules : required_modules fn =
fun _self arg -> list _self.module_id _self arg
Expand Down
14 changes: 7 additions & 7 deletions jscomp/core/lam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ module Types = struct

and t =
| Lvar of ident
| Lglobal_module of ident
| Lglobal_module of ident * bool
| Lconst of Lam_constant.t
| Lapply of apply
| Lfunction of lfunction
Expand Down Expand Up @@ -136,7 +136,7 @@ module X = struct

and t = Types.t =
| Lvar of ident
| Lglobal_module of ident
| Lglobal_module of ident * bool
| Lconst of Lam_constant.t
| Lapply of apply
| Lfunction of lfunction
Expand Down Expand Up @@ -344,8 +344,8 @@ let rec apply fn args (ap_info : ap_info) : t =

let rec eq_approx (l1 : t) (l2 : t) =
match l1 with
| Lglobal_module i1 -> (
match l2 with Lglobal_module i2 -> Ident.same i1 i2 | _ -> false)
| Lglobal_module (i1, b1) -> (
match l2 with Lglobal_module (i2, b2) -> Ident.same i1 i2 && b1 = b2 | _ -> false)
| Lvar i1 -> ( match l2 with Lvar i2 -> Ident.same i1 i2 | _ -> false)
| Lconst c1 -> (
match l2 with Lconst c2 -> Lam_constant.eq_approx c1 c2 | _ -> false)
Expand Down Expand Up @@ -434,7 +434,7 @@ let rec seq (a : t) b : t =
| _ -> Lsequence (a, b)

let var id : t = Lvar id
let global_module id = Lglobal_module id
let global_module ?(dynamic_import = false) id = Lglobal_module (id, dynamic_import)
let const ct : t = Lconst ct

let function_ ~attr ~arity ~params ~body : t =
Expand Down Expand Up @@ -574,7 +574,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
Lprim
{
primitive = Pfield (pos, Fld_module { name = f1 });
args = [ (Lglobal_module v1 | Lvar v1) ];
args = [ (Lglobal_module (v1, _) | Lvar v1) ];
}
:: args ) ->
pos = i && f = f1 && Ident.same var v1
Expand All @@ -586,7 +586,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t =
Lprim
{
primitive = Pfield (pos, Fld_module { name = f1 });
args = [ ((Lglobal_module v1 | Lvar v1) as lam) ];
args = [ ((Lglobal_module (v1, _) | Lvar v1) as lam) ];
}
:: args1 ) ->
if pos = 0 && field1 = f1 && aux rest args1 v1 1 then lam
Expand Down
4 changes: 2 additions & 2 deletions jscomp/core/lam.mli
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ and prim_info = private {

and t = private
| Lvar of ident
| Lglobal_module of ident
| Lglobal_module of ident * bool
| Lconst of Lam_constant.t
| Lapply of apply
| Lfunction of lfunction
Expand Down Expand Up @@ -98,7 +98,7 @@ val handle_bs_non_obj_ffi :
val var : ident -> t
(** Smart constructors *)

val global_module : ident -> t
val global_module : ?dynamic_import:bool -> ident -> t

val const : Lam_constant.t -> t

Expand Down
8 changes: 4 additions & 4 deletions jscomp/core/lam_arity_analysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ let rec get_arity (meta : Lam_stats.t) (lam : Lam.t) : Lam_arity.t =
| Lprim
{
primitive = Pfield (_, Fld_module { name });
args = [ Lglobal_module id ];
args = [ Lglobal_module (id, dynamic_import) ];
_;
} -> (
match (Lam_compile_env.query_external_id_info id name).arity with
match (Lam_compile_env.query_external_id_info ~dynamic_import id name).arity with
| Single x -> x
| Submodule _ -> Lam_arity.na)
| Lprim
Expand All @@ -57,12 +57,12 @@ let rec get_arity (meta : Lam_stats.t) (lam : Lam.t) : Lam_arity.t =
Lprim
{
primitive = Pfield (_, Fld_module { name });
args = [ Lglobal_module id ];
args = [ Lglobal_module (id, dynamic_import) ];
};
];
_;
} -> (
match (Lam_compile_env.query_external_id_info id name).arity with
match (Lam_compile_env.query_external_id_info ~dynamic_import id name).arity with
| Submodule subs -> subs.(m) (* TODO: shall we store it as array?*)
| Single _ -> Lam_arity.na)
(* TODO: all information except Pccall is complete, we could
Expand Down
26 changes: 13 additions & 13 deletions jscomp/core/lam_compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ type initialization = J.block
let compile output_prefix =

let rec compile_external_field (* Like [List.empty]*)
(lamba_cxt : Lam_compile_context.t) (id : Ident.t) name : Js_output.t =
match Lam_compile_env.query_external_id_info id name with
?(dynamic_import = false) (lamba_cxt : Lam_compile_context.t) (id : Ident.t) name : Js_output.t =
match Lam_compile_env.query_external_id_info ~dynamic_import id name with
| { persistent_closed_lambda = Some lam } when Lam_util.not_function lam ->
compile_lambda lamba_cxt lam
| _ ->
Js_output.output_of_expression lamba_cxt.continuation
~no_effects:no_effects_const (E.ml_var_dot id name)
~no_effects:no_effects_const (E.ml_var_dot ~dynamic_import id name)
(* TODO: how nested module call would behave,
In the future, we should keep in track of if
it is fully applied from [Lapply]
Expand Down Expand Up @@ -263,10 +263,10 @@ let rec compile_external_field (* Like [List.empty]*)
for the function, generative module or functor can be a function,
however it can not be global -- global can only module
*)
and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t)
and compile_external_field_apply ?(dynamic_import = false) (appinfo : Lam.apply) (module_id : Ident.t)
(field_name : string) (lambda_cxt : Lam_compile_context.t) : Js_output.t =
let ident_info =
Lam_compile_env.query_external_id_info module_id field_name
Lam_compile_env.query_external_id_info ~dynamic_import module_id field_name
in
let ap_args = appinfo.ap_args in
match ident_info.persistent_closed_lambda with
Expand All @@ -292,7 +292,7 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t)
| _ -> assert false)
in

let fn = E.ml_var_dot module_id ident_info.name in
let fn = E.ml_var_dot ~dynamic_import module_id ident_info.name in
let expression =
match appinfo.ap_info.ap_status with
| (App_infer_full | App_uncurry) as ap_status ->
Expand Down Expand Up @@ -1410,11 +1410,11 @@ and compile_apply (appinfo : Lam.apply) (lambda_cxt : Lam_compile_context.t) =
(* External function call: it can not be tailcall in this case*)
| {
ap_func =
Lprim { primitive = Pfield (_, fld_info); args = [ Lglobal_module id ]; _ };
Lprim { primitive = Pfield (_, fld_info); args = [ Lglobal_module (id, dynamic_import) ]; _ };
} -> (
match fld_info with
| Fld_module { name } ->
compile_external_field_apply appinfo id name lambda_cxt
compile_external_field_apply ~dynamic_import appinfo id name lambda_cxt
| _ -> assert false)
| _ -> (
(* TODO: ---
Expand Down Expand Up @@ -1491,11 +1491,11 @@ and compile_apply (appinfo : Lam.apply) (lambda_cxt : Lam_compile_context.t) =
and compile_prim (prim_info : Lam.prim_info)
(lambda_cxt : Lam_compile_context.t) =
match prim_info with
| { primitive = Pfield (_, fld_info); args = [ Lglobal_module id ]; _ } -> (
| { primitive = Pfield (_, fld_info); args = [ Lglobal_module (id, dynamic_import) ]; _ } -> (
(* should be before Lglobal_global *)
match fld_info with
| Fld_module { name = field } ->
compile_external_field lambda_cxt id field
compile_external_field ~dynamic_import lambda_cxt id field
| _ -> assert false)
| { primitive = Praise; args = [ e ]; _ } -> (
match
Expand Down Expand Up @@ -1715,13 +1715,13 @@ and compile_lambda (lambda_cxt : Lam_compile_context.t) (cur_lam : Lam.t) :
Js_output.output_of_expression lambda_cxt.continuation
~no_effects:no_effects_const
(Lam_compile_const.translate c)
| Lglobal_module i ->
| Lglobal_module (i, dynamic_import) ->
(* introduced by
1. {[ include Array --> let include = Array ]}
2. inline functor application
*)
Js_output.output_of_block_and_expression lambda_cxt.continuation []
(E.ml_module_as_var i)
(E.ml_module_as_var ~dynamic_import i)
| Lprim prim_info -> compile_prim prim_info lambda_cxt
| Lsequence (l1, l2) ->
let output_l1 =
Expand Down Expand Up @@ -1759,4 +1759,4 @@ and compile_lambda (lambda_cxt : Lam_compile_context.t) (cur_lam : Lam.t) :
in compile_recursive_lets, compile_lambda

let compile_recursive_lets ~output_prefix = fst (compile output_prefix)
let compile_lambda ~output_prefix = snd (compile output_prefix)
let compile_lambda ~output_prefix = snd (compile output_prefix)
6 changes: 3 additions & 3 deletions jscomp/core/lam_compile_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@ let add_js_module (hint_name : External_ffi_types.module_bind_name)
| Phint_nothing -> Ext_modulename.js_id_name_of_hint_name module_name)
in
let lam_module_ident : J.module_id =
{ id; kind = External { name = module_name; default } }
{ id; kind = External { name = module_name; default }; dynamic_import = false }
in
match Lam_module_ident.Hash.find_key_opt cached_tbl lam_module_ident with
| None ->
lam_module_ident +> External;
id
| Some old_key -> old_key.id

let query_external_id_info (module_id : Ident.t) (name : string) : ident_info =
let oid = Lam_module_ident.of_ml module_id in
let query_external_id_info ?(dynamic_import = false) (module_id : Ident.t) (name : string) : ident_info =
let oid = Lam_module_ident.of_ml ~dynamic_import module_id in
let cmj_table =
match Lam_module_ident.Hash.find_opt cached_tbl oid with
| None ->
Expand Down
2 changes: 1 addition & 1 deletion jscomp/core/lam_compile_env.mli
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ val add_js_module :
pay attention to for those modules are actually used or not
*)

val query_external_id_info : Ident.t -> string -> Js_cmj_format.keyed_cmj_value
val query_external_id_info : ?dynamic_import:bool -> Ident.t -> string -> Js_cmj_format.keyed_cmj_value
(**
[query_external_id_info id pos env found]
will raise if not found
Expand Down
2 changes: 1 addition & 1 deletion jscomp/core/lam_compile_primitive.ml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ let translate output_prefix loc (cxt : Lam_compile_context.t)

let path =
let module_system = get_module_system () in
Js_name_of_module_id.string_of_module_id module_id ~output_dir module_system
Js_name_of_module_id.string_of_module_id {module_id with dynamic_import = true} ~output_dir module_system
in

match module_value with
Expand Down
11 changes: 6 additions & 5 deletions jscomp/core/lam_convert.ml
Original file line number Diff line number Diff line change
Expand Up @@ -505,9 +505,10 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) :
primitive %s"
s
in
let args = Ext_list.map args convert_aux in
let dynamic_import = primitive = Pimport in
let args = Ext_list.map args (convert_aux ~dynamic_import) in
prim ~primitive ~args loc
and convert_aux (lam : Lambda.lambda) : Lam.t =
and convert_aux ?(dynamic_import = false) (lam : Lambda.lambda) : Lam.t =
match lam with
| Lvar x -> Lam.var (Hash_ident.find_default alias_tbl x x)
| Lconst x -> Lam.const (Lam_constant_convert.convert_constant x)
Expand Down Expand Up @@ -547,9 +548,9 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) :
if Ident.is_predef_exn id then
Lam.const (Const_string { s = id.name; unicode = false })
else (
may_depend may_depends (Lam_module_ident.of_ml id);
may_depend may_depends (Lam_module_ident.of_ml ~dynamic_import id);
assert (args = []);
Lam.global_module id)
Lam.global_module ~dynamic_import id)
| Lprim
( Puncurried_apply,
[ Lapply { ap_func = Lprim (Popaque, [ ap_func ], _); ap_args } ],
Expand All @@ -561,7 +562,7 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) :
for cases like `(fun [@bs] a b -> a + b ) 1 2 [@bs]` *)
| Lprim (Puncurried_apply, _, _) -> assert false
| Lprim (primitive, args, loc) ->
let args = Ext_list.map args convert_aux in
let args = Ext_list.map args (convert_aux ~dynamic_import) in
lam_prim ~primitive ~args loc
| Lswitch (e, s, _loc) -> convert_switch e s
| Lstringswitch (e, cases, default, _) ->
Expand Down
Loading