Skip to content

Commit

Permalink
[flow][refactor] Make CJSExtractNamedExportsTKit only depend on concr…
Browse files Browse the repository at this point in the history
…etizer

Summary:
The goal of this stack is to gradually refactor the checking and merging of modules so that we can eventually kill `ModuleT`, which really doesn't belong in `Type.t`. Instead, we want to replace everywhere where we currently accept `Type.t` but only meant to accept either module or any with `(moduletype, any_info) result`.

This diff addresses the root of the evil: `CJSExtractNamedExportsTKit`. To create `module_type` from cjs, we have to concretize a potentially lazy type to grab information. Since everything in Flow_js and annotation_inference only outputs type, we are forced to make module information a type.

This diff changes it so that we only use flow_js and annotation_inference for concretization (see the added `ConcretizeForCJSExtractNamedExports` and `Annot_ConcretizeForCJSExtractNamedExports`). Everything else can be done completely within `CJSExtractNamedExportsTKit`.

With this refactor, it becomes clear in `type_sig_merge` and `module_info_analyzer` that when we are creating module types, we are dealing with only `ModuleT` the entire time, which enables future diffs in the stack to do further cleanup.

Changelog: [internal]

Reviewed By: panagosg7

Differential Revision: D68303855

fbshipit-source-id: b10749f9a4dc3b1b00f1d487453ccf8f9c496561
  • Loading branch information
SamChou19815 authored and facebook-github-bot committed Jan 17, 2025
1 parent a508bd4 commit 5846cf2
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 86 deletions.
25 changes: 14 additions & 11 deletions src/typing/annotation_inference.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ let object_like_op = function
| Annot_ThisSpecializeT _
| Annot_UseT_TypeT _
| Annot_ConcretizeForImportsExports _
| Annot_ConcretizeForCJSExtractNamedExports _
| Annot_ConcretizeForInspection _
| Annot_CJSRequireT _
| Annot_ImportTypeofT _
| Annot_ImportNamedT _
| Annot_ImportDefaultT _
| Annot_ImportModuleNsT _
| Annot_CJSExtractNamedExportsT _
| Annot_ExportNamedT _
| Annot_ExportTypeT _
| Annot_AssertExportIsTypeT _
Expand Down Expand Up @@ -118,7 +118,8 @@ module type S = sig
Type.t ->
Type.t

val cjs_extract_named_exports : Context.t -> Reason.reason -> Type.moduletype -> Type.t -> Type.t
val lazy_cjs_extract_named_exports :
Context.t -> Reason.reason -> Type.moduletype -> Type.t -> Type.moduletype Lazy.t

val import_default :
Context.t -> Reason.t -> Type.import_kind -> string -> string -> bool -> Type.t -> Type.t
Expand Down Expand Up @@ -274,9 +275,6 @@ module rec ConsGen : S = struct
cx
export_t
(Annot_ExportTypeT { reason; name_loc; preferred_def_locs; export_name; target_module_t })

let cjs_extract_named_exports cx (reason, local_module) t =
ConsGen.cjs_extract_named_exports cx reason local_module t
end

let with_concretized_type cx r f t = ConsGen.elab_t cx t (Annot_ConcretizeForImportsExports (r, f))
Expand All @@ -291,8 +289,7 @@ module rec ConsGen : S = struct
module CopyNamedExportsTKit = Flow_js_utils.CopyNamedExportsT_kit (Import_export_helper)
module CopyTypeExportsTKit = Flow_js_utils.CopyTypeExportsT_kit (Import_export_helper)
module ExportTypeTKit = Flow_js_utils.ExportTypeT_kit (Import_export_helper)
module CJSExtractNamedExportsTKit =
Flow_js_utils.CJSExtractNamedExportsT_kit (Import_export_helper)
module CJSExtractNamedExportsTKit = Flow_js_utils.CJSExtractNamedExportsTKit

(***********)
(* GetProp *)
Expand Down Expand Up @@ -666,8 +663,7 @@ module rec ConsGen : S = struct
CopyNamedExportsTKit.on_AnyT cx target_module
| (AnyT (_, _), Annot_CopyTypeExportsT (_, target_module)) ->
CopyTypeExportsTKit.on_AnyT cx target_module
| (_, Annot_CJSExtractNamedExportsT (reason, local_module)) ->
CJSExtractNamedExportsTKit.on_concrete_type cx (reason, local_module) t
| (l, Annot_ConcretizeForCJSExtractNamedExports _) -> l
(******************)
(* Module imports *)
(******************)
Expand Down Expand Up @@ -1408,8 +1404,15 @@ module rec ConsGen : S = struct
and export_named cx reason export_kind value_exports_tmap type_exports_tmap t =
elab_t cx t (Annot_ExportNamedT { reason; value_exports_tmap; type_exports_tmap; export_kind })

and cjs_extract_named_exports cx reason local_module t =
elab_t cx t (Annot_CJSExtractNamedExportsT (reason, local_module))
and lazy_cjs_extract_named_exports cx reason local_module t =
lazy
(let concretize t =
match elab_t cx t (Annot_ConcretizeForCJSExtractNamedExports reason) with
| OpenT (_, id) -> get_fully_resolved_type cx id
| t -> t
in
CJSExtractNamedExportsTKit.on_type cx ~concretize (reason, local_module) t
)

and import_typeof cx reason export_name t = elab_t cx t (Annot_ImportTypeofT (reason, export_name))

Expand Down
1 change: 0 additions & 1 deletion src/typing/debug_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,6 @@ and dump_use_t_ (depth, tvars) cx t =
t
| CallT { use_op; reason = _; call_action = ConcretizeCallee _; return_hint = _ } ->
p ~extra:(spf "%s ConcretizeCallee" (string_of_use_op use_op)) t
| CJSExtractNamedExportsT _ -> p t
| ConstructorT _ -> p t
| CopyNamedExportsT _ -> p t
| CopyTypeExportsT _ -> p t
Expand Down
1 change: 0 additions & 1 deletion src/typing/default_resolve.ml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ let rec default_resolve_touts ~flow ?resolve_callee cx loc u =
| HasOwnPropT _ -> ()
| GetValuesT (_, t) -> resolve t
| ElemT (_, _, _, action) -> resolve_elem_action action
| CJSExtractNamedExportsT (_, _, t)
| CopyNamedExportsT (_, _, t)
| CopyTypeExportsT (_, _, t) ->
resolve t
Expand Down
3 changes: 3 additions & 0 deletions src/typing/flow_common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ module type S = sig
val possible_concrete_types_for_sentinel_prop_test :
Context.t -> Reason.reason -> Type.t -> Type.t list

val singleton_concrete_type_for_cjs_extract_named_exports :
Context.t -> Reason.reason -> Type.t -> Type.t

val singleton_concrete_type_for_inspection : Context.t -> Reason.reason -> Type.t -> Type.t

val possible_concrete_types_for_computed_props :
Expand Down
20 changes: 8 additions & 12 deletions src/typing/flow_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -200,20 +200,11 @@ struct
{ reason; name_loc; preferred_def_locs; export_name; target_module_t; tout }
)
)

let cjs_extract_named_exports cx (reason, local_module) proto_t =
Tvar.mk_where cx reason (fun t ->
FlowJs.rec_flow
cx
DepthTrace.dummy_trace
(proto_t, CJSExtractNamedExportsT (reason, local_module, t))
)
end

module CopyNamedExportsTKit = CopyNamedExportsT_kit (Import_export_helper)
module CopyTypeExportsTKit = CopyTypeExportsT_kit (Import_export_helper)
module ExportTypeTKit = ExportTypeT_kit (Import_export_helper)
module CJSExtractNamedExportsTKit = CJSExtractNamedExportsT_kit (Import_export_helper)
include InstantiationKit

(* get prop *)
Expand Down Expand Up @@ -719,8 +710,11 @@ struct
CopyNamedExportsTKit.on_AnyT cx target_module t
| (AnyT (_, _), CopyTypeExportsT (_, target_module, t)) ->
CopyTypeExportsTKit.on_AnyT cx target_module t
| (_, CJSExtractNamedExportsT (reason, local_module, t_out)) ->
CJSExtractNamedExportsTKit.on_concrete_type cx (reason, local_module) l t_out
| ( t,
ConcretizeT
{ reason = _; kind = ConcretizeForCJSExtractNamedExports; seen = _; collector }
) ->
TypeCollector.add collector t
(******************************)
(* optional chaining - part A *)
(******************************)
Expand Down Expand Up @@ -5896,7 +5890,6 @@ struct
| BindT _
| CallT _
| CallElemT _
| CJSExtractNamedExportsT _
| CondT _
| ConstructorT _
| CopyNamedExportsT _
Expand Down Expand Up @@ -9325,6 +9318,9 @@ struct
and possible_concrete_types_for_inspection cx reason t =
possible_concrete_types ConcretizeForInspection cx reason t

and singleton_concrete_type_for_cjs_extract_named_exports cx reason t =
singleton_concrete_type ConcretizeForCJSExtractNamedExports cx reason t

and singleton_concrete_type_for_inspection cx reason t =
singleton_concrete_type ConcretizeForInspection cx reason t

Expand Down
3 changes: 3 additions & 0 deletions src/typing/flow_js.mli
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ val possible_concrete_types_for_inspection : Context.t -> Reason.reason -> Type.
val possible_concrete_types_for_imports_exports :
Context.t -> Reason.reason -> Type.t -> Type.t list

val singleton_concrete_type_for_cjs_extract_named_exports :
Context.t -> Reason.reason -> Type.t -> Type.t

val singleton_concrete_type_for_inspection : Context.t -> Reason.reason -> Type.t -> Type.t

val possible_concrete_types_for_predicate :
Expand Down
53 changes: 25 additions & 28 deletions src/typing/flow_js_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1417,8 +1417,6 @@ module type Import_export_helper_sig = sig
Type.t ->
Type.t

val cjs_extract_named_exports : Context.t -> Reason.t * Type.moduletype -> Type.t -> Type.t

val return : Context.t -> Type.t -> r
end

Expand Down Expand Up @@ -2048,34 +2046,35 @@ module ExportTypeT_kit (F : Import_export_helper_sig) = struct
F.return cx target_module_t
end

module CJSExtractNamedExportsT_kit (F : Import_export_helper_sig) = struct
let on_concrete_type cx (reason, local_module) = function
module CJSExtractNamedExportsTKit = struct
let rec on_type cx ~concretize (reason, local_module) t =
match concretize t with
| NamespaceT { namespace_symbol = _; values_type; types_tmap } ->
(* Copy props from the values part *)
let module_t = F.cjs_extract_named_exports cx (reason, local_module) values_type in
let module_type = on_type cx ~concretize (reason, local_module) values_type in
(* Copy type exports *)
F.export_named
ExportNamedTKit.mod_ModuleT
cx
( reason,
NameUtils.Map.empty,
( NameUtils.Map.empty,
Properties.extract_named_exports (Context.find_props cx types_tmap),
DirectExport
)
module_t
module_type;
module_type
(* ObjT CommonJS export values have their properties turned into named exports. *)
| DefT (_, ObjT o) ->
let { props_tmap; proto_t; _ } = o in
(* Copy props from the prototype *)
let module_t = F.cjs_extract_named_exports cx (reason, local_module) proto_t in
let module_type = on_type cx ~concretize (reason, local_module) proto_t in
(* Copy own props *)
F.export_named
ExportNamedTKit.mod_ModuleT
cx
( reason,
Properties.extract_named_exports (Context.find_props cx props_tmap),
( Properties.extract_named_exports (Context.find_props cx props_tmap),
NameUtils.Map.empty,
DirectExport
)
module_t
module_type;
module_type
(* InstanceT CommonJS export values have their properties turned into named exports. *)
| DefT (_, InstanceT { inst = { own_props; proto_props; _ }; _ }) ->
let extract_named_exports id =
Expand All @@ -2088,12 +2087,14 @@ module CJSExtractNamedExportsT_kit (F : Import_export_helper_sig) = struct
cx
(extract_named_exports own_props, NameUtils.Map.empty, DirectExport)
local_module;

(* Copy proto props *)
(* TODO: own props should take precedence *)
F.export_named
ExportNamedTKit.mod_ModuleT
cx
(reason, extract_named_exports proto_props, NameUtils.Map.empty, DirectExport)
(ModuleT local_module)
(extract_named_exports proto_props, NameUtils.Map.empty, DirectExport)
local_module;
local_module
(* If the module is exporting any or Object, then we allow any named import. *)
| AnyT _ ->
let {
Expand All @@ -2104,19 +2105,15 @@ module CJSExtractNamedExportsT_kit (F : Import_export_helper_sig) = struct
} =
local_module
in
let module_t =
ModuleT
{
module_reason;
module_export_types = { exporttypes with has_every_named_export = true };
module_is_strict;
module_available_platforms;
}
in
F.return cx module_t
{
module_reason;
module_export_types = { exporttypes with has_every_named_export = true };
module_is_strict;
module_available_platforms;
}
(* All other CommonJS export value types do not get merged into the named
* exports tmap in any special way. *)
| _ -> F.return cx (ModuleT local_module)
| _ -> local_module
end

(*******************)
Expand Down
1 change: 0 additions & 1 deletion src/typing/implicit_instantiation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ module Make (Observer : OBSERVER) (Flow : Flow_common.S) : S = struct
| GetValuesT _
| GetDictValuesT _
(* Import-export related upper bounds won't appear during implicit instantiation. *)
| CJSExtractNamedExportsT _
| CopyNamedExportsT _
| CopyTypeExportsT _
| ExportNamedT _
Expand Down
31 changes: 15 additions & 16 deletions src/typing/module_info_analyzer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -465,22 +465,21 @@ let mk_module_t =
has_every_named_export = false;
}
in
Tvar_resolver.mk_tvar_and_fully_resolve_where cx reason (fun t ->
Flow_js.flow
cx
( export_t,
CJSExtractNamedExportsT
( reason,
{
module_reason = reason_exports_module;
module_export_types;
module_is_strict = Context.is_strict cx;
module_available_platforms = Context.available_platforms cx;
},
t
)
)
)
ModuleT
(let concretize = Flow_js.singleton_concrete_type_for_cjs_extract_named_exports cx reason in
Flow_js_utils.CJSExtractNamedExportsTKit.on_type
cx
~concretize
( reason,
{
module_reason = reason_exports_module;
module_export_types;
module_is_strict = Context.is_strict cx;
module_available_platforms = Context.available_platforms cx;
}
)
export_t
)
in
let copy_star_exports cx reason exports module_t =
let copy_named_exports module_t (loc, from_ns) =
Expand Down
1 change: 0 additions & 1 deletion src/typing/ty_normalizer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,6 @@ module Make (I : INPUT) : S = struct
uses_t_aux (t :: acc) rest
| T.ReposLowerT { use_t = u; _ } :: rest -> uses_t_aux acc (u :: rest)
(* skip these *)
| T.CJSExtractNamedExportsT _ :: rest -> uses_t_aux acc rest
| u :: _ -> return (Ty.SomeUnknownUpper (T.string_of_use_ctor u))
in
(fun uses -> uses_t_aux [] uses)
Expand Down
Loading

0 comments on commit 5846cf2

Please sign in to comment.