From 7f6d2747dfa60361bf649f3a5632d5ba3e909837 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 19:42:40 +0100 Subject: [PATCH 01/20] safeguard against infinite recursion monos --- src/core/tUnification.ml | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/core/tUnification.ml b/src/core/tUnification.ml index ff6c8f4cc17..d112b2f50b1 100644 --- a/src/core/tUnification.ml +++ b/src/core/tUnification.ml @@ -235,25 +235,37 @@ module Monomorph = struct and close m = match m.tm_type with | Some _ -> () - | None -> match classify_down_constraints m with + | None -> + let recursion_ok t = + let rec loop t = match t with + | TMono m2 when m == m2 -> + raise Exit + | _ -> + TFunctions.iter loop t + in + try + loop t; + true + with Exit -> + false + in + (* TODO: we never do anything with monos, I think *) + let monos,constraints = classify_down_constraints' m in + match constraints with | CUnknown -> () | CTypes [(t,_)] -> - do_bind m t; - () + (* TODO: silently not binding doesn't seem correct, but it's likely better than infinite recursion *) + if recursion_ok t then do_bind m t; | CTypes _ | CMixed _ -> () | CStructural(fields,_) -> let check_recursion cf = - let rec loop t = match t with - | TMono m2 when m == m2 -> + if not (recursion_ok cf.cf_type) then begin let pctx = print_context() in - let s = Printf.sprintf "%s appears in { %s: %s }" (s_type pctx t) cf.cf_name (s_type pctx cf.cf_type) in + let s = Printf.sprintf "%s appears in { %s: %s }" (s_type pctx (TMono m)) cf.cf_name (s_type pctx cf.cf_type) in raise (Unify_error [Unify_custom "Recursive type";Unify_custom s]); - | _ -> - TFunctions.map loop t - in - ignore(loop cf.cf_type); + end in (* We found a bunch of fields but no type, create a merged structure type and bind to that *) PMap.iter (fun _ cf -> check_recursion cf) fields; From 60ad1cbd33020e86528dd8c0a7c23c7f3dfb7ff8 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 19:54:00 +0100 Subject: [PATCH 02/20] restore previous printing behavior --- src/core/tType.ml | 3 +++ src/core/tUnification.ml | 23 +++++++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/core/tType.ml b/src/core/tType.ml index a391d4b4210..205d4415e91 100644 --- a/src/core/tType.ml +++ b/src/core/tType.ml @@ -449,6 +449,9 @@ and build_state = | Building of tclass list | BuildMacro of (unit -> unit) list ref + +exception Type_exception of t + type basic_types = { mutable tvoid : t; mutable tint : t; diff --git a/src/core/tUnification.ml b/src/core/tUnification.ml index d112b2f50b1..16807ceab71 100644 --- a/src/core/tUnification.ml +++ b/src/core/tUnification.ml @@ -236,18 +236,18 @@ module Monomorph = struct | Some _ -> () | None -> - let recursion_ok t = + let get_recursion t = let rec loop t = match t with | TMono m2 when m == m2 -> - raise Exit + raise (Type_exception t) | _ -> TFunctions.iter loop t in try loop t; - true - with Exit -> - false + None + with Type_exception t -> + Some t in (* TODO: we never do anything with monos, I think *) let monos,constraints = classify_down_constraints' m in @@ -256,15 +256,18 @@ module Monomorph = struct () | CTypes [(t,_)] -> (* TODO: silently not binding doesn't seem correct, but it's likely better than infinite recursion *) - if recursion_ok t then do_bind m t; + if get_recursion t = None then do_bind m t; | CTypes _ | CMixed _ -> () | CStructural(fields,_) -> let check_recursion cf = - if not (recursion_ok cf.cf_type) then begin - let pctx = print_context() in - let s = Printf.sprintf "%s appears in { %s: %s }" (s_type pctx (TMono m)) cf.cf_name (s_type pctx cf.cf_type) in - raise (Unify_error [Unify_custom "Recursive type";Unify_custom s]); + begin match get_recursion cf.cf_type with + | Some t -> + let pctx = print_context() in + let s = Printf.sprintf "%s appears in { %s: %s }" (s_type pctx t) cf.cf_name (s_type pctx cf.cf_type) in + raise (Unify_error [Unify_custom "Recursive type";Unify_custom s]); + | None -> + () end in (* We found a bunch of fields but no type, create a merged structure type and bind to that *) From 4c9976c0528506ef699fed1c498759f9a88d486a Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Thu, 1 Feb 2024 07:38:08 +0100 Subject: [PATCH 03/20] Warnings --- src/compiler/hxb/hxbWriterConfig.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/hxb/hxbWriterConfig.ml b/src/compiler/hxb/hxbWriterConfig.ml index a81d4caeec4..ee5932d9afc 100644 --- a/src/compiler/hxb/hxbWriterConfig.ml +++ b/src/compiler/hxb/hxbWriterConfig.ml @@ -1,5 +1,4 @@ open Globals -open Json open Json.Reader type writer_target_config = { From 1dec08e3c1a8fdca8475c02397af7c6a69d09586 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Thu, 1 Feb 2024 22:08:48 +0100 Subject: [PATCH 04/20] [server] do not crash when client exits before end of compilation --- src/compiler/server.ml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/compiler/server.ml b/src/compiler/server.ml index 17cde830af4..e664d8691a7 100644 --- a/src/compiler/server.ml +++ b/src/compiler/server.ml @@ -923,8 +923,19 @@ and init_wait_socket ip port = end in let read = fun _ -> (let s = read_loop 0 in Unix.clear_nonblock sin; Some s) in - let write s = ssend sin (Bytes.unsafe_of_string s) in - let close() = Unix.close sin in + let closed = ref false in + let close() = + if not !closed then begin + try Unix.close sin with Unix.Unix_error _ -> trace "Error while closing socket."; + closed := true; + end + in + let write s = + if not !closed then + match Unix.getsockopt_error sin with + | Some _ -> close() + | None -> ssend sin (Bytes.unsafe_of_string s); + in false, read, write, close ) in accept From f4bfd59842bf303a5d492cadb745d5675764302b Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Thu, 1 Feb 2024 22:14:26 +0100 Subject: [PATCH 05/20] [skip ci] add code-cookbook entry to release checklist --- extra/release-checklist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/extra/release-checklist.txt b/extra/release-checklist.txt index d8e7603049c..50589471d88 100644 --- a/extra/release-checklist.txt +++ b/extra/release-checklist.txt @@ -24,6 +24,7 @@ - Update https://github.com/HaxeFoundation/haxe.org/blob/staging/downloads/versions.json - Wait for staging to update, check everything related to release and merge to master - Update https://github.com/HaxeFoundation/api.haxe.org/blob/master/theme/templates/topbar.mtt +- Update https://github.com/HaxeFoundation/code-cookbook/blob/master/assets/content/index.mtt#L62-L63 # Cleanup From 8c5e022233bf70a36ace79fa74733aafce27845d Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Fri, 2 Feb 2024 15:07:21 +0100 Subject: [PATCH 06/20] Simplify type parameter typing (#11537) * change type parameter typing to something sensible * type defaults in the shared ttp context too * assign KTypeParameter in mk_type_param * calmly work around C# again --- src/codegen/gencommon/closuresToClass.ml | 7 +- src/codegen/gencommon/gencommon.ml | 4 +- src/compiler/hxb/hxbReader.ml | 4 +- src/context/display/displayTexpr.ml | 8 +-- src/context/typecore.ml | 4 +- src/core/tFunctions.ml | 19 +++--- src/typing/typeload.ml | 83 ++++++++++++------------ src/typing/typeloadFunction.ml | 4 +- src/typing/typeloadModule.ml | 12 ++-- 9 files changed, 72 insertions(+), 73 deletions(-) diff --git a/src/codegen/gencommon/closuresToClass.ml b/src/codegen/gencommon/closuresToClass.ml index ed45fd75b44..f79951d01c1 100644 --- a/src/codegen/gencommon/closuresToClass.ml +++ b/src/codegen/gencommon/closuresToClass.ml @@ -393,7 +393,12 @@ let configure gen ft = in (*let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(map_param cl, []) )) tparams in*) - let cltypes = List.map (fun cl -> mk_type_param cl TPHType None None) tparams in + let cltypes = List.map (fun cl -> + let lol = cl.cl_kind in + let ttp = mk_type_param cl TPHType None None in + cl.cl_kind <- lol; + ttp + ) tparams in (* create a new class that extends abstract function class, with a ctor implementation that will setup all captured variables *) let cfield = match gen.gcurrent_classfield with diff --git a/src/codegen/gencommon/gencommon.ml b/src/codegen/gencommon/gencommon.ml index e48d252c99d..b4af589c180 100644 --- a/src/codegen/gencommon/gencommon.ml +++ b/src/codegen/gencommon/gencommon.ml @@ -1142,9 +1142,7 @@ let clone_param ttp = let ret = mk_class cl.cl_module (fst cl.cl_path, snd cl.cl_path ^ "_c") cl.cl_pos null_pos in ret.cl_implements <- cl.cl_implements; ret.cl_kind <- cl.cl_kind; - let ttp = mk_type_param ret ttp.ttp_host ttp.ttp_default ttp.ttp_constraints in - ret.cl_kind <- KTypeParameter ttp; - ttp + mk_type_param ret ttp.ttp_host ttp.ttp_default ttp.ttp_constraints let get_cl_t t = match follow t with | TInst (cl,_) -> cl | _ -> die "" __LOC__ diff --git a/src/compiler/hxb/hxbReader.ml b/src/compiler/hxb/hxbReader.ml index 0adc6800bd0..a8cd5651d16 100644 --- a/src/compiler/hxb/hxbReader.ml +++ b/src/compiler/hxb/hxbReader.ml @@ -899,9 +899,7 @@ class hxb_reader | i -> die (Printf.sprintf "Invalid type paramter host: %i" i) __LOC__ in let c = mk_class current_module path pos pos in - let ttp = mk_type_param c host None None in - c.cl_kind <- KTypeParameter ttp; - ttp + mk_type_param c host None None ) method read_type_parameters_data (a : typed_type_param array) = diff --git a/src/context/display/displayTexpr.ml b/src/context/display/displayTexpr.ml index 4b6d0dd845b..105691004e1 100644 --- a/src/context/display/displayTexpr.ml +++ b/src/context/display/displayTexpr.ml @@ -87,7 +87,7 @@ let check_display_class ctx decls c = List.iter check_field c.cl_ordered_statics; | _ -> let sc = find_class_by_position decls c.cl_name_pos in - ignore(Typeload.type_type_params ctx TPHType c.cl_path (fun() -> c.cl_params) null_pos sc.d_params); + ignore(Typeload.type_type_params ctx TPHType c.cl_path null_pos sc.d_params); List.iter (function | (HExtends ptp | HImplements ptp) when display_position#enclosed_in ptp.pos_full -> ignore(Typeload.load_instance ~allow_display:true ctx ptp ParamNormal) @@ -101,7 +101,7 @@ let check_display_class ctx decls c = let check_display_enum ctx decls en = let se = find_enum_by_position decls en.e_name_pos in - ignore(Typeload.type_type_params ctx TPHType en.e_path (fun() -> en.e_params) null_pos se.d_params); + ignore(Typeload.type_type_params ctx TPHType en.e_path null_pos se.d_params); PMap.iter (fun _ ef -> if display_position#enclosed_in ef.ef_pos then begin let sef = find_enum_field_by_position se ef.ef_name_pos in @@ -111,12 +111,12 @@ let check_display_enum ctx decls en = let check_display_typedef ctx decls td = let st = find_typedef_by_position decls td.t_name_pos in - ignore(Typeload.type_type_params ctx TPHType td.t_path (fun() -> td.t_params) null_pos st.d_params); + ignore(Typeload.type_type_params ctx TPHType td.t_path null_pos st.d_params); ignore(Typeload.load_complex_type ctx true st.d_data) let check_display_abstract ctx decls a = let sa = find_abstract_by_position decls a.a_name_pos in - ignore(Typeload.type_type_params ctx TPHType a.a_path (fun() -> a.a_params) null_pos sa.d_params); + ignore(Typeload.type_type_params ctx TPHType a.a_path null_pos sa.d_params); List.iter (function | (AbOver(ct,p) | AbFrom(ct,p) | AbTo(ct,p)) when display_position#enclosed_in p -> ignore(Typeload.load_complex_type ctx true (ct,p)) diff --git a/src/context/typecore.ml b/src/context/typecore.ml index 04132c0a8af..a949bd405dd 100644 --- a/src/context/typecore.ml +++ b/src/context/typecore.ml @@ -517,9 +517,7 @@ let clone_type_parameter map path ttp = | None -> None | Some constraints -> Some (lazy (List.map map (Lazy.force constraints))) in - let ttp' = mk_type_param c ttp.ttp_host def constraints in - c.cl_kind <- KTypeParameter ttp'; - ttp' + mk_type_param c ttp.ttp_host def constraints (** checks if we can access to a given class field using current context *) let can_access ctx c cf stat = diff --git a/src/core/tFunctions.ml b/src/core/tFunctions.ml index 25d5abd5824..1c0a68c65e1 100644 --- a/src/core/tFunctions.ml +++ b/src/core/tFunctions.ml @@ -722,14 +722,17 @@ let lookup_param n l = in loop l -let mk_type_param c host def constraints = { - ttp_name = snd c.cl_path; - ttp_type = TInst(c,[]); - ttp_class = c; - ttp_host = host; - ttp_constraints = constraints; - ttp_default = def; -} +let mk_type_param c host def constraints = + let ttp = { + ttp_name = snd c.cl_path; + ttp_type = TInst(c,[]); + ttp_class = c; + ttp_host = host; + ttp_constraints = constraints; + ttp_default = def; + } in + c.cl_kind <- KTypeParameter ttp; + ttp let type_of_module_type = function | TClassDecl c -> TInst (c,extract_param_types c.cl_params) diff --git a/src/typing/typeload.ml b/src/typing/typeload.ml index 135f988ca60..f31aa999a28 100644 --- a/src/typing/typeload.ml +++ b/src/typing/typeload.ml @@ -726,42 +726,52 @@ let load_type_hint ?(opt=false) ctx pcur t = (* ---------------------------------------------------------------------- *) (* PASS 1 & 2 : Module and Class Structure *) -let rec type_type_param ctx host path get_params p tp = +let rec type_type_param ctx host path p tp = let n = fst tp.tp_name in let c = mk_class ctx.m.curmod (fst path @ [snd path],n) (pos tp.tp_name) (pos tp.tp_name) in - c.cl_params <- type_type_params ctx host c.cl_path get_params p tp.tp_params; + c.cl_params <- type_type_params ctx host c.cl_path p tp.tp_params; c.cl_meta <- tp.Ast.tp_meta; if host = TPHEnumConstructor then c.cl_meta <- (Meta.EnumConstructorParam,[],null_pos) :: c.cl_meta; - let t = TInst (c,extract_param_types c.cl_params) in + let ttp = mk_type_param c host None None in if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos tp.tp_name) then - DisplayEmitter.display_type ctx t (pos tp.tp_name); - let default = match tp.tp_default with - | None -> - None - | Some ct -> - let r = make_lazy ctx t (fun r -> - let t = load_complex_type ctx true ct in - begin match host with - | TPHType -> - () - | TPHConstructor - | TPHMethod - | TPHEnumConstructor - | TPHAnonField - | TPHLocal -> - display_error ctx.com "Default type parameters are only supported on types" (pos ct) - end; - t - ) "default" in - Some (TLazy r) - in - let ttp = match tp.tp_constraints with + DisplayEmitter.display_type ctx ttp.ttp_type (pos tp.tp_name); + ttp + +and type_type_params ctx host path p tpl = + let names = ref [] in + let param_pairs = List.map (fun tp -> + if List.exists (fun name -> name = fst tp.tp_name) !names then display_error ctx.com ("Duplicate type parameter name: " ^ fst tp.tp_name) (pos tp.tp_name); + names := (fst tp.tp_name) :: !names; + tp,type_type_param ctx host path p tp + ) tpl in + let params = List.map snd param_pairs in + let ctx = { ctx with type_params = params @ ctx.type_params } in + List.iter (fun (tp,ttp) -> + begin match tp.tp_default with + | None -> + () + | Some ct -> + let r = make_lazy ctx ttp.ttp_type (fun r -> + let t = load_complex_type ctx true ct in + begin match host with + | TPHType -> + () + | TPHConstructor + | TPHMethod + | TPHEnumConstructor + | TPHAnonField + | TPHLocal -> + display_error ctx.com "Default type parameters are only supported on types" (pos ct) + end; + t + ) "default" in + ttp.ttp_default <- Some (TLazy r) + end; + match tp.tp_constraints with | None -> - mk_type_param c host default None + () | Some th -> - let current_type_params = ctx.type_params in let constraints = lazy ( - let ctx = { ctx with type_params = get_params() @ current_type_params } in let rec loop th = match fst th with | CTIntersection tl -> List.map (load_complex_type ctx true) tl | CTParent ct -> loop ct @@ -771,7 +781,7 @@ let rec type_type_param ctx host path get_params p tp = (* check against direct recursion *) let rec loop t = match follow t with - | TInst (c2,_) when c == c2 -> + | TInst (c2,_) when ttp.ttp_class == c2 -> raise_typing_error "Recursive constraint parameter is not allowed" p | TInst ({ cl_kind = KTypeParameter ttp },_) -> List.iter loop (get_constraints ttp) @@ -782,18 +792,9 @@ let rec type_type_param ctx host path get_params p tp = constr ) in delay ctx PConnectField (fun () -> ignore (Lazy.force constraints)); - mk_type_param c host default (Some constraints) - in - c.cl_kind <- KTypeParameter ttp; - ttp - -and type_type_params ctx host path get_params p tpl = - let names = ref [] in - List.map (fun tp -> - if List.exists (fun name -> name = fst tp.tp_name) !names then display_error ctx.com ("Duplicate type parameter name: " ^ fst tp.tp_name) (pos tp.tp_name); - names := (fst tp.tp_name) :: !names; - type_type_param ctx host path get_params p tp - ) tpl + ttp.ttp_constraints <- Some constraints; + ) param_pairs; + params let load_core_class ctx c = let ctx2 = (match ctx.g.core_api with diff --git a/src/typing/typeloadFunction.ml b/src/typing/typeloadFunction.ml index 48f106c30cf..07c06f2e9d5 100644 --- a/src/typing/typeloadFunction.ml +++ b/src/typing/typeloadFunction.ml @@ -44,9 +44,7 @@ let save_field_state ctx = ) let type_function_params ctx fd host fname p = - let params = ref [] in - params := Typeload.type_type_params ctx host ([],fname) (fun() -> !params) p fd.f_params; - !params + Typeload.type_type_params ctx host ([],fname) p fd.f_params let type_function ctx (args : function_arguments) ret fmode e do_display p = ctx.in_function <- true; diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 69380e173d5..697cc2f581e 100644 --- a/src/typing/typeloadModule.ml +++ b/src/typing/typeloadModule.ml @@ -320,7 +320,7 @@ module ModuleLevel = struct List.iter (fun d -> match d with | (TClassDecl c, (EClass d, p)) -> - c.cl_params <- type_type_params ctx TPHType c.cl_path (fun() -> c.cl_params) p d.d_params; + c.cl_params <- type_type_params ctx TPHType c.cl_path p d.d_params; if Meta.has Meta.Generic c.cl_meta && c.cl_params <> [] then c.cl_kind <- KGeneric; if Meta.has Meta.GenericBuild c.cl_meta then begin if ctx.com.is_macro_context then raise_typing_error "@:genericBuild cannot be used in macros" c.cl_pos; @@ -328,11 +328,11 @@ module ModuleLevel = struct end; if c.cl_path = (["haxe";"macro"],"MacroType") then c.cl_kind <- KMacroType; | (TEnumDecl e, (EEnum d, p)) -> - e.e_params <- type_type_params ctx TPHType e.e_path (fun() -> e.e_params) p d.d_params; + e.e_params <- type_type_params ctx TPHType e.e_path p d.d_params; | (TTypeDecl t, (ETypedef d, p)) -> - t.t_params <- type_type_params ctx TPHType t.t_path (fun() -> t.t_params) p d.d_params; + t.t_params <- type_type_params ctx TPHType t.t_path p d.d_params; | (TAbstractDecl a, (EAbstract d, p)) -> - a.a_params <- type_type_params ctx TPHType a.a_path (fun() -> a.a_params) p d.d_params; + a.a_params <- type_type_params ctx TPHType a.a_path p d.d_params; | _ -> die "" __LOC__ ) decls @@ -341,9 +341,7 @@ end module TypeLevel = struct let load_enum_field ctx e et is_flat index c = let p = c.ec_pos in - let params = ref [] in - params := type_type_params ctx TPHEnumConstructor ([],fst c.ec_name) (fun() -> !params) c.ec_pos c.ec_params; - let params = !params in + let params = type_type_params ctx TPHEnumConstructor ([],fst c.ec_name) c.ec_pos c.ec_params in let ctx = { ctx with type_params = params @ ctx.type_params } in let rt = (match c.ec_type with | None -> et From 2b0e8cead3374f0cab8d52ec0ec9b05e269a6750 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Fri, 2 Feb 2024 17:29:25 +0100 Subject: [PATCH 07/20] Split up typer context (#11534) * add ctx.c * create class context earlier to avoid some heritage awkwardness * add ctx.e * start on ctx.f * curfield * vthis * untyped * in_loop * bypass_accessor & meta * with_type_stack & call_argument_stack * in_call_args & in_overload_call_args * in_display * is_display_file * in_call_args needs to be on ctx.f also do some cleanup * why did I change that * macro_depth * delayed_display * allow_inline & allow_tranform * rename to ctx_c to make difference visible * more renaming, less ctx because that will totally fix something * I'm committed now * make some context cloning explicit * clone for enum fields too and random cleanup * Revert "allow_inline & allow_tranform" This reverts commit f35e83c526d583c3ef2f25ed76625308c2a82684. --------- Co-authored-by: Rudy Ges --- src/context/abstractCast.ml | 8 +- src/context/display/displayEmitter.ml | 2 +- src/context/display/displayFields.ml | 10 +- src/context/display/displayPath.ml | 1 - src/context/display/displayTexpr.ml | 4 +- src/context/display/displayToplevel.ml | 26 +-- src/context/display/importHandling.ml | 2 +- src/context/typecore.ml | 222 +++++++++++++++----- src/filters/exceptions.ml | 4 +- src/filters/filters.ml | 6 +- src/filters/filtersCommon.ml | 6 +- src/filters/localStatic.ml | 6 +- src/filters/tre.ml | 10 +- src/optimization/inline.ml | 4 +- src/optimization/inlineConstructors.ml | 4 +- src/optimization/optimizer.ml | 2 +- src/typing/callUnification.ml | 44 ++-- src/typing/calls.ml | 20 +- src/typing/fields.ml | 46 ++-- src/typing/forLoop.ml | 8 +- src/typing/functionArguments.ml | 6 +- src/typing/generic.ml | 4 +- src/typing/instanceBuilder.ml | 26 +-- src/typing/macroContext.ml | 36 ++-- src/typing/matcher.ml | 2 +- src/typing/matcher/case.ml | 10 +- src/typing/matcher/exprToPattern.ml | 22 +- src/typing/operators.ml | 2 +- src/typing/typeload.ml | 21 +- src/typing/typeloadCheck.ml | 15 +- src/typing/typeloadFields.ml | 103 ++++----- src/typing/typeloadFunction.ml | 64 +++--- src/typing/typeloadModule.ml | 278 +++++++++++-------------- src/typing/typer.ml | 176 ++++++++-------- src/typing/typerBase.ml | 30 +-- src/typing/typerDisplay.ml | 32 +-- src/typing/typerEntry.ml | 34 +-- 37 files changed, 659 insertions(+), 637 deletions(-) diff --git a/src/context/abstractCast.ml b/src/context/abstractCast.ml index b26f26d980d..162af836fe2 100644 --- a/src/context/abstractCast.ml +++ b/src/context/abstractCast.ml @@ -12,12 +12,12 @@ let rec make_static_call ctx c cf a pl args t p = match args with | [e] -> let e,f = push_this ctx e in - ctx.with_type_stack <- (WithType.with_type t) :: ctx.with_type_stack; + ctx.e.with_type_stack <- (WithType.with_type t) :: ctx.e.with_type_stack; let e = match ctx.g.do_macro ctx MExpr c.cl_path cf.cf_name [e] p with | MSuccess e -> type_expr ctx e (WithType.with_type t) | _ -> type_expr ctx (EConst (Ident "null"),p) WithType.value in - ctx.with_type_stack <- List.tl ctx.with_type_stack; + ctx.e.with_type_stack <- List.tl ctx.e.with_type_stack; let e = try cast_or_unify_raise ctx t e p with Error { err_message = Unify _ } -> raise Not_found in f(); e @@ -40,7 +40,7 @@ and do_check_cast ctx uctx tleft eright p = raise_error_msg (Unify l) eright.epos) | _ -> () end; - if cf == ctx.curfield || rec_stack_memq cf cast_stack then raise_typing_error "Recursive implicit cast" p; + if cf == ctx.f.curfield || rec_stack_memq cf cast_stack then raise_typing_error "Recursive implicit cast" p; rec_stack_loop cast_stack cf f () in let make (a,tl,(tcf,cf)) = @@ -118,7 +118,7 @@ and cast_or_unify ctx tleft eright p = eright let prepare_array_access_field ctx a pl cf p = - let monos = List.map (fun _ -> spawn_monomorph ctx p) cf.cf_params in + let monos = List.map (fun _ -> spawn_monomorph ctx.e p) cf.cf_params in let map t = apply_params a.a_params pl (apply_params cf.cf_params monos t) in let check_constraints () = List.iter2 (fun m ttp -> match get_constraints ttp with diff --git a/src/context/display/displayEmitter.ml b/src/context/display/displayEmitter.ml index 9f50cef7905..58b50c7d25f 100644 --- a/src/context/display/displayEmitter.ml +++ b/src/context/display/displayEmitter.ml @@ -71,7 +71,7 @@ let check_display_type ctx t ptp = ctx.g.type_hints <- (ctx.m.curmod.m_extra.m_display,ptp.pos_full,t) :: ctx.g.type_hints; in let maybe_display_type () = - if ctx.is_display_file && display_position#enclosed_in ptp.pos_full then + if ctx.m.is_display_file && display_position#enclosed_in ptp.pos_full then display_type ctx t ptp.pos_path in add_type_hint(); diff --git a/src/context/display/displayFields.ml b/src/context/display/displayFields.ml index 8540e92fb99..234cf6d460f 100644 --- a/src/context/display/displayFields.ml +++ b/src/context/display/displayFields.ml @@ -49,7 +49,7 @@ let collect_static_extensions ctx items e p = let rec dup t = Type.map dup t in let handle_field c f acc = let f = { f with cf_type = opt_type f.cf_type } in - let monos = List.map (fun _ -> spawn_monomorph ctx p) f.cf_params in + let monos = List.map (fun _ -> spawn_monomorph ctx.e p) f.cf_params in let map = apply_params f.cf_params monos in match follow (map f.cf_type) with | TFun((_,_,TType({t_path=["haxe";"macro"], "ExprOf"}, [t])) :: args, ret) @@ -112,7 +112,7 @@ let collect ctx e_ast e dk with_type p = let opt_args args ret = TFun(List.map(fun (n,o,t) -> n,true,t) args,ret) in let should_access c cf stat = if Meta.has Meta.NoCompletion cf.cf_meta then false - else if c != ctx.curclass && not (has_class_field_flag cf CfPublic) && String.length cf.cf_name > 4 then begin match String.sub cf.cf_name 0 4 with + else if c != ctx.c.curclass && not (has_class_field_flag cf CfPublic) && String.length cf.cf_name > 4 then begin match String.sub cf.cf_name 0 4 with | "get_" | "set_" -> false | _ -> can_access ctx c cf stat end else @@ -402,9 +402,9 @@ let handle_missing_field_raise ctx tthis i mode with_type pfield = display.module_diagnostics <- MissingFields diag :: display.module_diagnostics let handle_missing_ident ctx i mode with_type p = - match ctx.curfun with + match ctx.e.curfun with | FunStatic -> - let e_self = Texpr.Builder.make_static_this ctx.curclass p in + let e_self = Texpr.Builder.make_static_this ctx.c.curclass p in begin try handle_missing_field_raise ctx e_self.etype i mode with_type p with Exit -> @@ -412,7 +412,7 @@ let handle_missing_ident ctx i mode with_type p = end | _ -> begin try - handle_missing_field_raise ctx ctx.tthis i mode with_type p + handle_missing_field_raise ctx ctx.c.tthis i mode with_type p with Exit -> () end diff --git a/src/context/display/displayPath.ml b/src/context/display/displayPath.ml index a10ab00bf7d..87940cfa93a 100644 --- a/src/context/display/displayPath.ml +++ b/src/context/display/displayPath.ml @@ -165,7 +165,6 @@ let resolve_position_by_path ctx path p = let p = (t_infos mt).mt_pos in raise_positions [p] - let handle_path_display ctx path p = let class_field c name = ignore(c.cl_build()); diff --git a/src/context/display/displayTexpr.ml b/src/context/display/displayTexpr.ml index 105691004e1..777ba93ef24 100644 --- a/src/context/display/displayTexpr.ml +++ b/src/context/display/displayTexpr.ml @@ -140,8 +140,8 @@ let check_display_module ctx decls m = | (EImport _ | EUsing _),_ -> true | _ -> false ) decls in - let imports = TypeloadModule.ModuleLevel.handle_import_hx ctx m imports null_pos in - let ctx = TypeloadModule.type_types_into_module ctx m imports null_pos in + let imports = TypeloadModule.ModuleLevel.handle_import_hx ctx.com ctx.g m imports null_pos in + let ctx = TypeloadModule.type_types_into_module ctx.com ctx.g m imports null_pos in List.iter (fun md -> let infos = t_infos md in if display_position#enclosed_in infos.mt_name_pos then diff --git a/src/context/display/displayToplevel.ml b/src/context/display/displayToplevel.ml index 32d9afeda3d..facb253d13b 100644 --- a/src/context/display/displayToplevel.ml +++ b/src/context/display/displayToplevel.ml @@ -227,7 +227,7 @@ let is_pack_visible pack = let collect ctx tk with_type sort = let t = Timer.timer ["display";"toplevel collect"] in let cctx = CollectionContext.create ctx in - let curpack = fst ctx.curclass.cl_path in + let curpack = fst ctx.c.curclass.cl_path in (* Note: This checks for the explicit `ServerConfig.legacy_completion` setting instead of using `is_legacy_completion com` because the latter is always false for the old protocol, yet we have tests which assume advanced completion even in the old protocol. This means that we can only @@ -302,7 +302,7 @@ let collect ctx tk with_type sort = PMap.iter (fun _ v -> if not (is_gen_local v) then add (make_ci_local v (tpair ~values:(get_value_meta v.v_meta) v.v_type)) (Some v.v_name) - ) ctx.locals; + ) ctx.f.locals; t(); let add_field scope origin cf = @@ -331,22 +331,22 @@ let collect ctx tk with_type sort = let t = Timer.timer ["display";"toplevel collect";"fields"] in (* member fields *) - if ctx.curfun <> FunStatic then begin - let all_fields = Type.TClass.get_all_fields ctx.curclass (extract_param_types ctx.curclass.cl_params) in + if ctx.e.curfun <> FunStatic then begin + let all_fields = Type.TClass.get_all_fields ctx.c.curclass (extract_param_types ctx.c.curclass.cl_params) in PMap.iter (fun _ (c,cf) -> - let origin = if c == ctx.curclass then Self (TClassDecl c) else Parent (TClassDecl c) in + let origin = if c == ctx.c.curclass then Self (TClassDecl c) else Parent (TClassDecl c) in maybe_add_field CFSMember origin cf ) all_fields; (* TODO: local using? *) end; (* statics *) - begin match ctx.curclass.cl_kind with + begin match ctx.c.curclass.cl_kind with | KAbstractImpl ({a_impl = Some c} as a) -> let origin = Self (TAbstractDecl a) in List.iter (fun cf -> if has_class_field_flag cf CfImpl then begin - if ctx.curfun = FunStatic then () + if ctx.e.curfun = FunStatic then () else begin let cf = prepare_using_field cf in maybe_add_field CFSMember origin cf @@ -355,7 +355,7 @@ let collect ctx tk with_type sort = maybe_add_field CFSStatic origin cf ) c.cl_ordered_statics | _ -> - List.iter (maybe_add_field CFSStatic (Self (TClassDecl ctx.curclass))) ctx.curclass.cl_ordered_statics + List.iter (maybe_add_field CFSStatic (Self (TClassDecl ctx.c.curclass))) ctx.c.curclass.cl_ordered_statics end; t(); @@ -363,7 +363,7 @@ let collect ctx tk with_type sort = (* enum constructors *) let rec enum_ctors t = match t with - | TAbstractDecl ({a_impl = Some c} as a) when a.a_enum && not (path_exists cctx a.a_path) && ctx.curclass != c -> + | TAbstractDecl ({a_impl = Some c} as a) when a.a_enum && not (path_exists cctx a.a_path) && ctx.c.curclass != c -> add_path cctx a.a_path; List.iter (fun cf -> let ccf = CompletionClassField.make cf CFSMember (Self (decl_of_class c)) true in @@ -433,16 +433,16 @@ let collect ctx tk with_type sort = add (make_ci_literal "null" (tpair t_dynamic)) (Some "null"); add (make_ci_literal "true" (tpair ctx.com.basic.tbool)) (Some "true"); add (make_ci_literal "false" (tpair ctx.com.basic.tbool)) (Some "false"); - begin match ctx.curfun with + begin match ctx.e.curfun with | FunMember | FunConstructor | FunMemberClassLocal -> - let t = TInst(ctx.curclass,extract_param_types ctx.curclass.cl_params) in + let t = TInst(ctx.c.curclass,extract_param_types ctx.c.curclass.cl_params) in add (make_ci_literal "this" (tpair t)) (Some "this"); - begin match ctx.curclass.cl_super with + begin match ctx.c.curclass.cl_super with | Some(c,tl) -> add (make_ci_literal "super" (tpair (TInst(c,tl)))) (Some "super") | None -> () end | FunMemberAbstract -> - let t = TInst(ctx.curclass,extract_param_types ctx.curclass.cl_params) in + let t = TInst(ctx.c.curclass,extract_param_types ctx.c.curclass.cl_params) in add (make_ci_literal "abstract" (tpair t)) (Some "abstract"); | _ -> () diff --git a/src/context/display/importHandling.ml b/src/context/display/importHandling.ml index cb7e9f42367..69a9e9f16c3 100644 --- a/src/context/display/importHandling.ml +++ b/src/context/display/importHandling.ml @@ -113,7 +113,7 @@ let init_import ctx path mode p = let check_alias mt name pname = if not (name.[0] >= 'A' && name.[0] <= 'Z') then raise_typing_error "Type aliases must start with an uppercase letter" pname; - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in pname then + if ctx.m.is_display_file && DisplayPosition.display_position#enclosed_in pname then DisplayEmitter.display_alias ctx name (type_of_module_type mt) pname; in let add_static_init t name s = diff --git a/src/context/typecore.ml b/src/context/typecore.ml index a949bd405dd..180b14daaf7 100644 --- a/src/context/typecore.ml +++ b/src/context/typecore.ml @@ -73,6 +73,13 @@ type typer_module = { mutable enum_with_type : module_type option; mutable module_using : (tclass * pos) list; mutable import_statements : import list; + mutable is_display_file : bool; +} + +type typer_class = { + mutable curclass : tclass; (* TODO: should not be mutable *) + mutable tthis : t; + mutable get_build_infos : unit -> (module_type * t list * class_field list) option; } type build_kind = @@ -118,6 +125,7 @@ type typer_globals = { mutable return_partial_type : bool; mutable build_count : int; mutable t_dynamic_def : Type.t; + mutable delayed_display : DisplayTypes.display_exception_kind option; (* api *) do_macro : typer -> macro_mode -> path -> string -> expr list -> pos -> macro_result; do_load_macro : typer -> bool -> path -> string -> pos -> ((string * bool * t) list * t * tclass * Type.tclass_field); @@ -128,43 +136,45 @@ type typer_globals = { do_load_core_class : typer -> tclass -> tclass; } +(* typer_expr holds information that is specific to a (function) expresssion, whereas typer_field + is shared by local TFunctions. *) +and typer_expr = { + mutable ret : t; + mutable curfun : current_fun; + mutable opened : anon_status ref list; + mutable monomorphs : monomorphs; + mutable in_function : bool; + mutable in_loop : bool; + mutable bypass_accessor : int; + mutable with_type_stack : WithType.t list; + mutable call_argument_stack : expr list list; + mutable macro_depth : int; +} + +and typer_field = { + mutable curfield : tclass_field; + mutable locals : (string, tvar) PMap.t; + mutable vthis : tvar option; + mutable untyped : bool; + mutable meta : metadata; + mutable in_display : bool; + mutable in_call_args : bool; + mutable in_overload_call_args : bool; +} + and typer = { (* shared *) com : context; t : basic_types; g : typer_globals; - mutable bypass_accessor : int; - mutable meta : metadata; - mutable with_type_stack : WithType.t list; - mutable call_argument_stack : expr list list; - (* variable *) - mutable pass : typer_pass; - (* per-module *) mutable m : typer_module; - mutable is_display_file : bool; - (* per-class *) - mutable curclass : tclass; - mutable tthis : t; + c : typer_class; + f : typer_field; + mutable e : typer_expr; + mutable pass : typer_pass; mutable type_params : type_params; - mutable get_build_infos : unit -> (module_type * t list * class_field list) option; - (* per-function *) mutable allow_inline : bool; mutable allow_transform : bool; - mutable curfield : tclass_field; - mutable untyped : bool; - mutable in_function : bool; - mutable in_loop : bool; - mutable in_display : bool; - mutable macro_depth : int; - mutable curfun : current_fun; - mutable ret : t; - mutable locals : (string, tvar) PMap.t; - mutable opened : anon_status ref list; - mutable vthis : tvar option; - mutable in_call_args : bool; - mutable in_overload_call_args : bool; - mutable delayed_display : DisplayTypes.display_exception_kind option; - mutable monomorphs : monomorphs; (* events *) memory_marker : float array; } @@ -173,6 +183,106 @@ and monomorphs = { mutable perfunction : (tmono * pos) list; } +module TyperManager = struct + let create com g m c f e pass params = { + com = com; + g = g; + t = com.basic; + m = m; + c = c; + f = f; + e = e; + pass = pass; + allow_inline = true; + allow_transform = true; + type_params = params; + memory_marker = memory_marker; + } + + let create_ctx_c c = + { + curclass = c; + tthis = (match c.cl_kind with + | KAbstractImpl a -> + (match a.a_this with + | TMono r when r.tm_type = None -> TAbstract (a,extract_param_types c.cl_params) + | t -> t) + | _ -> + TInst (c,extract_param_types c.cl_params) + ); + get_build_infos = (fun () -> None); + } + + let create_ctx_f cf = + { + locals = PMap.empty; + curfield = cf; + vthis = None; + untyped = false; + meta = []; + in_display = false; + in_overload_call_args = false; + in_call_args = false; + } + + let create_ctx_e () = + { + ret = t_dynamic; + curfun = FunStatic; + opened = []; + in_function = false; + monomorphs = { + perfunction = []; + }; + in_loop = false; + bypass_accessor = 0; + with_type_stack = []; + call_argument_stack = []; + macro_depth = 0; + } + + let create_for_module com g m = + let c = create_ctx_c null_class in + let f = create_ctx_f null_field in + let e = create_ctx_e () in + create com g m c f e PBuildModule [] + + let clone_for_class ctx c = + let c = create_ctx_c c in + let f = create_ctx_f null_field in + let e = create_ctx_e () in + let params = match c.curclass.cl_kind with KAbstractImpl a -> a.a_params | _ -> c.curclass.cl_params in + create ctx.com ctx.g ctx.m c f e PBuildClass params + + let clone_for_enum ctx en = + let c = create_ctx_c null_class in + let f = create_ctx_f null_field in + let e = create_ctx_e () in + create ctx.com ctx.g ctx.m c f e PBuildModule en.e_params + + let clone_for_typedef ctx td = + let c = create_ctx_c null_class in + let f = create_ctx_f null_field in + let e = create_ctx_e () in + create ctx.com ctx.g ctx.m c f e PBuildModule td.t_params + + let clone_for_abstract ctx a = + let c = create_ctx_c null_class in + let f = create_ctx_f null_field in + let e = create_ctx_e () in + create ctx.com ctx.g ctx.m c f e PBuildModule a.a_params + + let clone_for_field ctx cf params = + let f = create_ctx_f cf in + let e = create_ctx_e () in + create ctx.com ctx.g ctx.m ctx.c f e PBuildClass params + + let clone_for_enum_field ctx params = + let f = create_ctx_f null_field in + let e = create_ctx_e () in + create ctx.com ctx.g ctx.m ctx.c f e PBuildClass params +end + type field_host = | FHStatic of tclass | FHInstance of tclass * tparams @@ -252,7 +362,7 @@ let pass_name = function | PFinal -> "final" let warning ?(depth=0) ctx w msg p = - let options = (Warning.from_meta ctx.curclass.cl_meta) @ (Warning.from_meta ctx.curfield.cf_meta) in + let options = (Warning.from_meta ctx.c.curclass.cl_meta) @ (Warning.from_meta ctx.f.curfield.cf_meta) in match Warning.get_mode w options with | WMEnable -> module_warning ctx.com ctx.m.curmod w options msg p @@ -279,7 +389,7 @@ let make_static_field_access c cf t p = mk (TField (ethis,(FStatic (c,cf)))) t p let make_static_call ctx c cf map args t p = - let monos = List.map (fun _ -> spawn_monomorph ctx p) cf.cf_params in + let monos = List.map (fun _ -> spawn_monomorph ctx.e p) cf.cf_params in let map t = map (apply_params cf.cf_params monos t) in let ef = make_static_field_access c cf (map cf.cf_type) p in make_call ctx ef args (map t) p @@ -288,17 +398,17 @@ let raise_with_type_error ?(depth = 0) msg p = raise (WithTypeError (make_error ~depth (Custom msg) p)) let raise_or_display ctx l p = - if ctx.untyped then () - else if ctx.in_call_args then raise (WithTypeError (make_error (Unify l) p)) + if ctx.f.untyped then () + else if ctx.f.in_call_args then raise (WithTypeError (make_error (Unify l) p)) else display_error_ext ctx.com (make_error (Unify l) p) let raise_or_display_error ctx err = - if ctx.untyped then () - else if ctx.in_call_args then raise (WithTypeError err) + if ctx.f.untyped then () + else if ctx.f.in_call_args then raise (WithTypeError err) else display_error_ext ctx.com err let raise_or_display_message ctx msg p = - if ctx.in_call_args then raise_with_type_error msg p + if ctx.f.in_call_args then raise_with_type_error msg p else display_error ctx.com msg p let unify ctx t1 t2 p = @@ -319,8 +429,8 @@ let unify_raise_custom uctx t1 t2 p = let unify_raise = unify_raise_custom default_unification_context let save_locals ctx = - let locals = ctx.locals in - (fun() -> ctx.locals <- locals) + let locals = ctx.f.locals in + (fun() -> ctx.f.locals <- locals) let add_local ctx k n t p = let v = alloc_var k n t p in @@ -328,7 +438,7 @@ let add_local ctx k n t p = match k with | VUser _ -> begin try - let v' = PMap.find n ctx.locals in + let v' = PMap.find n ctx.f.locals in (* ignore std lib *) if not (List.exists (fun path -> ExtLib.String.starts_with p.pfile (path#path)) ctx.com.class_paths#get_std_paths) then begin warning ctx WVarShadow "This variable shadows a previously declared variable" p; @@ -340,7 +450,7 @@ let add_local ctx k n t p = | _ -> () end; - ctx.locals <- PMap.add n v ctx.locals; + ctx.f.locals <- PMap.add n v ctx.f.locals; v let display_identifier_error ctx ?prepend_msg msg p = @@ -523,7 +633,7 @@ let clone_type_parameter map path ttp = let can_access ctx c cf stat = if (has_class_field_flag cf CfPublic) then true - else if c == ctx.curclass then + else if c == ctx.c.curclass then true else match ctx.m.curmod.m_statics with | Some c' when c == c' -> @@ -576,24 +686,24 @@ let can_access ctx c cf stat = in loop c.cl_meta || loop f.cf_meta in - let module_path = ctx.curclass.cl_module.m_path in + let module_path = ctx.c.curclass.cl_module.m_path in let cur_paths = ref [fst module_path @ [snd module_path], false] in let rec loop c is_current_path = - cur_paths := (make_path c ctx.curfield, is_current_path) :: !cur_paths; + cur_paths := (make_path c ctx.f.curfield, is_current_path) :: !cur_paths; begin match c.cl_super with | Some (csup,_) -> loop csup false | None -> () end; List.iter (fun (c,_) -> loop c false) c.cl_implements; in - loop ctx.curclass true; + loop ctx.c.curclass true; let is_constr = cf.cf_name = "new" in let rec loop c = try - has Meta.Access ctx.curclass ctx.curfield ((make_path c cf), true) + has Meta.Access ctx.c.curclass ctx.f.curfield ((make_path c cf), true) || ( (* if our common ancestor declare/override the field, then we can access it *) - let allowed f = extends ctx.curclass c || (List.exists (has Meta.Allow c f) !cur_paths) in + let allowed f = extends ctx.c.curclass c || (List.exists (has Meta.Allow c f) !cur_paths) in if is_constr then ( match c.cl_constructor with | Some cf -> @@ -616,10 +726,10 @@ let can_access ctx c cf stat = | KTypeParameter ttp -> List.exists (fun t -> match follow t with TInst(c,_) -> loop c | _ -> false) (get_constraints ttp) | _ -> false) - || (Meta.has Meta.PrivateAccess ctx.meta) + || (Meta.has Meta.PrivateAccess ctx.f.meta) let check_field_access ctx c f stat p = - if not ctx.untyped && not (can_access ctx c f stat) then + if not ctx.f.untyped && not (can_access ctx c f stat) then display_error ctx.com ("Cannot access private field " ^ f.cf_name) p (** removes the first argument of the class field's function type and all its overloads *) @@ -703,11 +813,11 @@ let mk_infos ctx p params = (EObjectDecl ( (("fileName",null_pos,NoQuotes) , (EConst (String(file,SDoubleQuotes)) , p)) :: (("lineNumber",null_pos,NoQuotes) , (EConst (Int (string_of_int (Lexer.get_error_line p), None)),p)) :: - (("className",null_pos,NoQuotes) , (EConst (String (s_type_path ctx.curclass.cl_path,SDoubleQuotes)),p)) :: - if ctx.curfield.cf_name = "" then + (("className",null_pos,NoQuotes) , (EConst (String (s_type_path ctx.c.curclass.cl_path,SDoubleQuotes)),p)) :: + if ctx.f.curfield.cf_name = "" then params else - (("methodName",null_pos,NoQuotes), (EConst (String (ctx.curfield.cf_name,SDoubleQuotes)),p)) :: params + (("methodName",null_pos,NoQuotes), (EConst (String (ctx.f.curfield.cf_name,SDoubleQuotes)),p)) :: params ) ,p) let rec is_pos_infos = function @@ -754,8 +864,8 @@ let push_this ctx e = match e.eexpr with let create_deprecation_context ctx = { (DeprecationCheck.create_context ctx.com) with - class_meta = ctx.curclass.cl_meta; - field_meta = ctx.curfield.cf_meta; + class_meta = ctx.c.curclass.cl_meta; + field_meta = ctx.f.curfield.cf_meta; curmod = ctx.m.curmod; } @@ -801,14 +911,14 @@ let debug com (path : string list) str = end let init_class_done ctx = - let path = fst ctx.curclass.cl_path @ [snd ctx.curclass.cl_path] in - debug ctx.com path ("init_class_done " ^ s_type_path ctx.curclass.cl_path); + let path = fst ctx.c.curclass.cl_path @ [snd ctx.c.curclass.cl_path] in + debug ctx.com path ("init_class_done " ^ s_type_path ctx.c.curclass.cl_path); init_class_done ctx let ctx_pos ctx = let inf = fst ctx.m.curmod.m_path @ [snd ctx.m.curmod.m_path]in - let inf = (match snd ctx.curclass.cl_path with "" -> inf | n when n = snd ctx.m.curmod.m_path -> inf | n -> inf @ [n]) in - let inf = (match ctx.curfield.cf_name with "" -> inf | n -> inf @ [n]) in + let inf = (match snd ctx.c.curclass.cl_path with "" -> inf | n when n = snd ctx.m.curmod.m_path -> inf | n -> inf @ [n]) in + let inf = (match ctx.f.curfield.cf_name with "" -> inf | n -> inf @ [n]) in inf let pass_infos ctx p = diff --git a/src/filters/exceptions.ml b/src/filters/exceptions.ml index d913b4a993a..1429260aa60 100644 --- a/src/filters/exceptions.ml +++ b/src/filters/exceptions.ml @@ -39,7 +39,7 @@ let haxe_exception_static_call ctx method_name args p = | TFun(_,t) -> t | _ -> raise_typing_error ("haxe.Exception." ^ method_name ^ " is not a function and cannot be called") p in - add_dependency ctx.typer.curclass.cl_module ctx.haxe_exception_class.cl_module; + add_dependency ctx.typer.c.curclass.cl_module ctx.haxe_exception_class.cl_module; make_static_call ctx.typer ctx.haxe_exception_class method_field (fun t -> t) args return_type p (** @@ -605,7 +605,7 @@ let insert_save_stacks tctx = in let catch_local = mk (TLocal catch_var) catch_var.v_type catch_var.v_pos in begin - add_dependency tctx.curclass.cl_module native_stack_trace_cls.cl_module; + add_dependency tctx.c.curclass.cl_module native_stack_trace_cls.cl_module; make_static_call tctx native_stack_trace_cls method_field (fun t -> t) [catch_local] return_type catch_var.v_pos end else diff --git a/src/filters/filters.ml b/src/filters/filters.ml index c3314b9243a..e2d12215832 100644 --- a/src/filters/filters.ml +++ b/src/filters/filters.ml @@ -545,7 +545,7 @@ let destruction tctx detail_times main locals = check_private_path com; Naming.apply_native_paths; add_rtti com; - (match com.platform with | Java | Cs -> (fun _ -> ()) | _ -> (fun mt -> AddFieldInits.add_field_inits tctx.curclass.cl_path locals com mt)); + (match com.platform with | Java | Cs -> (fun _ -> ()) | _ -> (fun mt -> AddFieldInits.add_field_inits tctx.c.curclass.cl_path locals com mt)); (match com.platform with Hl -> (fun _ -> ()) | _ -> add_meta_field com); check_void_field; (match com.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ -> ())); @@ -560,7 +560,7 @@ let destruction tctx detail_times main locals = List.iter (fun t -> begin match t with | TClassDecl c -> - tctx.curclass <- c + tctx.c.curclass <- c | _ -> () end; @@ -811,7 +811,7 @@ let run tctx main before_destruction = "RenameVars",(match com.platform with | Eval -> (fun e -> e) | Java when defined com Jvm -> (fun e -> e) - | _ -> (fun e -> RenameVars.run tctx.curclass.cl_path locals e)); + | _ -> (fun e -> RenameVars.run tctx.c.curclass.cl_path locals e)); "mark_switch_break_loops",mark_switch_break_loops; ] in List.iter (run_expression_filters tctx detail_times filters) new_types; diff --git a/src/filters/filtersCommon.ml b/src/filters/filtersCommon.ml index 43494cf1374..7468f4425fc 100644 --- a/src/filters/filtersCommon.ml +++ b/src/filters/filtersCommon.ml @@ -63,11 +63,11 @@ let run_expression_filters ?(ignore_processed_status=false) ctx detail_times fil match t with | TClassDecl c when is_removable_class c -> () | TClassDecl c -> - ctx.curclass <- c; - ctx.m <- TypeloadModule.make_curmod ctx c.cl_module; + ctx.c.curclass <- c; + ctx.m <- TypeloadModule.make_curmod ctx.com ctx.g c.cl_module; let rec process_field f = if ignore_processed_status || not (has_class_field_flag f CfPostProcessed) then begin - ctx.curfield <- f; + ctx.f.curfield <- f; (match f.cf_expr with | Some e when not (is_removable_field com f) -> let identifier = Printf.sprintf "%s.%s" (s_type_path c.cl_path) f.cf_name in diff --git a/src/filters/localStatic.ml b/src/filters/localStatic.ml index b6d9c1d7d5f..e2560ae6c5b 100644 --- a/src/filters/localStatic.ml +++ b/src/filters/localStatic.ml @@ -10,8 +10,8 @@ type lscontext = { } let promote_local_static lsctx run v eo = - let name = Printf.sprintf "%s_%s" lsctx.ctx.curfield.cf_name v.v_name in - let c = lsctx.ctx.curclass in + let name = Printf.sprintf "%s_%s" lsctx.ctx.f.curfield.cf_name v.v_name in + let c = lsctx.ctx.c.curclass in begin try let cf = PMap.find name c.cl_statics in display_error lsctx.ctx.com (Printf.sprintf "The expanded name of this local (%s) conflicts with another static field" name) v.v_pos; @@ -56,7 +56,7 @@ let run ctx e = lut = Hashtbl.create 0; added_fields = []; } in - let c = ctx.curclass in + let c = ctx.c.curclass in let rec run e = match e.eexpr with | TBlock el -> let el = ExtList.List.filter_map (fun e -> match e.eexpr with diff --git a/src/filters/tre.ml b/src/filters/tre.ml index dce3b8f4392..1bbf18bfffe 100644 --- a/src/filters/tre.ml +++ b/src/filters/tre.ml @@ -206,19 +206,19 @@ let run ctx = match e.eexpr with | TFunction fn -> let is_tre_eligible = - match ctx.curfield.cf_kind with + match ctx.f.curfield.cf_kind with | Method MethDynamic -> false | Method MethInline -> true | Method MethNormal -> - PMap.mem ctx.curfield.cf_name ctx.curclass.cl_statics + PMap.mem ctx.f.curfield.cf_name ctx.c.curclass.cl_statics | _ -> - has_class_field_flag ctx.curfield CfFinal + has_class_field_flag ctx.f.curfield CfFinal in let is_recursive_call callee args = - is_tre_eligible && is_recursive_method_call ctx.curclass ctx.curfield callee args + is_tre_eligible && is_recursive_method_call ctx.c.curclass ctx.f.curfield callee args in if has_tail_recursion is_recursive_call false true fn.tf_expr then - (* print_endline ("TRE: " ^ ctx.curfield.cf_pos.pfile ^ ": " ^ ctx.curfield.cf_name); *) + (* print_endline ("TRE: " ^ ctx.f.curfield.cf_pos.pfile ^ ": " ^ ctx.f.curfield.cf_name); *) let fn = transform_function ctx is_recursive_call fn in { e with eexpr = TFunction fn } else diff --git a/src/optimization/inline.ml b/src/optimization/inline.ml index a9709f37040..6b77604dd7d 100644 --- a/src/optimization/inline.ml +++ b/src/optimization/inline.ml @@ -546,7 +546,7 @@ class inline_state ctx ethis params cf f p = object(self) in let e = (if PMap.is_empty subst then e else inline_params false false e) in let init = match vars with [] -> None | l -> Some l in - let md = ctx.curclass.cl_module.m_extra.m_display in + let md = ctx.c.curclass.cl_module.m_extra.m_display in md.m_inline_calls <- (cf.cf_name_pos,{p with pmax = p.pmin + String.length cf.cf_name}) :: md.m_inline_calls; let wrap e = (* we can't mute the type of the expression because it is not correct to do so *) @@ -866,7 +866,7 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f in let tl = arg_types params f.tf_args in let e = state#finalize e tl tret has_params map_type p in - if Meta.has (Meta.Custom ":inlineDebug") ctx.meta then begin + if Meta.has (Meta.Custom ":inlineDebug") ctx.f.meta then begin let se t = s_expr_ast true t (s_type (print_context())) in print_endline (Printf.sprintf "Inline %s:\n\tArgs: %s\n\tExpr: %s\n\tResult: %s" cf.cf_name diff --git a/src/optimization/inlineConstructors.ml b/src/optimization/inlineConstructors.ml index 461ae859b9e..1fb7f8c71e5 100644 --- a/src/optimization/inlineConstructors.ml +++ b/src/optimization/inlineConstructors.ml @@ -111,7 +111,7 @@ and inline_object_field = inline_expression_handled Defines what will happen to the expression being analized by analyze_aliases *) -and inline_expression_handled = +and inline_expression_handled = | IEHCaptured (* The expression will be assigned to a variable *) | IEHIgnored (* The result of the expression will not be used *) | IEHNotHandled (* Cases that are not handled (usually leads to cancelling inlining *) @@ -728,7 +728,7 @@ let inline_constructors ctx original_e = original_e end else begin let el,_ = final_map e in - let cf = ctx.curfield in + let cf = ctx.f.curfield in if !included_untyped && not (Meta.has Meta.HasUntyped cf.cf_meta) then cf.cf_meta <- (Meta.HasUntyped,[],e.epos) :: cf.cf_meta; let e = make_expr_for_rev_list el e.etype e.epos in let rec get_pretty_name iv = match iv.iv_kind with diff --git a/src/optimization/optimizer.ml b/src/optimization/optimizer.ml index 73f1dd6ea78..d51c8e246ca 100644 --- a/src/optimization/optimizer.ml +++ b/src/optimization/optimizer.ml @@ -384,7 +384,7 @@ let reduce_expression ctx e = if ctx.com.foptimize then (* We go through rec_stack_default here so that the current field is on inline_stack. This prevents self-recursive inlining (#7569). *) - rec_stack_default inline_stack ctx.curfield (fun cf' -> cf' == ctx.curfield) (fun () -> reduce_loop ctx e) e + rec_stack_default inline_stack ctx.f.curfield (fun cf' -> cf' == ctx.f.curfield) (fun () -> reduce_loop ctx e) e else e diff --git a/src/typing/callUnification.ml b/src/typing/callUnification.ml index 9da0e9c3198..623c0fe4ed6 100644 --- a/src/typing/callUnification.ml +++ b/src/typing/callUnification.ml @@ -144,7 +144,7 @@ let unify_call_args ctx el args r callp inline force_inline in_overload = | (e,p) :: el, [] -> begin match List.rev !skipped with | [] -> - if ctx.is_display_file && not (Diagnostics.error_in_diagnostics_run ctx.com p) then begin + if ctx.m.is_display_file && not (Diagnostics.error_in_diagnostics_run ctx.com p) then begin ignore(type_expr ctx (e,p) WithType.value); ignore(loop el []) end; @@ -168,13 +168,13 @@ let unify_call_args ctx el args r callp inline force_inline in_overload = end in let restore = - let in_call_args = ctx.in_call_args in - let in_overload_call_args = ctx.in_overload_call_args in - ctx.in_call_args <- true; - ctx.in_overload_call_args <- in_overload; + let in_call_args = ctx.f.in_call_args in + let in_overload_call_args = ctx.f.in_overload_call_args in + ctx.f.in_call_args <- true; + ctx.f.in_overload_call_args <- in_overload; (fun () -> - ctx.in_call_args <- in_call_args; - ctx.in_overload_call_args <- in_overload_call_args; + ctx.f.in_call_args <- in_call_args; + ctx.f.in_overload_call_args <- in_overload_call_args; ) in let el = try loop el args with exc -> restore(); raise exc; in @@ -241,14 +241,14 @@ let unify_field_call ctx fa el_typed el p inline = else if fa.fa_field.cf_overloads <> [] then OverloadMeta else OverloadNone in - (* Delayed display handling works like this: If ctx.in_overload_call_args is set (via attempt_calls calling unify_call_args' below), - the code which normally raises eager Display exceptions (in typerDisplay.ml handle_display) instead stores them in ctx.delayed_display. + (* Delayed display handling works like this: If ctx.e.in_overload_call_args is set (via attempt_calls calling unify_call_args' below), + the code which normally raises eager Display exceptions (in typerDisplay.ml handle_display) instead stores them in ctx.g.delayed_display. The overload handling here extracts them and associates the exception with the field call candidates. Afterwards, normal overload resolution can take place and only then the display callback is actually committed. *) - let extract_delayed_display () = match ctx.delayed_display with + let extract_delayed_display () = match ctx.g.delayed_display with | Some f -> - ctx.delayed_display <- None; + ctx.g.delayed_display <- None; Some f | None -> None @@ -328,11 +328,11 @@ let unify_field_call ctx fa el_typed el p inline = | cf :: candidates -> let known_monos = List.map (fun (m,_) -> m,m.tm_type,m.tm_down_constraints - ) ctx.monomorphs.perfunction in - let current_monos = ctx.monomorphs.perfunction in + ) ctx.e.monomorphs.perfunction in + let current_monos = ctx.e.monomorphs.perfunction in begin try let candidate = attempt_call cf true in - ctx.monomorphs.perfunction <- current_monos; + ctx.e.monomorphs.perfunction <- current_monos; if overload_kind = OverloadProper then begin let candidates,failures = loop candidates in candidate :: candidates,failures @@ -343,7 +343,7 @@ let unify_field_call ctx fa el_typed el p inline = if t != m.tm_type then m.tm_type <- t; if constr != m.tm_down_constraints then m.tm_down_constraints <- constr; ) known_monos; - ctx.monomorphs.perfunction <- current_monos; + ctx.e.monomorphs.perfunction <- current_monos; check_unknown_ident err; let candidates,failures = loop candidates in candidates,(cf,err,extract_delayed_display()) :: failures @@ -362,7 +362,7 @@ let unify_field_call ctx fa el_typed el p inline = in (* There's always a chance that we never even came across the EDisplay in an argument, so let's look for it (issue #11422). *) let check_display_args () = - if ctx.is_display_file then begin + if ctx.m.is_display_file then begin let rec loop el = match el with | [] -> () @@ -465,9 +465,9 @@ object(self) end method private macro_call (ethis : texpr) (cf : tclass_field) (el : expr list) = - if ctx.macro_depth > 300 then raise_typing_error "Stack overflow" p; - ctx.macro_depth <- ctx.macro_depth + 1; - ctx.with_type_stack <- with_type :: ctx.with_type_stack; + if ctx.e.macro_depth > 300 then raise_typing_error "Stack overflow" p; + ctx.e.macro_depth <- ctx.e.macro_depth + 1; + ctx.e.with_type_stack <- with_type :: ctx.e.with_type_stack; let ethis_f = ref (fun () -> ()) in let macro_in_macro () = (fun () -> @@ -506,8 +506,8 @@ object(self) loop c | _ -> die "" __LOC__)) in - ctx.macro_depth <- ctx.macro_depth - 1; - ctx.with_type_stack <- List.tl ctx.with_type_stack; + ctx.e.macro_depth <- ctx.e.macro_depth - 1; + ctx.e.with_type_stack <- List.tl ctx.e.with_type_stack; let old = ctx.com.error_ext in ctx.com.error_ext <- (fun err -> let ep = err.err_pos in @@ -538,7 +538,7 @@ object(self) let el = el_typed @ List.map (fun e -> type_expr ctx e WithType.value) el in let t = if t == t_dynamic then t_dynamic - else if ctx.untyped then + else if ctx.f.untyped then mk_mono() else raise_typing_error (s_type (print_context()) e.etype ^ " cannot be called") e.epos diff --git a/src/typing/calls.ml b/src/typing/calls.ml index 3261058c30b..7a4e275aec7 100644 --- a/src/typing/calls.ml +++ b/src/typing/calls.ml @@ -51,8 +51,8 @@ let make_call ctx e params t ?(force_inline=false) p = end; let config = Inline.inline_config cl f params t in ignore(follow f.cf_type); (* force evaluation *) - (match cl, ctx.curclass.cl_kind, params with - | Some c, KAbstractImpl _, { eexpr = TLocal { v_meta = v_meta } } :: _ when c == ctx.curclass -> + (match cl, ctx.c.curclass.cl_kind, params with + | Some c, KAbstractImpl _, { eexpr = TLocal { v_meta = v_meta } } :: _ when c == ctx.c.curclass -> if f.cf_name <> "_new" && has_meta Meta.This v_meta @@ -60,7 +60,7 @@ let make_call ctx e params t ?(force_inline=false) p = then if assign_to_this_is_allowed ctx then (* Current method needs to infer CfModifiesThis flag, since we are calling a method, which modifies `this` *) - add_class_field_flag ctx.curfield CfModifiesThis + add_class_field_flag ctx.f.curfield CfModifiesThis else raise_typing_error ("Abstract 'this' value can only be modified inside an inline function. '" ^ f.cf_name ^ "' modifies 'this'") p; | _ -> () @@ -206,7 +206,7 @@ let rec acc_get ctx g = | AKAccess _ -> die "" __LOC__ | AKResolve(sea,name) -> (dispatcher sea.se_access.fa_pos)#resolve_call sea name - | AKUsingAccessor sea | AKUsingField sea when ctx.in_display -> + | AKUsingAccessor sea | AKUsingField sea when ctx.f.in_display -> (* Generate a TField node so we can easily match it for position/usage completion (issue #1968) *) let e_field = FieldAccess.get_field_expr sea.se_access FGet in let id,_ = store_typed_expr ctx.com sea.se_this e_field.epos in @@ -220,7 +220,7 @@ let rec acc_get ctx g = begin match fa.fa_field.cf_kind with | Method MethMacro -> (* If we are in display mode, we're probably hovering a macro call subject. Just generate a normal field. *) - if ctx.in_display then + if ctx.f.in_display then FieldAccess.get_field_expr fa FRead else raise_typing_error "Invalid macro access" fa.fa_pos @@ -328,9 +328,9 @@ let call_to_string ctx ?(resume=false) e = else let gen_to_string e = (* Ignore visibility of the toString field. *) - ctx.meta <- (Meta.PrivateAccess,[],e.epos) :: ctx.meta; + ctx.f.meta <- (Meta.PrivateAccess,[],e.epos) :: ctx.f.meta; let acc = type_field (TypeFieldConfig.create resume) ctx e "toString" e.epos (MCall []) (WithType.with_type ctx.t.tstring) in - ctx.meta <- List.tl ctx.meta; + ctx.f.meta <- List.tl ctx.f.meta; build_call ctx acc [] (WithType.with_type ctx.t.tstring) e.epos in if ctx.com.config.pf_static && not (is_nullable e.etype) then @@ -359,7 +359,7 @@ let type_bind ctx (e : texpr) (args,ret) params p = let vexpr v = mk (TLocal v) v.v_type p in let acount = ref 0 in let alloc_name n = - if n = "" && not ctx.is_display_file then begin + if n = "" && not ctx.m.is_display_file then begin incr acount; "a" ^ string_of_int !acount; end else @@ -468,12 +468,12 @@ let array_access ctx e1 e2 mode p = let skip_abstract = fast_eq et at in loop ~skip_abstract at | _, _ -> - let pt = spawn_monomorph ctx p in + let pt = spawn_monomorph ctx.e p in let t = ctx.t.tarray pt in begin try unify_raise et t p with Error { err_message = Unify _ } -> - if not ctx.untyped then begin + if not ctx.f.untyped then begin let msg = if !has_abstract_array_access then "No @:arrayAccess function accepts an argument of " ^ (s_type (print_context()) e2.etype) else diff --git a/src/typing/fields.ml b/src/typing/fields.ml index b1c29238caf..ed16c63b862 100644 --- a/src/typing/fields.ml +++ b/src/typing/fields.ml @@ -77,7 +77,7 @@ let no_abstract_constructor c p = let check_constructor_access ctx c f p = if (Meta.has Meta.CompilerGenerated f.cf_meta) then display_error ctx.com (error_msg (No_constructor (TClassDecl c))) p; - if not (can_access ctx c f true || extends ctx.curclass c) && not ctx.untyped then display_error ctx.com (Printf.sprintf "Cannot access private constructor of %s" (s_class_path c)) p + if not (can_access ctx c f true || extends ctx.c.curclass c) && not ctx.f.untyped then display_error ctx.com (Printf.sprintf "Cannot access private constructor of %s" (s_class_path c)) p let check_no_closure_meta ctx cf fa mode p = match mode with @@ -109,12 +109,12 @@ let field_access ctx mode f fh e pfield = let pfull = punion e.epos pfield in let is_set = match mode with MSet _ -> true | _ -> false in check_no_closure_meta ctx f fh mode pfield; - let bypass_accessor () = if ctx.bypass_accessor > 0 then (ctx.bypass_accessor <- ctx.bypass_accessor - 1; true) else false in + let bypass_accessor () = if ctx.e.bypass_accessor > 0 then (ctx.e.bypass_accessor <- ctx.e.bypass_accessor - 1; true) else false in let make_access inline = FieldAccess.create e f fh (inline && ctx.allow_inline) pfull in match f.cf_kind with | Method m -> let normal () = AKField(make_access false) in - if is_set && m <> MethDynamic && not ctx.untyped then raise_typing_error "Cannot rebind this method : please use 'dynamic' before method declaration" pfield; + if is_set && m <> MethDynamic && not ctx.f.untyped then raise_typing_error "Cannot rebind this method : please use 'dynamic' before method declaration" pfield; let maybe_check_visibility c static = (* For overloads we have to resolve the actual field before we can check accessibility. *) begin match mode with @@ -191,30 +191,30 @@ let field_access ctx mode f fh e pfield = AKNo((normal false),pfield) in match (match mode with MGet | MCall _ -> v.v_read | MSet _ -> v.v_write) with - | AccNo when not (Meta.has Meta.PrivateAccess ctx.meta) -> + | AccNo when not (Meta.has Meta.PrivateAccess ctx.f.meta) -> (match follow e.etype with - | TInst (c,_) when extends ctx.curclass c || can_access ctx c { f with cf_flags = unset_flag f.cf_flags (int_of_class_field_flag CfPublic) } false -> + | TInst (c,_) when extends ctx.c.curclass c || can_access ctx c { f with cf_flags = unset_flag f.cf_flags (int_of_class_field_flag CfPublic) } false -> normal false | TAnon a -> (match !(a.a_status) with - | ClassStatics c2 when ctx.curclass == c2 || can_access ctx c2 { f with cf_flags = unset_flag f.cf_flags (int_of_class_field_flag CfPublic) } true -> normal false - | _ -> if ctx.untyped then normal false else normal_failure()) + | ClassStatics c2 when ctx.c.curclass == c2 || can_access ctx c2 { f with cf_flags = unset_flag f.cf_flags (int_of_class_field_flag CfPublic) } true -> normal false + | _ -> if ctx.f.untyped then normal false else normal_failure()) | _ -> - if ctx.untyped then normal false else normal_failure()) + if ctx.f.untyped then normal false else normal_failure()) | AccNormal | AccNo -> normal false - | AccCall when (not ctx.allow_transform) || (ctx.in_display && DisplayPosition.display_position#enclosed_in pfull) -> + | AccCall when (not ctx.allow_transform) || (ctx.f.in_display && DisplayPosition.display_position#enclosed_in pfull) -> normal false | AccCall -> let m = (match mode with MSet _ -> "set_" | _ -> "get_") ^ f.cf_name in let bypass_accessor = ( - m = ctx.curfield.cf_name + m = ctx.f.curfield.cf_name && match e.eexpr with | TConst TThis -> true - | TLocal v -> Option.map_default (fun vthis -> v == vthis) false ctx.vthis - | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true + | TLocal v -> Option.map_default (fun vthis -> v == vthis) false ctx.f.vthis + | TTypeExpr (TClassDecl c) when c == ctx.c.curclass -> true | _ -> false ) || bypass_accessor () in @@ -234,15 +234,15 @@ let field_access ctx mode f fh e pfield = AKAccessor (make_access false) end | AccNever -> - if ctx.untyped then normal false else normal_failure() + if ctx.f.untyped then normal false else normal_failure() | AccInline -> normal true | AccCtor -> let is_child_of_abstract c = - has_class_flag c CAbstract && extends ctx.curclass c + has_class_flag c CAbstract && extends ctx.c.curclass c in - (match ctx.curfun, fh with - | FunConstructor, FHInstance(c,_) when c == ctx.curclass || is_child_of_abstract c -> normal false + (match ctx.e.curfun, fh with + | FunConstructor, FHInstance(c,_) when c == ctx.c.curclass || is_child_of_abstract c -> normal false | _ -> normal_failure() ) | AccRequire (r,msg) -> @@ -382,8 +382,8 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = | CTypes tl -> type_field_by_list (fun (t,_) -> type_field_by_et type_field_by_type e t) tl | CUnknown -> - if not (List.exists (fun (m,_) -> m == r) ctx.monomorphs.perfunction) && not (ctx.untyped && ctx.com.platform = Neko) then - ctx.monomorphs.perfunction <- (r,p) :: ctx.monomorphs.perfunction; + if not (List.exists (fun (m,_) -> m == r) ctx.e.monomorphs.perfunction) && not (ctx.f.untyped && ctx.com.platform = Neko) then + ctx.e.monomorphs.perfunction <- (r,p) :: ctx.e.monomorphs.perfunction; let f = mk_field() in Monomorph.add_down_constraint r (MField f); Monomorph.add_down_constraint r MOpenStructure; @@ -426,9 +426,9 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = check cfl | cf :: cfl -> (* We always want to reset monomorphs here because they will be handled again when making the actual call. *) - let current_monos = ctx.monomorphs.perfunction in + let current_monos = ctx.e.monomorphs.perfunction in let check () = - ctx.monomorphs.perfunction <- current_monos; + ctx.e.monomorphs.perfunction <- current_monos; check cfl in try @@ -441,7 +441,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = else begin let e = unify_static_extension ctx e t0 p in ImportHandling.mark_import_position ctx pc; - ctx.monomorphs.perfunction <- current_monos; + ctx.e.monomorphs.perfunction <- current_monos; AKUsingField (make_static_extension_access c cf e false p) end | _ -> @@ -572,7 +572,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = with Not_found -> try type_field_by_module e t with Not_found when not (TypeFieldConfig.do_resume cfg) -> - if not ctx.untyped then begin + if not ctx.f.untyped then begin let has_special_field a = List.exists (fun (_,cf) -> cf.cf_name = i) a.a_ops || List.exists (fun (_,_,cf) -> cf.cf_name = i) a.a_unops @@ -594,7 +594,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = with Exit -> display_error ctx.com (StringError.string_error i (string_source tthis) (s_type (print_context()) tthis ^ " has no field " ^ i)) pfield end; - AKExpr (mk (TField (e,FDynamic i)) (spawn_monomorph ctx p) p) + AKExpr (mk (TField (e,FDynamic i)) (spawn_monomorph ctx.e p) p) let type_field_default_cfg = type_field TypeFieldConfig.default diff --git a/src/typing/forLoop.ml b/src/typing/forLoop.ml index 65b67979cd5..6bb73631c7a 100644 --- a/src/typing/forLoop.ml +++ b/src/typing/forLoop.ml @@ -458,9 +458,9 @@ type iteration_kind = | IKKeyValue of iteration_ident * iteration_ident let type_for_loop ctx handle_display ik e1 e2 p = - let old_loop = ctx.in_loop in + let old_loop = ctx.e.in_loop in let old_locals = save_locals ctx in - ctx.in_loop <- true; + ctx.e.in_loop <- true; let e2 = Expr.ensure_block e2 in let check_display (i,pi,dko) = match dko with | None -> () @@ -472,7 +472,7 @@ let type_for_loop ctx handle_display ik e1 e2 p = let i = add_local_with_origin ctx TVOForVariable i iterator.it_type pi in let e2 = type_expr ctx e2 NoValue in check_display (i,pi,dko); - ctx.in_loop <- old_loop; + ctx.e.in_loop <- old_loop; old_locals(); begin try IterationKind.to_texpr ctx i iterator e2 p @@ -509,7 +509,7 @@ let type_for_loop ctx handle_display ik e1 e2 p = mk (TVar(vtmp,Some e1)) ctx.t.tvoid e1.epos; mk (TWhile(ehasnext,ebody,NormalWhile)) ctx.t.tvoid p; ]) ctx.t.tvoid p in - ctx.in_loop <- old_loop; + ctx.e.in_loop <- old_loop; old_locals(); e diff --git a/src/typing/functionArguments.ml b/src/typing/functionArguments.ml index 4baf7402020..cba9c2add66 100644 --- a/src/typing/functionArguments.ml +++ b/src/typing/functionArguments.ml @@ -131,9 +131,9 @@ object(self) in loop (abstract_this <> None) syntax with_default - (* Brings arguments into context by adding them to `ctx.locals`. *) - method bring_into_context = + (* Brings arguments into context by adding them to `ctx.f.locals`. *) + method bring_into_context ctx = List.iter (fun (v,_) -> - ctx.locals <- PMap.add v.v_name v ctx.locals + ctx.f.locals <- PMap.add v.v_name v ctx.f.locals ) self#for_expr end diff --git a/src/typing/generic.ml b/src/typing/generic.ml index b6f94bd339f..30e59364c07 100644 --- a/src/typing/generic.ml +++ b/src/typing/generic.ml @@ -26,7 +26,7 @@ let make_generic ctx ps pt debug p = begin match c.cl_kind with | KExpr e -> let name = ident_safe (Ast.Printer.s_expr e) in - let e = type_expr {ctx with locals = PMap.empty} e WithType.value in + let e = type_expr {ctx with f = {ctx.f with locals = PMap.empty}} e WithType.value in name,(t,Some e) | _ -> ((ident_safe (s_type_path_underscore c.cl_path)) ^ (loop_tl top tl),(t,None)) @@ -354,7 +354,7 @@ let build_generic_class ctx c p tl = if gctx.generic_debug then print_endline (Printf.sprintf "[GENERIC] %s" (Printer.s_tclass_field " " cf_new)); t in - let t = spawn_monomorph ctx p in + let t = spawn_monomorph ctx.e p in let r = make_lazy ctx t (fun r -> let t0 = f() in unify_raise t0 t p; diff --git a/src/typing/instanceBuilder.ml b/src/typing/instanceBuilder.ml index a600016d352..5d86ee883b9 100644 --- a/src/typing/instanceBuilder.ml +++ b/src/typing/instanceBuilder.ml @@ -14,8 +14,8 @@ let get_macro_path ctx e args p = let path = match e with | (EConst(Ident i)),_ -> let path = try - if not (PMap.mem i ctx.curclass.cl_statics) then raise Not_found; - ctx.curclass.cl_path + if not (PMap.mem i ctx.c.curclass.cl_statics) then raise Not_found; + ctx.c.curclass.cl_path with Not_found -> try (t_infos (let path,_,_ = PMap.find i (ctx.m.import_resolution#extract_field_imports) in path)).mt_path with Not_found -> @@ -37,12 +37,12 @@ let build_macro_type ctx pl p = | _ -> raise_typing_error "MacroType requires a single expression call parameter" p ) in - let old = ctx.ret in + let old = ctx.e.ret in let t = (match ctx.g.do_macro ctx MMacroType path field args p with - | MError | MMacroInMacro -> spawn_monomorph ctx p - | MSuccess _ -> ctx.ret + | MError | MMacroInMacro -> spawn_monomorph ctx.e p + | MSuccess _ -> ctx.e.ret ) in - ctx.ret <- old; + ctx.e.ret <- old; t let build_macro_build ctx c pl cfl p = @@ -55,14 +55,14 @@ let build_macro_build ctx c pl cfl p = | _,[ECall(e,args),_],_ -> get_macro_path ctx e args p | _ -> raise_typing_error "genericBuild requires a single expression call parameter" p in - let old = ctx.ret,ctx.get_build_infos in - ctx.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl)); + let old = ctx.e.ret,ctx.c.get_build_infos in + ctx.c.get_build_infos <- (fun() -> Some (TClassDecl c, pl, cfl)); let t = (match ctx.g.do_macro ctx MMacroType path field args p with - | MError | MMacroInMacro -> spawn_monomorph ctx p - | MSuccess _ -> ctx.ret + | MError | MMacroInMacro -> spawn_monomorph ctx.e p + | MSuccess _ -> ctx.e.ret ) in - ctx.ret <- fst old; - ctx.get_build_infos <- snd old; + ctx.e.ret <- fst old; + ctx.c.get_build_infos <- snd old; t (* -------------------------------------------------------------------------- *) @@ -73,7 +73,7 @@ let get_build_info ctx mtype p = | TClassDecl c -> if ctx.pass > PBuildClass then ignore(c.cl_build()); let build f s tl = - let t = spawn_monomorph ctx p in + let t = spawn_monomorph ctx.e p in let r = make_lazy ctx t (fun r -> let tf = f tl in unify_raise tf t p; diff --git a/src/typing/macroContext.ml b/src/typing/macroContext.ml index 8a85aa0cdb2..b76ddbec32c 100644 --- a/src/typing/macroContext.ml +++ b/src/typing/macroContext.ml @@ -79,7 +79,7 @@ let macro_timer com l = let typing_timer ctx need_type f = let t = Timer.timer ["typing"] in - let old = ctx.com.error_ext and oldp = ctx.pass and oldlocals = ctx.locals in + let old = ctx.com.error_ext and oldp = ctx.pass and oldlocals = ctx.f.locals in let restore_report_mode = disable_report_mode ctx.com in (* disable resumable errors... unless we are in display mode (we want to reach point of completion) @@ -94,7 +94,7 @@ let typing_timer ctx need_type f = t(); ctx.com.error_ext <- old; ctx.pass <- oldp; - ctx.locals <- oldlocals; + ctx.f.locals <- oldlocals; restore_report_mode (); in try @@ -453,7 +453,7 @@ let make_macro_api ctx mctx p = tp.tp_meta <- tp.tp_meta @ (List.map (fun (m,el,_) -> (m,el,p)) ml); ); MacroApi.get_local_type = (fun() -> - match ctx.get_build_infos() with + match ctx.c.get_build_infos() with | Some (mt,tl,_) -> Some (match mt with | TClassDecl c -> TInst (c,tl) @@ -462,23 +462,23 @@ let make_macro_api ctx mctx p = | TAbstractDecl a -> TAbstract(a,tl) ) | _ -> - if ctx.curclass == null_class then + if ctx.c.curclass == null_class then None else - Some (TInst (ctx.curclass,[])) + Some (TInst (ctx.c.curclass,[])) ); MacroApi.get_expected_type = (fun() -> - match ctx.with_type_stack with + match ctx.e.with_type_stack with | (WithType.WithType(t,_)) :: _ -> Some t | _ -> None ); MacroApi.get_call_arguments = (fun() -> - match ctx.call_argument_stack with + match ctx.e.call_argument_stack with | [] -> None | el :: _ -> Some el ); MacroApi.get_local_method = (fun() -> - ctx.curfield.cf_name; + ctx.f.curfield.cf_name; ); MacroApi.get_local_using = (fun() -> List.map fst ctx.m.module_using; @@ -487,10 +487,10 @@ let make_macro_api ctx mctx p = ctx.m.import_statements; ); MacroApi.get_local_vars = (fun () -> - ctx.locals; + ctx.f.locals; ); MacroApi.get_build_fields = (fun() -> - match ctx.get_build_infos() with + match ctx.c.get_build_infos() with | None -> Interp.vnull | Some (_,_,fields) -> Interp.encode_array (List.map Interp.encode_field fields) ); @@ -537,7 +537,7 @@ let make_macro_api ctx mctx p = let mpath = Ast.parse_path m in begin try let m = ctx.com.module_lut#find mpath in - ignore(TypeloadModule.type_types_into_module ctx m types pos) + ignore(TypeloadModule.type_types_into_module ctx.com ctx.g m types pos) with Not_found -> let mnew = TypeloadModule.type_module ctx mpath (Path.UniqueKey.lazy_path ctx.m.curmod.m_extra.m_file) types pos in mnew.m_extra.m_kind <- MFake; @@ -682,7 +682,7 @@ and flush_macro_context mint mctx = let type_filters = [ FiltersCommon.remove_generic_base; Exceptions.patch_constructors mctx; - (fun mt -> AddFieldInits.add_field_inits mctx.curclass.cl_path (RenameVars.init mctx.com) mctx.com mt); + (fun mt -> AddFieldInits.add_field_inits mctx.c.curclass.cl_path (RenameVars.init mctx.com) mctx.com mt); minimal_restore; ] in let ready = fun t -> @@ -750,7 +750,7 @@ let create_macro_context com = com2.platform <- Eval; Common.init_platform com2; let mctx = !create_context_ref com2 None in - mctx.is_display_file <- false; + mctx.m.is_display_file <- false; CommonCache.lock_signature com2 "get_macro_context"; mctx @@ -780,6 +780,7 @@ let load_macro_module mctx com cpath display p = enum_with_type = None; module_using = []; import_statements = []; + is_display_file = (com.display.dms_kind <> DMNone && DisplayPosition.display_position#is_in_file (Path.UniqueKey.lazy_key mloaded.m_extra.m_file)); }; mloaded,(fun () -> mctx.com.display <- old) @@ -821,6 +822,7 @@ let load_macro'' com mctx display cpath f p = enum_with_type = None; module_using = []; import_statements = []; + is_display_file = false; }; t(); meth @@ -1002,7 +1004,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p = | MBuild -> "Array",(fun () -> let fields = if v = Interp.vnull then - (match ctx.get_build_infos() with + (match ctx.c.get_build_infos() with | None -> die "" __LOC__ | Some (_,_,fields) -> fields) else @@ -1013,14 +1015,14 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p = | MMacroType -> "ComplexType",(fun () -> let t = if v = Interp.vnull then - spawn_monomorph ctx p + spawn_monomorph ctx.e p else try let ct = Interp.decode_ctype v in Typeload.load_complex_type ctx false ct; with MacroApi.Invalid_expr | EvalContext.RunTimeException _ -> Interp.decode_type v in - ctx.ret <- t; + ctx.e.ret <- t; MSuccess (EBlock [],p) ) in @@ -1034,7 +1036,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p = e let call_macro mctx args margs call p = - mctx.curclass <- null_class; + mctx.c.curclass <- null_class; let el, _ = CallUnification.unify_call_args mctx args margs t_dynamic p false false false in call (List.map (fun e -> try Interp.make_const e with Exit -> raise_typing_error "Argument should be a constant" e.epos) el) diff --git a/src/typing/matcher.ml b/src/typing/matcher.ml index 2149921be3c..7aa11c7c265 100644 --- a/src/typing/matcher.ml +++ b/src/typing/matcher.ml @@ -26,7 +26,7 @@ module Match = struct open Typecore let match_expr ctx e cases def with_type postfix_match p = - let match_debug = Meta.has (Meta.Custom ":matchDebug") ctx.curfield.cf_meta in + let match_debug = Meta.has (Meta.Custom ":matchDebug") ctx.f.curfield.cf_meta in let rec loop e = match fst e with | EArrayDecl el when (match el with [(EFor _ | EWhile _),_] -> false | _ -> true) -> let el = List.map (fun e -> type_expr ctx e WithType.value) el in diff --git a/src/typing/matcher/case.ml b/src/typing/matcher/case.ml index 1afd9be3af4..c03ca512e22 100644 --- a/src/typing/matcher/case.ml +++ b/src/typing/matcher/case.ml @@ -29,13 +29,13 @@ let make ctx t el eg eo_ast with_type postfix_match p = let t_old = v.v_type in v.v_type <- map v.v_type; (v,t_old) :: acc - ) ctx.locals [] in - let old_ret = ctx.ret in - ctx.ret <- map ctx.ret; + ) ctx.f.locals [] in + let old_ret = ctx.e.ret in + ctx.e.ret <- map ctx.e.ret; let pctx = { ctx = ctx; current_locals = PMap.empty; - ctx_locals = ctx.locals; + ctx_locals = ctx.f.locals; or_locals = None; in_reification = false; is_postfix_match = postfix_match; @@ -63,7 +63,7 @@ let make ctx t el eg eo_ast with_type postfix_match p = let e = type_expr ctx e with_type in Some e in - ctx.ret <- old_ret; + ctx.e.ret <- old_ret; List.iter (fun (v,t) -> v.v_type <- t) old_types; save(); { diff --git a/src/typing/matcher/exprToPattern.ml b/src/typing/matcher/exprToPattern.ml index 3d6446cb0f3..3db86b92e1a 100644 --- a/src/typing/matcher/exprToPattern.ml +++ b/src/typing/matcher/exprToPattern.ml @@ -63,7 +63,7 @@ let get_general_module_type ctx mt p = let unify_type_pattern ctx mt t p = let tcl = get_general_module_type ctx mt p in match tcl with - | TAbstract(a,_) -> unify ctx (TAbstract(a,[spawn_monomorph ctx p])) t p + | TAbstract(a,_) -> unify ctx (TAbstract(a,[spawn_monomorph ctx.e p])) t p | _ -> die "" __LOC__ let rec make pctx toplevel t e = @@ -93,7 +93,7 @@ let rec make pctx toplevel t e = let v = alloc_var (VUser TVOPatternVariable) name t p in if final then add_var_flag v VFinal; pctx.current_locals <- PMap.add name (v,p) pctx.current_locals; - ctx.locals <- PMap.add name v ctx.locals; + ctx.f.locals <- PMap.add name v ctx.f.locals; v in let con_enum en ef p = @@ -166,18 +166,18 @@ let rec make pctx toplevel t e = ) in let try_typing e = - let old = ctx.untyped in - ctx.untyped <- true; + let old = ctx.f.untyped in + ctx.f.untyped <- true; let restore = catch_errors () in let e = try type_expr ctx e (WithType.with_type t) with exc -> restore(); - ctx.untyped <- old; + ctx.f.untyped <- old; raise exc in restore(); - ctx.untyped <- old; + ctx.f.untyped <- old; let pat = check_expr e in begin match pat with | PatConstructor((ConTypeExpr mt,_),_) -> unify_type_pattern ctx mt t e.epos; @@ -405,7 +405,7 @@ let rec make pctx toplevel t e = loop None e1 | EBinop(OpArrow,e1,e2) -> let restore = save_locals ctx in - ctx.locals <- pctx.ctx_locals; + ctx.f.locals <- pctx.ctx_locals; let v = add_local false "_" null_pos in (* Tricky stuff: Extractor expressions are like normal expressions, so we don't want to deal with GADT-applied types here. Let's unapply, then reapply after we're done with the extractor (#5952). *) @@ -422,12 +422,12 @@ let rec make pctx toplevel t e = (* Special case for completion on a pattern local: We don't want to add the local to the context while displaying (#7319) *) | EDisplay((EConst (Ident _),_ as e),dk) when pctx.ctx.com.display.dms_kind = DMDefault -> - let locals = ctx.locals in + let locals = ctx.f.locals in let pat = loop e in - let locals' = ctx.locals in - ctx.locals <- locals; + let locals' = ctx.f.locals in + ctx.f.locals <- locals; ignore(TyperDisplay.handle_edisplay ctx e (display_mode()) MGet (WithType.with_type t)); - ctx.locals <- locals'; + ctx.f.locals <- locals'; pat (* For signature completion, we don't want to recurse into the inner pattern because there's probably a EDisplay(_,DMMarked) in there. We can handle display immediately because inner patterns should not diff --git a/src/typing/operators.ml b/src/typing/operators.ml index ba188a434f2..8cc4ecd776c 100644 --- a/src/typing/operators.ml +++ b/src/typing/operators.ml @@ -94,7 +94,7 @@ let check_assign ctx e = raise_typing_error "Cannot assign to final" e.epos | TLocal {v_extra = None} | TArray _ | TField _ | TIdent _ -> () - | TConst TThis | TTypeExpr _ when ctx.untyped -> + | TConst TThis | TTypeExpr _ when ctx.f.untyped -> () | _ -> if not (Common.ignore_error ctx.com) then diff --git a/src/typing/typeload.ml b/src/typing/typeload.ml index f31aa999a28..7bc27105321 100644 --- a/src/typing/typeload.ml +++ b/src/typing/typeload.ml @@ -229,11 +229,6 @@ let load_type_def ctx p t = let timer = Timer.timer ["typing";"load_type_def"] in Std.finally timer (load_type_def ctx p) t *) -let resolve_position_by_path ctx path p = - let mt = load_type_def ctx p path in - let p = (t_infos mt).mt_pos in - raise_positions [p] - let generate_args_meta com cls_opt add_meta args = let values = List.fold_left (fun acc ((name,p),_,_,_,eo) -> match eo with Some e -> ((name,p,NoQuotes),e) :: acc | _ -> acc) [] args in (match values with @@ -280,11 +275,11 @@ let check_param_constraints ctx t map ttp p = unify_raise t ti p with Error ({ err_message = Unify l } as err) -> let fail() = - if not ctx.untyped then display_error_ext ctx.com { err with err_message = (Unify (Constraint_failure (s_type_path ttp.ttp_class.cl_path) :: l)) } + if not ctx.f.untyped then display_error_ext ctx.com { err with err_message = (Unify (Constraint_failure (s_type_path ttp.ttp_class.cl_path) :: l)) } in match follow t with | TInst({cl_kind = KExpr e},_) -> - let e = type_expr {ctx with locals = PMap.empty} e (WithType.with_type ti) in + let e = type_expr {ctx with f = {ctx.f with locals = PMap.empty}} e (WithType.with_type ti) in begin try unify_raise e.etype ti p with Error { err_message = Unify _ } -> fail() end | _ -> @@ -449,7 +444,7 @@ and load_instance ctx ?(allow_display=false) ptp get_params = let t = load_instance' ctx ptp get_params in if allow_display then DisplayEmitter.check_display_type ctx t ptp; t - with Error { err_message = Module_not_found path } when ctx.macro_depth <= 0 && (ctx.com.display.dms_kind = DMDefault) && DisplayPosition.display_position#enclosed_in ptp.pos_path -> + with Error { err_message = Module_not_found path } when ctx.e.macro_depth <= 0 && (ctx.com.display.dms_kind = DMDefault) && DisplayPosition.display_position#enclosed_in ptp.pos_path -> let s = s_type_path path in DisplayToplevel.collect_and_raise ctx TKType NoValue CRTypeHint (s,ptp.pos_full) ptp.pos_path @@ -459,7 +454,7 @@ and load_instance ctx ?(allow_display=false) ptp get_params = and load_complex_type' ctx allow_display (t,p) = match t with | CTParent t -> load_complex_type ctx allow_display t - | CTPath { path = {tpackage = ["$"]; tname = "_hx_mono" }} -> spawn_monomorph ctx p + | CTPath { path = {tpackage = ["$"]; tname = "_hx_mono" }} -> spawn_monomorph ctx.e p | CTPath ptp -> load_instance ~allow_display ctx ptp ParamNormal | CTOptional _ -> raise_typing_error "Optional type not allowed here" p | CTNamed _ -> raise_typing_error "Named type not allowed here" p @@ -610,7 +605,7 @@ and load_complex_type' ctx allow_display (t,p) = } in if !final then add_class_field_flag cf CfFinal; init_meta_overloads ctx None cf; - if ctx.is_display_file then begin + if ctx.m.is_display_file then begin DisplayEmitter.check_display_metadata ctx cf.cf_meta; if DisplayPosition.display_position#enclosed_in cf.cf_name_pos then displayed_field := Some cf; end; @@ -708,7 +703,7 @@ let t_iterator ctx p = match load_qualified_type_def ctx [] "StdTypes" "Iterator" p with | TTypeDecl t -> add_dependency ctx.m.curmod t.t_module; - let pt = spawn_monomorph ctx p in + let pt = spawn_monomorph ctx.e p in apply_typedef t [pt], pt | _ -> die "" __LOC__ @@ -718,7 +713,7 @@ let t_iterator ctx p = *) let load_type_hint ?(opt=false) ctx pcur t = let t = match t with - | None -> spawn_monomorph ctx pcur + | None -> spawn_monomorph ctx.e pcur | Some (t,p) -> load_complex_type ctx true (t,p) in if opt then ctx.t.tnull t else t @@ -733,7 +728,7 @@ let rec type_type_param ctx host path p tp = c.cl_meta <- tp.Ast.tp_meta; if host = TPHEnumConstructor then c.cl_meta <- (Meta.EnumConstructorParam,[],null_pos) :: c.cl_meta; let ttp = mk_type_param c host None None in - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos tp.tp_name) then + if ctx.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos tp.tp_name) then DisplayEmitter.display_type ctx ttp.ttp_type (pos tp.tp_name); ttp diff --git a/src/typing/typeloadCheck.ml b/src/typing/typeloadCheck.ml index d0cacbff8a0..6532c9e99f3 100644 --- a/src/typing/typeloadCheck.ml +++ b/src/typing/typeloadCheck.ml @@ -39,11 +39,11 @@ let is_generic_parameter ctx c = (* first check field parameters, then class parameters *) let name = snd c.cl_path in try - ignore(lookup_param name ctx.curfield.cf_params); - has_class_field_flag ctx.curfield CfGeneric + ignore(lookup_param name ctx.f.curfield.cf_params); + has_class_field_flag ctx.f.curfield CfGeneric with Not_found -> try ignore(lookup_param name ctx.type_params); - (match ctx.curclass.cl_kind with | KGeneric -> true | _ -> false); + (match ctx.c.curclass.cl_kind with | KGeneric -> true | _ -> false); with Not_found -> false @@ -287,7 +287,7 @@ let class_field_no_interf c i = let rec return_flow ctx e = let error() = - display_error ctx.com (Printf.sprintf "Missing return: %s" (s_type (print_context()) ctx.ret)) e.epos; raise Exit + display_error ctx.com (Printf.sprintf "Missing return: %s" (s_type (print_context()) ctx.e.ret)) e.epos; raise Exit in let return_flow = return_flow ctx in match e.eexpr with @@ -332,7 +332,7 @@ let check_global_metadata ctx meta f_add mpath tpath so = let add = ((field_mode && to_fields) || (not field_mode && to_types)) && (match_path recursive sl1 sl2) in if add then f_add m ) ctx.com.global_metadata; - if ctx.is_display_file then delay ctx PCheckConstraint (fun () -> DisplayEmitter.check_display_metadata ctx meta) + if ctx.m.is_display_file then delay ctx PCheckConstraint (fun () -> DisplayEmitter.check_display_metadata ctx meta) module Inheritance = struct let is_basic_class_path path = match path with @@ -510,7 +510,6 @@ module Inheritance = struct let set_heritance ctx c herits p = let is_lib = Meta.has Meta.LibType c.cl_meta in - let ctx = { ctx with curclass = c; type_params = c.cl_params; } in let old_meta = c.cl_meta in let process_meta csup = List.iter (fun m -> @@ -638,7 +637,7 @@ let check_final_vars ctx e = | _ -> () in - loop ctx.curclass; + loop ctx.c.curclass; if Hashtbl.length final_vars > 0 then begin let rec find_inits e = match e.eexpr with | TBinop(OpAssign,{eexpr = TField({eexpr = TConst TThis},fa)},e2) -> @@ -649,7 +648,7 @@ let check_final_vars ctx e = in find_inits e; if Hashtbl.length final_vars > 0 then - display_error ctx.com "Some final fields are uninitialized in this class" ctx.curclass.cl_name_pos; + display_error ctx.com "Some final fields are uninitialized in this class" ctx.c.curclass.cl_name_pos; DynArray.iter (fun (c,cf) -> if Hashtbl.mem final_vars cf.cf_name then display_error ~depth:1 ctx.com "Uninitialized field" cf.cf_name_pos diff --git a/src/typing/typeloadFields.ml b/src/typing/typeloadFields.ml index 80a2b395657..1c335511c76 100644 --- a/src/typing/typeloadFields.ml +++ b/src/typing/typeloadFields.ml @@ -31,7 +31,7 @@ open Common open Error type class_init_ctx = { - tclass : tclass; (* I don't trust ctx.curclass because it's mutable. *) + tclass : tclass; (* I don't trust ctx.c.curclass because it's mutable. *) is_lib : bool; is_native : bool; is_core_api : bool; @@ -466,10 +466,10 @@ let build_module_def ctx mt meta fvars fbuild = raise_typing_error "Invalid macro path" p in if ctx.com.is_macro_context then raise_typing_error "You cannot use @:build inside a macro : make sure that your type is not used in macro" p; - let old = ctx.get_build_infos in - ctx.get_build_infos <- (fun() -> Some (mt, extract_param_types (t_infos mt).mt_params, fvars())); - let r = try ctx.g.do_macro ctx MBuild cpath meth el p with e -> ctx.get_build_infos <- old; raise e in - ctx.get_build_infos <- old; + let old = ctx.c.get_build_infos in + ctx.c.get_build_infos <- (fun() -> Some (mt, extract_param_types (t_infos mt).mt_params, fvars())); + let r = try ctx.g.do_macro ctx MBuild cpath meth el p with e -> ctx.c.get_build_infos <- old; raise e in + ctx.c.get_build_infos <- old; (match r with | MError | MMacroInMacro -> raise_typing_error "Build failure" p | MSuccess e -> fbuild e) @@ -554,19 +554,7 @@ let create_typer_context_for_class ctx cctx p = let c = cctx.tclass in if cctx.is_lib && not (has_class_flag c CExtern) then ctx.com.error "@:libType can only be used in extern classes" c.cl_pos; if Meta.has Meta.Macro c.cl_meta then display_error ctx.com "Macro classes are no longer allowed in haxe 3" c.cl_pos; - let ctx = { - ctx with - curclass = c; - type_params = (match c.cl_kind with KAbstractImpl a -> a.a_params | _ -> c.cl_params); - pass = PBuildClass; - tthis = (match cctx.abstract with - | Some a -> - (match a.a_this with - | TMono r when r.tm_type = None -> TAbstract (a,extract_param_types c.cl_params) - | t -> t) - | None -> TInst (c,extract_param_types c.cl_params)); - } in - ctx + TyperManager.clone_for_class ctx c let create_field_context ctx cctx cff is_display_file display_modifier = let is_static = List.mem_assoc AStatic cff.cff_access in @@ -627,17 +615,9 @@ let create_field_context ctx cctx cff is_display_file display_modifier = fctx let create_typer_context_for_field ctx cctx fctx cff = - DeprecationCheck.check_is ctx.com ctx.m.curmod ctx.curclass.cl_meta cff.cff_meta (fst cff.cff_name) cff.cff_meta (snd cff.cff_name); - let ctx = { - ctx with - pass = PBuildClass; (* will be set later to PTypeExpr *) - locals = PMap.empty; - opened = []; - monomorphs = { - perfunction = []; - }; - type_params = if fctx.is_static && not fctx.is_abstract_member && not (Meta.has Meta.LibType cctx.tclass.cl_meta) (* TODO: remove this *) then [] else ctx.type_params; - } in + DeprecationCheck.check_is ctx.com ctx.m.curmod ctx.c.curclass.cl_meta cff.cff_meta (fst cff.cff_name) cff.cff_meta (snd cff.cff_name); + let params = if fctx.is_static && not fctx.is_abstract_member && not (Meta.has Meta.LibType cctx.tclass.cl_meta) (* TODO: remove this *) then [] else ctx.type_params in + let ctx = TyperManager.clone_for_field ctx null_field params in let c = cctx.tclass in if (fctx.is_abstract && not (has_meta Meta.LibType c.cl_meta)) then begin @@ -696,7 +676,7 @@ let transform_field (ctx,cctx) c f fields p = f let type_var_field ctx t e stat do_display p = - if stat then ctx.curfun <- FunStatic else ctx.curfun <- FunMember; + if stat then ctx.e.curfun <- FunStatic else ctx.e.curfun <- FunMember; let e = if do_display then Display.preprocess_expr ctx.com e else e in let e = type_expr ctx e (WithType.with_type t) in let e = AbstractCast.cast_or_unify ctx t e p in @@ -850,7 +830,7 @@ module TypeBinding = struct let r = make_lazy ~force:false ctx t (fun r -> (* type constant init fields (issue #1956) *) if not ctx.g.return_partial_type || (match fst e with EConst _ -> true | _ -> false) then begin - enter_field_typing_pass ctx ("bind_var_expression",fst ctx.curclass.cl_path @ [snd ctx.curclass.cl_path;ctx.curfield.cf_name]); + enter_field_typing_pass ctx ("bind_var_expression",fst ctx.c.curclass.cl_path @ [snd ctx.c.curclass.cl_path;ctx.f.curfield.cf_name]); if (Meta.has (Meta.Custom ":debug.typing") (c.cl_meta @ cf.cf_meta)) then ctx.com.print (Printf.sprintf "Typing field %s.%s\n" (s_type_path c.cl_path) cf.cf_name); let e = type_var_field ctx t e fctx.is_static fctx.is_display_field p in let maybe_run_analyzer e = match e.eexpr with @@ -880,7 +860,7 @@ module TypeBinding = struct | TConst TThis -> display_error ctx.com "Cannot access this or other member field in variable initialization" e.epos; raise Exit - | TLocal v when (match ctx.vthis with Some v2 -> v == v2 | None -> false) -> + | TLocal v when (match ctx.f.vthis with Some v2 -> v == v2 | None -> false) -> display_error ctx.com "Cannot access this or other member field in variable initialization" e.epos; raise Exit | _ -> @@ -1031,7 +1011,7 @@ let create_variable (ctx,cctx,fctx) c f t eo p = add_class_field_flag cf CfImpl; end; if is_abstract_enum_field then add_class_field_flag cf CfEnum; - ctx.curfield <- cf; + ctx.f.curfield <- cf; TypeBinding.bind_var ctx cctx fctx cf eo; cf @@ -1274,7 +1254,7 @@ let setup_args_ret ctx cctx fctx name fd p = | _ -> None in - let is_extern = fctx.is_extern || has_class_flag ctx.curclass CExtern in + let is_extern = fctx.is_extern || has_class_flag ctx.c.curclass CExtern in let type_arg i opt cto p = let def () = type_opt (ctx,cctx,fctx) p cto @@ -1341,7 +1321,7 @@ let create_method (ctx,cctx,fctx) c f fd p = begin match fd.f_type with | None -> () | Some (CTPath ({ path = {tpackage = []; tname = "Void" } as tp}),p) -> - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in p then + if ctx.m.is_display_file && DisplayPosition.display_position#enclosed_in p then ignore(load_instance ~allow_display:true ctx (make_ptp tp p) ParamNormal); | _ -> raise_typing_error "A class constructor can't have a return type" p; end @@ -1386,7 +1366,7 @@ let create_method (ctx,cctx,fctx) c f fd p = | Some p -> begin match ctx.com.platform with | Java -> - if not (has_class_flag ctx.curclass CExtern) || not (has_class_flag c CInterface) then invalid_modifier_only ctx.com fctx "default" "on extern interfaces" p; + if not (has_class_flag ctx.c.curclass CExtern) || not (has_class_flag c CInterface) then invalid_modifier_only ctx.com fctx "default" "on extern interfaces" p; add_class_field_flag cf CfDefault; | _ -> invalid_modifier_only ctx.com fctx "default" "on the Java target" p @@ -1428,7 +1408,7 @@ let create_method (ctx,cctx,fctx) c f fd p = () end; init_meta_overloads ctx (Some c) cf; - ctx.curfield <- cf; + ctx.f.curfield <- cf; if fctx.do_bind then TypeBinding.bind_method ctx cctx fctx cf t args ret fd.f_expr (match fd.f_expr with Some e -> snd e | None -> f.cff_pos) else begin @@ -1586,7 +1566,7 @@ let create_property (ctx,cctx,fctx) c f (get,set,t,eo) p = cf.cf_kind <- Var { v_read = get; v_write = set }; if fctx.is_extern then add_class_field_flag cf CfExtern; if List.mem_assoc AEnum f.cff_access then add_class_field_flag cf CfEnum; - ctx.curfield <- cf; + ctx.f.curfield <- cf; TypeBinding.bind_var ctx cctx fctx cf eo; cf @@ -1694,7 +1674,7 @@ let check_overloads ctx c = List.iter check_field c.cl_ordered_statics; Option.may check_field c.cl_constructor -let finalize_class ctx cctx = +let finalize_class cctx = (* push delays in reverse order so they will be run in correct order *) List.iter (fun (ctx,r) -> init_class_done ctx; @@ -1727,19 +1707,18 @@ let check_functional_interface ctx c = add_class_flag c CFunctionalInterface; ctx.g.functional_interface_lut#add c.cl_path cf -let init_class ctx c p herits fields = - let cctx = create_class_context c p in - let ctx = create_typer_context_for_class ctx cctx p in +let init_class ctx_c cctx c p herits fields = + let com = ctx_c.com in if cctx.is_class_debug then print_endline ("Created class context: " ^ dump_class_context cctx); - let fields = patch_class ctx c fields in - let fields = build_fields (ctx,cctx) c fields in - if cctx.is_core_api && ctx.com.display.dms_check_core_api then delay ctx PForce (fun() -> init_core_api ctx c); + let fields = patch_class ctx_c c fields in + let fields = build_fields (ctx_c,cctx) c fields in + if cctx.is_core_api && com.display.dms_check_core_api then delay ctx_c PForce (fun() -> init_core_api ctx_c c); if not cctx.is_lib then begin - delay ctx PForce (fun() -> check_overloads ctx c); + delay ctx_c PForce (fun() -> check_overloads ctx_c c); begin match c.cl_super with | Some(csup,tl) -> if (has_class_flag csup CAbstract) && not (has_class_flag c CAbstract) then - delay ctx PForce (fun () -> TypeloadCheck.Inheritance.check_abstract_class ctx c csup tl); + delay ctx_c PForce (fun () -> TypeloadCheck.Inheritance.check_abstract_class ctx_c c csup tl); | None -> () end @@ -1760,7 +1739,7 @@ let init_class ctx c p herits fields = | EBinop ((OpEq|OpNotEq|OpGt|OpGte|OpLt|OpLte) as op,(EConst (Ident s),_),(EConst ((Int (_,_) | Float (_,_) | String _) as c),_)) -> s ^ s_binop op ^ s_constant c | _ -> "" in - if not (ParserEntry.is_true (ParserEntry.eval ctx.com.defines e)) then + if not (ParserEntry.is_true (ParserEntry.eval com.defines e)) then Some (sc,(match List.rev l with (EConst (String(msg,_)),_) :: _ -> Some msg | _ -> None)) else loop l @@ -1773,10 +1752,10 @@ let init_class ctx c p herits fields = let has_init = ref false in List.iter (fun f -> let p = f.cff_pos in + let display_modifier = Typeload.check_field_access ctx_c f in + let fctx = create_field_context ctx_c cctx f ctx_c.m.is_display_file display_modifier in + let ctx = create_typer_context_for_field ctx_c cctx fctx f in try - let display_modifier = Typeload.check_field_access ctx f in - let fctx = create_field_context ctx cctx f ctx.is_display_file display_modifier in - let ctx = create_typer_context_for_field ctx cctx fctx f in if fctx.is_field_debug then print_endline ("Created field context: " ^ dump_field_context fctx); let cf = init_field (ctx,cctx,fctx) f in if fctx.field_kind = CfrInit then begin @@ -1842,7 +1821,7 @@ let init_class ctx c p herits fields = with Error ({ err_message = Custom _; err_pos = p2 } as err) when p = p2 -> display_error_ext ctx.com err ) fields; - begin match cctx.abstract with + begin match cctx.abstract with | Some a -> a.a_to_field <- List.rev a.a_to_field; a.a_from_field <- List.rev a.a_from_field; @@ -1850,11 +1829,11 @@ let init_class ctx c p herits fields = a.a_unops <- List.rev a.a_unops; a.a_array <- List.rev a.a_array; | None -> - if (has_class_flag c CInterface) && ctx.com.platform = Java then check_functional_interface ctx c; + if (has_class_flag c CInterface) && com.platform = Java then check_functional_interface ctx_c c; end; c.cl_ordered_statics <- List.rev c.cl_ordered_statics; c.cl_ordered_fields <- List.rev c.cl_ordered_fields; - delay ctx PConnectField (fun () -> match follow c.cl_type with + delay ctx_c PConnectField (fun () -> match follow c.cl_type with | TAnon an -> an.a_fields <- c.cl_statics | _ -> @@ -1872,28 +1851,28 @@ let init_class ctx c p herits fields = in if has_struct_init then if (has_class_flag c CInterface) then - display_error ctx.com "@:structInit is not allowed on interfaces" struct_init_pos + display_error com "@:structInit is not allowed on interfaces" struct_init_pos else - ensure_struct_init_constructor ctx c fields p; + ensure_struct_init_constructor ctx_c c fields p; begin match cctx.uninitialized_final with | cf :: cfl when c.cl_constructor = None && not (has_class_flag c CAbstract) -> - if Diagnostics.error_in_diagnostics_run ctx.com cf.cf_name_pos then begin + if Diagnostics.error_in_diagnostics_run com cf.cf_name_pos then begin let diag = { mf_pos = c.cl_name_pos; mf_on = TClassDecl c; mf_fields = []; mf_cause = FinalFields (cf :: cfl); } in - let display = ctx.com.display_information in + let display = com.display_information in display.module_diagnostics <- MissingFields diag :: display.module_diagnostics end else begin - display_error ctx.com "This class has uninitialized final vars, which requires a constructor" p; - display_error ctx.com "Example of an uninitialized final var" cf.cf_name_pos; + display_error com "This class has uninitialized final vars, which requires a constructor" p; + display_error com "Example of an uninitialized final var" cf.cf_name_pos; end | _ -> () end; if not has_struct_init then (* add_constructor does not deal with overloads correctly *) - if not ctx.com.config.pf_overload then TypeloadFunction.add_constructor ctx c cctx.force_constructor p; - finalize_class ctx cctx + if not com.config.pf_overload then TypeloadFunction.add_constructor ctx_c c cctx.force_constructor p; + finalize_class cctx diff --git a/src/typing/typeloadFunction.ml b/src/typing/typeloadFunction.ml index 07c06f2e9d5..d3dff29cd54 100644 --- a/src/typing/typeloadFunction.ml +++ b/src/typing/typeloadFunction.ml @@ -28,32 +28,25 @@ open Error open FunctionArguments let save_field_state ctx = - let old_ret = ctx.ret in - let old_fun = ctx.curfun in - let old_opened = ctx.opened in - let old_monos = ctx.monomorphs.perfunction in - let old_in_function = ctx.in_function in - let locals = ctx.locals in + let old_e = ctx.e in + ctx.e <- TyperManager.create_ctx_e (); + let locals = ctx.f.locals in (fun () -> - ctx.locals <- locals; - ctx.ret <- old_ret; - ctx.curfun <- old_fun; - ctx.opened <- old_opened; - ctx.monomorphs.perfunction <- old_monos; - ctx.in_function <- old_in_function; + ctx.f.locals <- locals; + ctx.e <- old_e; ) let type_function_params ctx fd host fname p = Typeload.type_type_params ctx host ([],fname) p fd.f_params let type_function ctx (args : function_arguments) ret fmode e do_display p = - ctx.in_function <- true; - ctx.curfun <- fmode; - ctx.ret <- ret; - ctx.opened <- []; - ctx.monomorphs.perfunction <- []; - enter_field_typing_pass ctx ("type_function",fst ctx.curclass.cl_path @ [snd ctx.curclass.cl_path;ctx.curfield.cf_name]); - args#bring_into_context; + ctx.e.in_function <- true; + ctx.e.curfun <- fmode; + ctx.e.ret <- ret; + ctx.e.opened <- []; + ctx.e.monomorphs.perfunction <- []; + enter_field_typing_pass ctx ("type_function",fst ctx.c.curclass.cl_path @ [snd ctx.c.curclass.cl_path;ctx.f.curfield.cf_name]); + args#bring_into_context ctx; let e = match e with | None -> if ignore_error ctx.com then @@ -63,18 +56,18 @@ let type_function ctx (args : function_arguments) ret fmode e do_display p = *) EBlock [],p else - if fmode = FunMember && has_class_flag ctx.curclass CAbstract then + if fmode = FunMember && has_class_flag ctx.c.curclass CAbstract then raise_typing_error "Function body or abstract modifier required" p else raise_typing_error "Function body required" p | Some e -> e in - let is_position_debug = Meta.has (Meta.Custom ":debug.position") ctx.curfield.cf_meta in + let is_position_debug = Meta.has (Meta.Custom ":debug.position") ctx.f.curfield.cf_meta in let e = if not do_display then begin if is_position_debug then print_endline ("syntax:\n" ^ (Expr.dump_with_pos e)); type_expr ctx e NoValue end else begin - let is_display_debug = Meta.has (Meta.Custom ":debug.display") ctx.curfield.cf_meta in + let is_display_debug = Meta.has (Meta.Custom ":debug.display") ctx.f.curfield.cf_meta in if is_display_debug then print_endline ("before processing:\n" ^ (Expr.dump_with_pos e)); let e = if !Parser.had_resume then e else Display.preprocess_expr ctx.com e in if is_display_debug then print_endline ("after processing:\n" ^ (Expr.dump_with_pos e)); @@ -110,7 +103,7 @@ let type_function ctx (args : function_arguments) ret fmode e do_display p = | _ -> Type.iter loop e in let has_super_constr() = - match ctx.curclass.cl_super with + match ctx.c.curclass.cl_super with | None -> None | Some (csup,tl) -> @@ -141,9 +134,9 @@ let type_function ctx (args : function_arguments) ret fmode e do_display p = | None -> e end in - let e = match ctx.curfun, ctx.vthis with + let e = match ctx.e.curfun, ctx.f.vthis with | (FunMember|FunConstructor), Some v -> - let ev = mk (TVar (v,Some (mk (TConst TThis) ctx.tthis p))) ctx.t.tvoid p in + let ev = mk (TVar (v,Some (mk (TConst TThis) ctx.c.tthis p))) ctx.t.tvoid p in (match e.eexpr with | TBlock l -> if ctx.com.config.pf_this_before_super then @@ -168,8 +161,8 @@ let type_function ctx (args : function_arguments) ret fmode e do_display p = | _ -> mk (TBlock [ev;e]) e.etype p) | _ -> e in - List.iter (fun r -> r := Closed) ctx.opened; - List.iter (fun (m,p) -> safe_mono_close ctx m p) ctx.monomorphs.perfunction; + List.iter (fun r -> r := Closed) ctx.e.opened; + List.iter (fun (m,p) -> safe_mono_close ctx m p) ctx.e.monomorphs.perfunction; if is_position_debug then print_endline ("typing:\n" ^ (Texpr.dump_with_pos "" e)); e @@ -177,7 +170,7 @@ let type_function ctx args ret fmode e do_display p = let save = save_field_state ctx in Std.finally save (type_function ctx args ret fmode e do_display) p -let add_constructor ctx c force_constructor p = +let add_constructor ctx_c c force_constructor p = if c.cl_constructor <> None then () else let constructor = try Some (Type.get_constructor_class c (extract_param_types c.cl_params)) with Not_found -> None in match constructor with @@ -186,12 +179,9 @@ let add_constructor ctx c force_constructor p = cf.cf_kind <- cfsup.cf_kind; cf.cf_params <- cfsup.cf_params; cf.cf_meta <- List.filter (fun (m,_,_) -> m = Meta.CompilerGenerated) cfsup.cf_meta; - let t = spawn_monomorph ctx p in - let r = make_lazy ctx t (fun r -> - let ctx = { ctx with - curfield = cf; - pass = PConnectField; - } in + let t = spawn_monomorph ctx_c.e p in + let r = make_lazy ctx_c t (fun r -> + let ctx = TyperManager.clone_for_field ctx_c cf cf.cf_params in ignore (follow cfsup.cf_type); (* make sure it's typed *) List.iter (fun cf -> ignore (follow cf.cf_type)) cf.cf_overloads; let map_arg (v,def) = @@ -242,9 +232,9 @@ let add_constructor ctx c force_constructor p = | _ when force_constructor -> let constr = mk (TFunction { tf_args = []; - tf_type = ctx.t.tvoid; - tf_expr = mk (TBlock []) ctx.t.tvoid p; - }) (tfun [] ctx.t.tvoid) p in + tf_type = ctx_c.t.tvoid; + tf_expr = mk (TBlock []) ctx_c.t.tvoid p; + }) (tfun [] ctx_c.t.tvoid) p in let cf = mk_field "new" constr.etype p null_pos in cf.cf_expr <- Some constr; cf.cf_type <- constr.etype; diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 697cc2f581e..1966c5eb1d5 100644 --- a/src/typing/typeloadModule.ml +++ b/src/typing/typeloadModule.ml @@ -44,30 +44,30 @@ let field_of_static_definition d p = } module ModuleLevel = struct - let make_module ctx mpath file loadp = + let make_module com g mpath file loadp = let m = { m_id = alloc_mid(); m_path = mpath; m_types = []; m_statics = None; - m_extra = module_extra (Path.get_full_path file) (Define.get_signature ctx.com.defines) (file_time file) (if ctx.com.is_macro_context then MMacro else MCode) ctx.com.compilation_step (get_policy ctx.g mpath); + m_extra = module_extra (Path.get_full_path file) (Define.get_signature com.defines) (file_time file) (if com.is_macro_context then MMacro else MCode) com.compilation_step (get_policy g mpath); } in m - let add_module ctx m p = - ctx.com.module_lut#add m.m_path m + let add_module com m p = + com.module_lut#add m.m_path m (* Build module structure : should be atomic - no type loading is possible *) - let create_module_types ctx m tdecls loadp = - let com = ctx.com in + let create_module_types ctx_m m tdecls loadp = + let com = ctx_m.com in let decls = ref [] in let statics = ref [] in let check_name name meta also_statics p = - DeprecationCheck.check_is com ctx.m.curmod meta [] name meta p; + DeprecationCheck.check_is com ctx_m.m.curmod meta [] name meta p; let error prev_pos = - display_error ctx.com ("Name " ^ name ^ " is already defined in this module") p; + display_error com ("Name " ^ name ^ " is already defined in this module") p; raise_typing_error ~depth:1 (compl_msg "Previous declaration here") prev_pos; in List.iter (fun (t2,(_,p2)) -> @@ -87,7 +87,7 @@ module ModuleLevel = struct let p = snd decl in let check_type_name type_name meta = let module_name = snd m.m_path in - if type_name <> module_name && not (Meta.has Meta.Native meta) then Typecore.check_uppercase_identifier_name ctx type_name "type" p; + if type_name <> module_name && not (Meta.has Meta.Native meta) then Typecore.check_uppercase_identifier_name ctx_m type_name "type" p; in let acc = (match fst decl with | EImport _ | EUsing _ -> @@ -119,8 +119,8 @@ module ModuleLevel = struct ) d.d_flags; if not (has_class_flag c CExtern) then check_type_name name d.d_meta; if has_class_flag c CAbstract then begin - if has_class_flag c CInterface then display_error ctx.com "An interface may not be abstract" c.cl_name_pos; - if has_class_flag c CFinal then display_error ctx.com "An abstract class may not be final" c.cl_name_pos; + if has_class_flag c CInterface then display_error com "An interface may not be abstract" c.cl_name_pos; + if has_class_flag c CFinal then display_error com "An abstract class may not be final" c.cl_name_pos; end; decls := (TClassDecl c, decl) :: !decls; acc @@ -152,7 +152,7 @@ module ModuleLevel = struct t_meta = d.d_meta; } in (* failsafe in case the typedef is not initialized (see #3933) *) - delay ctx PBuildModule (fun () -> + delay ctx_m PBuildModule (fun () -> match t.t_type with | TMono r -> (match r.tm_type with None -> Monomorph.bind r com.basic.tvoid | _ -> ()) | _ -> () @@ -195,7 +195,7 @@ module ModuleLevel = struct | None -> () | Some p -> let options = Warning.from_meta d.d_meta in - module_warning ctx.com ctx.m.curmod WDeprecatedEnumAbstract options "`@:enum abstract` is deprecated in favor of `enum abstract`" p + module_warning com ctx_m.m.curmod WDeprecatedEnumAbstract options "`@:enum abstract` is deprecated in favor of `enum abstract`" p end; decls := (TAbstractDecl a, decl) :: !decls; match d.d_data with @@ -267,8 +267,7 @@ module ModuleLevel = struct let decls = List.rev !decls in decls, List.rev tdecls - let handle_import_hx ctx m decls p = - let com = ctx.com in + let handle_import_hx com g m decls p = let path_split = match List.rev (Path.get_path_parts (Path.UniqueKey.lazy_path m.m_extra.m_file)) with | [] -> [] | _ :: l -> l @@ -283,7 +282,7 @@ module ModuleLevel = struct let make_import_module path r = com.parser_cache#add path r; (* We use the file path as module name to make it unique. This may or may not be a good idea... *) - let m_import = make_module ctx ([],path) path p in + let m_import = make_module com g ([],path) path p in m_import.m_extra.m_kind <- MImport; m_import in @@ -295,13 +294,13 @@ module ModuleLevel = struct r with Not_found -> if Sys.file_exists path then begin - let _,r = match !TypeloadParse.parse_hook com (ClassPaths.create_resolved_file path ctx.com.empty_class_path) p with + let _,r = match !TypeloadParse.parse_hook com (ClassPaths.create_resolved_file path com.empty_class_path) p with | ParseSuccess(data,_,_) -> data | ParseError(_,(msg,p),_) -> Parser.error msg p in List.iter (fun (d,p) -> match d with EImport _ | EUsing _ -> () | _ -> raise_typing_error "Only import and using is allowed in import.hx files" p) r; let m_import = make_import_module path r in - add_module ctx m_import p; + add_module com m_import p; add_dependency m m_import; r end else begin @@ -314,39 +313,39 @@ module ModuleLevel = struct decls @ acc ) decls candidates - let init_type_params ctx decls = + let init_type_params ctx_m decls = (* here is an additional PASS 1 phase, which define the type parameters for all module types. Constraints are handled lazily (no other type is loaded) because they might be recursive anyway *) List.iter (fun d -> match d with | (TClassDecl c, (EClass d, p)) -> - c.cl_params <- type_type_params ctx TPHType c.cl_path p d.d_params; + c.cl_params <- type_type_params ctx_m TPHType c.cl_path p d.d_params; if Meta.has Meta.Generic c.cl_meta && c.cl_params <> [] then c.cl_kind <- KGeneric; if Meta.has Meta.GenericBuild c.cl_meta then begin - if ctx.com.is_macro_context then raise_typing_error "@:genericBuild cannot be used in macros" c.cl_pos; + if ctx_m.com.is_macro_context then raise_typing_error "@:genericBuild cannot be used in macros" c.cl_pos; c.cl_kind <- KGenericBuild d.d_data; end; if c.cl_path = (["haxe";"macro"],"MacroType") then c.cl_kind <- KMacroType; | (TEnumDecl e, (EEnum d, p)) -> - e.e_params <- type_type_params ctx TPHType e.e_path p d.d_params; + e.e_params <- type_type_params ctx_m TPHType e.e_path p d.d_params; | (TTypeDecl t, (ETypedef d, p)) -> - t.t_params <- type_type_params ctx TPHType t.t_path p d.d_params; + t.t_params <- type_type_params ctx_m TPHType t.t_path p d.d_params; | (TAbstractDecl a, (EAbstract d, p)) -> - a.a_params <- type_type_params ctx TPHType a.a_path p d.d_params; + a.a_params <- type_type_params ctx_m TPHType a.a_path p d.d_params; | _ -> die "" __LOC__ ) decls end module TypeLevel = struct - let load_enum_field ctx e et is_flat index c = + let load_enum_field ctx_en e et is_flat index c = let p = c.ec_pos in - let params = type_type_params ctx TPHEnumConstructor ([],fst c.ec_name) c.ec_pos c.ec_params in - let ctx = { ctx with type_params = params @ ctx.type_params } in + let params = type_type_params ctx_en TPHEnumConstructor ([],fst c.ec_name) c.ec_pos c.ec_params in + let ctx_ef = TyperManager.clone_for_enum_field ctx_en (params @ ctx_en.type_params) in let rt = (match c.ec_type with | None -> et | Some (t,pt) -> - let t = load_complex_type ctx true (t,pt) in + let t = load_complex_type ctx_ef true (t,pt) in (match follow t with | TEnum (te,_) when te == e -> () @@ -363,7 +362,7 @@ module TypeLevel = struct (match t with CTPath({path = {tpackage=[];tname="Void"}}) -> raise_typing_error "Arguments of type Void are not allowed in enum constructors" tp | _ -> ()); if PMap.mem s (!pnames) then raise_typing_error ("Duplicate argument `" ^ s ^ "` in enum constructor " ^ fst c.ec_name) p; pnames := PMap.add s () (!pnames); - s, opt, load_type_hint ~opt ctx p (Some (t,tp)) + s, opt, load_type_hint ~opt ctx_ef p (Some (t,tp)) ) l, rt) ) in let f = { @@ -376,44 +375,46 @@ module TypeLevel = struct ef_params = params; ef_meta = c.ec_meta; } in - DeprecationCheck.check_is ctx.com ctx.m.curmod e.e_meta f.ef_meta f.ef_name f.ef_meta f.ef_name_pos; - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in f.ef_name_pos then - DisplayEmitter.display_enum_field ctx e f p; + DeprecationCheck.check_is ctx_ef.com ctx_ef.m.curmod e.e_meta f.ef_meta f.ef_name f.ef_meta f.ef_name_pos; + if ctx_ef.m.is_display_file && DisplayPosition.display_position#enclosed_in f.ef_name_pos then + DisplayEmitter.display_enum_field ctx_ef e f p; f - let init_class ctx c d p = - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then - DisplayEmitter.display_module_type ctx (match c.cl_kind with KAbstractImpl a -> TAbstractDecl a | _ -> TClassDecl c) (pos d.d_name); - TypeloadCheck.check_global_metadata ctx c.cl_meta (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None; + let init_class ctx_m c d p = + if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then + DisplayEmitter.display_module_type ctx_m (match c.cl_kind with KAbstractImpl a -> TAbstractDecl a | _ -> TClassDecl c) (pos d.d_name); + TypeloadCheck.check_global_metadata ctx_m c.cl_meta (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None; let herits = d.d_flags in List.iter (fun (m,_,p) -> if m = Meta.Final then begin add_class_flag c CFinal; end ) d.d_meta; - let prev_build_count = ref (ctx.g.build_count - 1) in + let prev_build_count = ref (ctx_m.g.build_count - 1) in let build() = c.cl_build <- (fun()-> Building [c]); - let fl = TypeloadCheck.Inheritance.set_heritance ctx c herits p in + let cctx = TypeloadFields.create_class_context c p in + let ctx_c = TypeloadFields.create_typer_context_for_class ctx_m cctx p in + let fl = TypeloadCheck.Inheritance.set_heritance ctx_c c herits p in let rec build() = c.cl_build <- (fun()-> Building [c]); try List.iter (fun f -> f()) fl; - TypeloadFields.init_class ctx c p d.d_flags d.d_data; + TypeloadFields.init_class ctx_c cctx c p d.d_flags d.d_data; c.cl_build <- (fun()-> Built); - ctx.g.build_count <- ctx.g.build_count + 1; + ctx_c.g.build_count <- ctx_c.g.build_count + 1; List.iter (fun tp -> ignore(follow tp.ttp_type)) c.cl_params; Built; with TypeloadCheck.Build_canceled state -> - c.cl_build <- make_pass ctx build; + c.cl_build <- make_pass ctx_c build; let rebuild() = - delay_late ctx PBuildClass (fun() -> ignore(c.cl_build())); + delay_late ctx_c PBuildClass (fun() -> ignore(c.cl_build())); in (match state with | Built -> die "" __LOC__ | Building cl -> - if ctx.g.build_count = !prev_build_count then raise_typing_error ("Loop in class building prevent compiler termination (" ^ String.concat "," (List.map (fun c -> s_type_path c.cl_path) cl) ^ ")") c.cl_pos; - prev_build_count := ctx.g.build_count; + if ctx_c.g.build_count = !prev_build_count then raise_typing_error ("Loop in class building prevent compiler termination (" ^ String.concat "," (List.map (fun c -> s_type_path c.cl_path) cl) ^ ")") c.cl_pos; + prev_build_count := ctx_c.g.build_count; rebuild(); Building (c :: cl) | BuildMacro f -> @@ -425,18 +426,16 @@ module TypeLevel = struct in build() in - ctx.curclass <- c; - c.cl_build <- make_pass ctx build; - ctx.curclass <- null_class; - delay ctx PBuildClass (fun() -> ignore(c.cl_build())); + c.cl_build <- make_pass ctx_m build; + delay ctx_m PBuildClass (fun() -> ignore(c.cl_build())); if Meta.has Meta.InheritDoc c.cl_meta then - delay ctx PConnectField (fun() -> InheritDoc.build_class_doc ctx c); - if (ctx.com.platform = Java || ctx.com.platform = Cs) && not (has_class_flag c CExtern) then - delay ctx PTypeField (fun () -> - let metas = StrictMeta.check_strict_meta ctx c.cl_meta in + delay ctx_m PConnectField (fun() -> InheritDoc.build_class_doc ctx_m c); + if (ctx_m.com.platform = Java || ctx_m.com.platform = Cs) && not (has_class_flag c CExtern) then + delay ctx_m PTypeField (fun () -> + let metas = StrictMeta.check_strict_meta ctx_m c.cl_meta in if metas <> [] then c.cl_meta <- metas @ c.cl_meta; let rec run_field cf = - let metas = StrictMeta.check_strict_meta ctx cf.cf_meta in + let metas = StrictMeta.check_strict_meta ctx_m cf.cf_meta in if metas <> [] then cf.cf_meta <- metas @ cf.cf_meta; List.iter run_field cf.cf_overloads in @@ -447,12 +446,12 @@ module TypeLevel = struct | _ -> () ) - let init_enum ctx e d p = - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then - DisplayEmitter.display_module_type ctx (TEnumDecl e) (pos d.d_name); - let ctx = { ctx with type_params = e.e_params } in - let h = (try Some (Hashtbl.find ctx.g.type_patches e.e_path) with Not_found -> None) in - TypeloadCheck.check_global_metadata ctx e.e_meta (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None; + let init_enum ctx_m e d p = + if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then + DisplayEmitter.display_module_type ctx_m (TEnumDecl e) (pos d.d_name); + let ctx_en = TyperManager.clone_for_enum ctx_m e in + let h = (try Some (Hashtbl.find ctx_en.g.type_patches e.e_path) with Not_found -> None) in + TypeloadCheck.check_global_metadata ctx_en e.e_meta (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None; (match h with | None -> () | Some (h,hcl) -> @@ -473,7 +472,7 @@ module TypeLevel = struct } ) (!constructs) in - TypeloadFields.build_module_def ctx (TEnumDecl e) e.e_meta get_constructs (fun (e,p) -> + TypeloadFields.build_module_def ctx_en (TEnumDecl e) e.e_meta get_constructs (fun (e,p) -> match e with | EVars [{ ev_type = Some (CTAnonymous fields,p); ev_expr = None }] -> constructs := List.map (fun f -> @@ -503,35 +502,35 @@ module TypeLevel = struct let is_flat = ref true in List.iter (fun c -> if PMap.mem (fst c.ec_name) e.e_constrs then raise_typing_error ("Duplicate constructor " ^ fst c.ec_name) (pos c.ec_name); - let f = load_enum_field ctx e et is_flat index c in + let f = load_enum_field ctx_en e et is_flat index c in e.e_constrs <- PMap.add f.ef_name f e.e_constrs; incr index; names := (fst c.ec_name) :: !names; if Meta.has Meta.InheritDoc f.ef_meta then - delay ctx PConnectField (fun() -> InheritDoc.build_enum_field_doc ctx f); + delay ctx_en PConnectField (fun() -> InheritDoc.build_enum_field_doc ctx_en f); ) (!constructs); e.e_names <- List.rev !names; e.e_extern <- e.e_extern; - unify ctx (TType(enum_module_type e,[])) e.e_type p; + unify ctx_en (TType(enum_module_type e,[])) e.e_type p; if !is_flat then e.e_meta <- (Meta.FlatEnum,[],null_pos) :: e.e_meta; if Meta.has Meta.InheritDoc e.e_meta then - delay ctx PConnectField (fun() -> InheritDoc.build_enum_doc ctx e); - if (ctx.com.platform = Java || ctx.com.platform = Cs) && not e.e_extern then - delay ctx PTypeField (fun () -> - let metas = StrictMeta.check_strict_meta ctx e.e_meta in + delay ctx_en PConnectField (fun() -> InheritDoc.build_enum_doc ctx_en e); + if (ctx_en.com.platform = Java || ctx_en.com.platform = Cs) && not e.e_extern then + delay ctx_en PTypeField (fun () -> + let metas = StrictMeta.check_strict_meta ctx_en e.e_meta in e.e_meta <- metas @ e.e_meta; PMap.iter (fun _ ef -> - let metas = StrictMeta.check_strict_meta ctx ef.ef_meta in + let metas = StrictMeta.check_strict_meta ctx_en ef.ef_meta in if metas <> [] then ef.ef_meta <- metas @ ef.ef_meta ) e.e_constrs ) - let init_typedef ctx t d p = - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then - DisplayEmitter.display_module_type ctx (TTypeDecl t) (pos d.d_name); - TypeloadCheck.check_global_metadata ctx t.t_meta (fun m -> t.t_meta <- m :: t.t_meta) t.t_module.m_path t.t_path None; - let ctx = { ctx with type_params = t.t_params } in - let tt = load_complex_type ctx true d.d_data in + let init_typedef ctx_m t d p = + if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then + DisplayEmitter.display_module_type ctx_m (TTypeDecl t) (pos d.d_name); + TypeloadCheck.check_global_metadata ctx_m t.t_meta (fun m -> t.t_meta <- m :: t.t_meta) t.t_module.m_path t.t_path None; + let ctx_td = TyperManager.clone_for_typedef ctx_m t in + let tt = load_complex_type ctx_td true d.d_data in let tt = (match fst d.d_data with | CTExtend _ -> tt | CTPath { path = {tpackage = ["haxe";"macro"]; tname = "MacroType" }} -> @@ -557,7 +556,7 @@ module TypeLevel = struct | _ -> () in - let r = make_lazy ctx tt (fun r -> + let r = make_lazy ctx_td tt (fun r -> check_rec tt; tt ) "typedef_rec_check" in @@ -570,25 +569,25 @@ module TypeLevel = struct | None -> Monomorph.bind r tt; | Some t' -> die (Printf.sprintf "typedef %s is already initialized to %s, but new init to %s was attempted" (s_type_path t.t_path) (s_type_kind t') (s_type_kind tt)) __LOC__); | _ -> die "" __LOC__); - TypeloadFields.build_module_def ctx (TTypeDecl t) t.t_meta (fun _ -> []) (fun _ -> ()); - if ctx.com.platform = Cs && t.t_meta <> [] then - delay ctx PTypeField (fun () -> - let metas = StrictMeta.check_strict_meta ctx t.t_meta in + TypeloadFields.build_module_def ctx_td (TTypeDecl t) t.t_meta (fun _ -> []) (fun _ -> ()); + if ctx_td.com.platform = Cs && t.t_meta <> [] then + delay ctx_td PTypeField (fun () -> + let metas = StrictMeta.check_strict_meta ctx_td t.t_meta in if metas <> [] then t.t_meta <- metas @ t.t_meta; ) - let init_abstract ctx a d p = - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then - DisplayEmitter.display_module_type ctx (TAbstractDecl a) (pos d.d_name); - TypeloadCheck.check_global_metadata ctx a.a_meta (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None; - let ctx = { ctx with type_params = a.a_params } in + let init_abstract ctx_m a d p = + if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then + DisplayEmitter.display_module_type ctx_m (TAbstractDecl a) (pos d.d_name); + TypeloadCheck.check_global_metadata ctx_m a.a_meta (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None; + let ctx_a = TyperManager.clone_for_abstract ctx_m a in let is_type = ref false in let load_type t from = let _, pos = t in - let t = load_complex_type ctx true t in + let t = load_complex_type ctx_a true t in let t = if not (Meta.has Meta.CoreType a.a_meta) then begin if !is_type then begin - let r = make_lazy ctx t (fun r -> + let r = make_lazy ctx_a t (fun r -> (try (if from then Type.unify t a.a_this else Type.unify a.a_this t) with Unify_error _ -> raise_typing_error "You can only declare from/to with compatible types" pos); t ) "constraint" in @@ -608,8 +607,8 @@ module TypeLevel = struct | AbOver t -> if a.a_impl = None then raise_typing_error "Abstracts with underlying type must have an implementation" a.a_pos; if Meta.has Meta.CoreType a.a_meta then raise_typing_error "@:coreType abstracts cannot have an underlying type" p; - let at = load_complex_type ctx true t in - delay ctx PForce (fun () -> + let at = load_complex_type ctx_a true t in + delay ctx_a PForce (fun () -> let rec loop stack t = match follow t with | TAbstract(a,_) when not (Meta.has Meta.CoreType a.a_meta) -> @@ -636,54 +635,55 @@ module TypeLevel = struct raise_typing_error "Abstract is missing underlying type declaration" a.a_pos end; if Meta.has Meta.InheritDoc a.a_meta then - delay ctx PConnectField (fun() -> InheritDoc.build_abstract_doc ctx a) + delay ctx_a PConnectField (fun() -> InheritDoc.build_abstract_doc ctx_a a) (* In this pass, we can access load and access other modules types, but we cannot follow them or access their structure since they have not been setup. We also build a list that will be evaluated the first time we evaluate an expression into the context *) - let init_module_type ctx (decl,p) = + let init_module_type ctx_m (decl,p) = + let com = ctx_m.com in let get_type name = - try List.find (fun t -> snd (t_infos t).mt_path = name) ctx.m.curmod.m_types with Not_found -> die "" __LOC__ + try List.find (fun t -> snd (t_infos t).mt_path = name) ctx_m.m.curmod.m_types with Not_found -> die "" __LOC__ in let check_path_display path p = - if DisplayPosition.display_position#is_in_file (ctx.com.file_keys#get p.pfile) then DisplayPath.handle_path_display ctx path p + if DisplayPosition.display_position#is_in_file (com.file_keys#get p.pfile) then DisplayPath.handle_path_display ctx_m path p in match decl with | EImport (path,mode) -> begin try check_path_display path p; - ImportHandling.init_import ctx path mode p; - ImportHandling.commit_import ctx path mode p; + ImportHandling.init_import ctx_m path mode p; + ImportHandling.commit_import ctx_m path mode p; with Error err -> - display_error_ext ctx.com err + display_error_ext com err end | EUsing path -> check_path_display path p; - ImportHandling.init_using ctx path p + ImportHandling.init_using ctx_m path p | EClass d -> let c = (match get_type (fst d.d_name) with TClassDecl c -> c | _ -> die "" __LOC__) in - init_class ctx c d p + init_class ctx_m c d p | EEnum d -> let e = (match get_type (fst d.d_name) with TEnumDecl e -> e | _ -> die "" __LOC__) in - init_enum ctx e d p + init_enum ctx_m e d p | ETypedef d -> let t = (match get_type (fst d.d_name) with TTypeDecl t -> t | _ -> die "" __LOC__) in - init_typedef ctx t d p + init_typedef ctx_m t d p | EAbstract d -> let a = (match get_type (fst d.d_name) with TAbstractDecl a -> a | _ -> die "" __LOC__) in - init_abstract ctx a d p + init_abstract ctx_m a d p | EStatic _ -> (* nothing to do here as module fields are collected into a special EClass *) () end -let make_curmod ctx m = +let make_curmod com g m = let rl = new resolution_list ["import";s_type_path m.m_path] in List.iter (fun mt -> rl#add (module_type_resolution mt None null_pos)) - (List.rev ctx.g.std_types.m_types); + (List.rev g.std_types.m_types); { curmod = m; import_resolution = rl; @@ -691,79 +691,43 @@ let make_curmod ctx m = enum_with_type = None; module_using = []; import_statements = []; - } - -let create_typer_context_for_module ctx m = { - com = ctx.com; - g = ctx.g; - t = ctx.com.basic; - m = make_curmod ctx m; - is_display_file = (ctx.com.display.dms_kind <> DMNone && DisplayPosition.display_position#is_in_file (Path.UniqueKey.lazy_key m.m_extra.m_file)); - bypass_accessor = 0; - meta = []; - with_type_stack = []; - call_argument_stack = []; - pass = PBuildModule; - get_build_infos = (fun() -> None); - macro_depth = 0; - curclass = null_class; - allow_inline = true; - allow_transform = true; - curfield = null_field; - tthis = mk_mono(); - ret = mk_mono(); - locals = PMap.empty; - type_params = []; - curfun = FunStatic; - untyped = false; - in_display = false; - in_function = false; - in_loop = false; - opened = []; - in_call_args = false; - in_overload_call_args = false; - delayed_display = None; - monomorphs = { - perfunction = []; - }; - vthis = None; - memory_marker = Typecore.memory_marker; + is_display_file = (com.display.dms_kind <> DMNone && DisplayPosition.display_position#is_in_file (Path.UniqueKey.lazy_key m.m_extra.m_file)); } (* Creates a module context for [m] and types [tdecls] using it. *) -let type_types_into_module ctx m tdecls p = - let ctx = create_typer_context_for_module ctx m in - let decls,tdecls = ModuleLevel.create_module_types ctx m tdecls p in +let type_types_into_module com g m tdecls p = + let ctx_m = TyperManager.create_for_module com g (make_curmod com g m) in + let decls,tdecls = ModuleLevel.create_module_types ctx_m m tdecls p in let types = List.map fst decls in (* During the initial module_lut#add in type_module, m has no m_types yet by design. We manually add them here. This and module_lut#add itself should be the only places in the compiler that call add_module_type. *) - List.iter (fun mt -> ctx.com.module_lut#add_module_type m mt) types; + List.iter (fun mt -> ctx_m.com.module_lut#add_module_type m mt) types; m.m_types <- m.m_types @ types; (* define the per-module context for the next pass *) - if ctx.g.std_types != null_module then begin - add_dependency m ctx.g.std_types; + if ctx_m.g.std_types != null_module then begin + add_dependency m ctx_m.g.std_types; (* this will ensure both String and (indirectly) Array which are basic types which might be referenced *) - ignore(load_instance ctx (make_ptp (mk_type_path (["std"],"String")) null_pos) ParamNormal) + ignore(load_instance ctx_m (make_ptp (mk_type_path (["std"],"String")) null_pos) ParamNormal) end; - ModuleLevel.init_type_params ctx decls; + ModuleLevel.init_type_params ctx_m decls; (* setup module types *) - List.iter (TypeLevel.init_module_type ctx) tdecls; + List.iter (TypeLevel.init_module_type ctx_m) tdecls; (* Make sure that we actually init the context at some point (issue #9012) *) - delay ctx PConnectField (fun () -> ctx.m.import_resolution#resolve_lazies); - ctx + delay ctx_m PConnectField (fun () -> ctx_m.m.import_resolution#resolve_lazies); + ctx_m (* Creates a new module and types [tdecls] into it. *) -let type_module ctx mpath file ?(dont_check_path=false) ?(is_extern=false) tdecls p = - let m = ModuleLevel.make_module ctx mpath file p in - ctx.com.module_lut#add m.m_path m; - let tdecls = ModuleLevel.handle_import_hx ctx m tdecls p in - let ctx = type_types_into_module ctx m tdecls p in - if is_extern then m.m_extra.m_kind <- MExtern else if not dont_check_path then Typecore.check_module_path ctx m.m_path p; +let type_module ctx_from mpath file ?(dont_check_path=false) ?(is_extern=false) tdecls p = + let m = ModuleLevel.make_module ctx_from.com ctx_from.g mpath file p in + ctx_from.com.module_lut#add m.m_path m; + let tdecls = ModuleLevel.handle_import_hx ctx_from.com ctx_from.g m tdecls p in + let ctx_m = type_types_into_module ctx_from.com ctx_from.g m tdecls p in + if is_extern then m.m_extra.m_kind <- MExtern else if not dont_check_path then Typecore.check_module_path ctx_m m.m_path p; m (* let type_module ctx mpath file ?(is_extern=false) tdecls p = @@ -778,7 +742,7 @@ class hxb_reader_api_typeload (p : pos) = object(self) method make_module (path : path) (file : string) = - let m = ModuleLevel.make_module ctx path file p in + let m = ModuleLevel.make_module ctx.com ctx.g path file p in m.m_extra.m_processed <- 1; m diff --git a/src/typing/typer.ml b/src/typing/typer.ml index 6fad5ed24a5..13aca40a8de 100644 --- a/src/typing/typer.ml +++ b/src/typing/typer.ml @@ -40,7 +40,7 @@ let mono_or_dynamic ctx with_type p = match with_type with | WithType.NoValue -> t_dynamic | Value _ | WithType _ -> - spawn_monomorph ctx p + spawn_monomorph ctx.e p let get_iterator_param t = match follow t with @@ -144,7 +144,7 @@ let maybe_type_against_enum ctx f with_type iscall p = let rec unify_min_raise ctx (el:texpr list) : t = let basic = ctx.com.basic in match el with - | [] -> spawn_monomorph ctx null_pos + | [] -> spawn_monomorph ctx.e null_pos | [e] -> e.etype | _ -> let rec chk_null e = is_null e.etype || is_explicit_null e.etype || @@ -172,7 +172,7 @@ let rec unify_min_raise ctx (el:texpr list) : t = with Unify_error _ -> true, t in - let has_error, t = loop (spawn_monomorph ctx null_pos) el in + let has_error, t = loop (spawn_monomorph ctx.e null_pos) el in if not has_error then t else try @@ -263,7 +263,7 @@ let rec unify_min_raise ctx (el:texpr list) : t = let unify_min ctx el = try unify_min_raise ctx el with Error ({ err_message = Unify l } as err) -> - if not ctx.untyped then display_error_ext ctx.com err; + if not ctx.f.untyped then display_error_ext ctx.com err; (List.hd el).etype let unify_min_for_type_source ctx el src = @@ -350,8 +350,8 @@ let rec type_ident_raise ctx i p mode with_type = let acc = AKExpr(get_this ctx p) in begin match mode with | MSet _ -> - add_class_field_flag ctx.curfield CfModifiesThis; - begin match ctx.curclass.cl_kind with + add_class_field_flag ctx.f.curfield CfModifiesThis; + begin match ctx.c.curclass.cl_kind with | KAbstractImpl _ -> if not (assign_to_this_is_allowed ctx) then raise_typing_error "Abstract 'this' value can only be modified inside an inline function" p; @@ -360,7 +360,7 @@ let rec type_ident_raise ctx i p mode with_type = AKNo(acc,p) end | MCall _ -> - begin match ctx.curclass.cl_kind with + begin match ctx.c.curclass.cl_kind with | KAbstractImpl _ -> acc | _ -> @@ -370,7 +370,7 @@ let rec type_ident_raise ctx i p mode with_type = acc end; | "abstract" -> - begin match mode, ctx.curclass.cl_kind with + begin match mode, ctx.c.curclass.cl_kind with | MSet _, KAbstractImpl ab -> raise_typing_error "Property 'abstract' is read-only" p; | (MGet, KAbstractImpl ab) | (MCall _, KAbstractImpl ab) -> @@ -382,11 +382,11 @@ let rec type_ident_raise ctx i p mode with_type = raise_typing_error "Property 'abstract' is reserved and only available in abstracts" p end | "super" -> - let t = (match ctx.curclass.cl_super with + let t = (match ctx.c.curclass.cl_super with | None -> raise_typing_error "Current class does not have a superclass" p | Some (c,params) -> TInst(c,params) ) in - (match ctx.curfun with + (match ctx.e.curfun with | FunMember | FunConstructor -> () | FunMemberAbstract -> raise_typing_error "Cannot access super inside an abstract function" p | FunStatic -> raise_typing_error "Cannot access super inside a static function" p; @@ -396,9 +396,9 @@ let rec type_ident_raise ctx i p mode with_type = let acc = (* Hack for #10787 *) if ctx.com.platform = Cs then - AKExpr (null (spawn_monomorph ctx p) p) + AKExpr (null (spawn_monomorph ctx.e p) p) else begin - let tnull () = ctx.t.tnull (spawn_monomorph ctx p) in + let tnull () = ctx.t.tnull (spawn_monomorph ctx.e p) in let t = match with_type with | WithType.WithType(t,_) -> begin match follow t with @@ -421,7 +421,7 @@ let rec type_ident_raise ctx i p mode with_type = if mode = MGet then acc else AKNo(acc,p) | _ -> try - let v = PMap.find i ctx.locals in + let v = PMap.find i ctx.f.locals in add_var_flag v VUsedByTyper; (match v.v_extra with | Some ve -> @@ -447,25 +447,25 @@ let rec type_ident_raise ctx i p mode with_type = AKExpr (mk (TLocal v) v.v_type p)) with Not_found -> try (* member variable lookup *) - if ctx.curfun = FunStatic then raise Not_found; - let c , t , f = class_field ctx ctx.curclass (extract_param_types ctx.curclass.cl_params) i p in + if ctx.e.curfun = FunStatic then raise Not_found; + let c , t , f = class_field ctx ctx.c.curclass (extract_param_types ctx.c.curclass.cl_params) i p in field_access ctx mode f (match c with None -> FHAnon | Some (c,tl) -> FHInstance (c,tl)) (get_this ctx p) p with Not_found -> try (* static variable lookup *) - let f = PMap.find i ctx.curclass.cl_statics in + let f = PMap.find i ctx.c.curclass.cl_statics in let is_impl = has_class_field_flag f CfImpl in let is_enum = has_class_field_flag f CfEnum in - if is_impl && not (has_class_field_flag ctx.curfield CfImpl) && not is_enum then + if is_impl && not (has_class_field_flag ctx.f.curfield CfImpl) && not is_enum then raise_typing_error (Printf.sprintf "Cannot access non-static field %s from static method" f.cf_name) p; - let e,fa = match ctx.curclass.cl_kind with + let e,fa = match ctx.c.curclass.cl_kind with | KAbstractImpl a when is_impl && not is_enum -> let tl = extract_param_types a.a_params in let e = get_this ctx p in let e = {e with etype = TAbstract(a,tl)} in - e,FHAbstract(a,tl,ctx.curclass) + e,FHAbstract(a,tl,ctx.c.curclass) | _ -> - let e = type_module_type ctx (TClassDecl ctx.curclass) p in - e,FHStatic ctx.curclass + let e = type_module_type ctx (TClassDecl ctx.c.curclass) p in + e,FHStatic ctx.c.curclass in field_access ctx mode f fa e p with Not_found -> try @@ -500,20 +500,20 @@ and type_ident ctx i p mode with_type = end else raise Not_found with Not_found -> - if ctx.untyped then begin + if ctx.f.untyped then begin if i = "__this__" then - AKExpr (mk (TConst TThis) ctx.tthis p) + AKExpr (mk (TConst TThis) ctx.c.tthis p) else let t = mk_mono() in AKExpr ((mk (TIdent i)) t p) end else begin - if ctx.curfun = FunStatic && PMap.mem i ctx.curclass.cl_fields then raise_typing_error ("Cannot access " ^ i ^ " in static function") p; + if ctx.e.curfun = FunStatic && PMap.mem i ctx.c.curclass.cl_fields then raise_typing_error ("Cannot access " ^ i ^ " in static function") p; if !resolved_to_type_parameter then begin display_error ctx.com ("Only @:const type parameters on @:generic classes can be used as value") p; AKExpr (mk (TConst TNull) t_dynamic p) end else begin let err = Unknown_ident i in - if ctx.in_display then begin + if ctx.f.in_display then begin raise_error_msg err p end; if Diagnostics.error_in_diagnostics_run ctx.com p then begin @@ -584,7 +584,7 @@ and handle_efield ctx e p0 mode with_type = end with Not_found -> (* if there was no module name part, last guess is that we're trying to get package completion *) - if ctx.in_display then begin + if ctx.f.in_display then begin let sl = List.map (fun part -> part.name) path in if is_legacy_completion ctx.com then raise (Parser.TypePath (sl,None,false,p)) @@ -707,15 +707,15 @@ and type_vars ctx vl p = let vl = List.map (fun ev -> let n = fst ev.ev_name and pv = snd ev.ev_name in - DeprecationCheck.check_is ctx.com ctx.m.curmod ctx.curclass.cl_meta ctx.curfield.cf_meta n ev.ev_meta pv; + DeprecationCheck.check_is ctx.com ctx.m.curmod ctx.c.curclass.cl_meta ctx.f.curfield.cf_meta n ev.ev_meta pv; try let t = Typeload.load_type_hint ctx p ev.ev_type in let e = (match ev.ev_expr with | None -> None | Some e -> - let old_in_loop = ctx.in_loop in - if ev.ev_static then ctx.in_loop <- false; - let e = Std.finally (fun () -> ctx.in_loop <- old_in_loop) (type_expr ctx e) (WithType.with_type t) in + let old_in_loop = ctx.e.in_loop in + if ev.ev_static then ctx.e.in_loop <- false; + let e = Std.finally (fun () -> ctx.e.in_loop <- old_in_loop) (type_expr ctx e) (WithType.with_type t) in let e = AbstractCast.cast_or_unify ctx t e p in Some e ) in @@ -728,7 +728,7 @@ and type_vars ctx vl p = DisplayEmitter.check_display_metadata ctx v.v_meta; if ev.ev_final then add_var_flag v VFinal; if ev.ev_static then add_var_flag v VStatic; - if ctx.in_display && DisplayPosition.display_position#enclosed_in pv then + if ctx.f.in_display && DisplayPosition.display_position#enclosed_in pv then DisplayEmitter.display_variable ctx v pv; v,e with @@ -751,7 +751,7 @@ and type_vars ctx vl p = and format_string ctx s p = FormatString.format_string ctx.com.defines s p (fun enext p -> - if ctx.in_display && DisplayPosition.display_position#enclosed_in p then + if ctx.f.in_display && DisplayPosition.display_position#enclosed_in p then Display.preprocess_expr ctx.com (enext,p) else enext,p @@ -823,7 +823,7 @@ and type_object_decl ctx fl with_type p = | None -> let cf = PMap.find n field_map in if (has_class_field_flag cf CfFinal) then is_final := true; - if ctx.in_display && DisplayPosition.display_position#enclosed_in pn then DisplayEmitter.display_field ctx Unknown CFSMember cf pn; + if ctx.f.in_display && DisplayPosition.display_position#enclosed_in pn then DisplayEmitter.display_field ctx Unknown CFSMember cf pn; cf.cf_type in let e = type_expr ctx e (WithType.with_structure_field t n) in @@ -844,7 +844,7 @@ and type_object_decl ctx fl with_type p = ((n,pn,qs),e) ) fl in let t = mk_anon ~fields:!fields (ref Const) in - if not ctx.untyped then begin + if not ctx.f.untyped then begin (match PMap.foldi (fun n cf acc -> if not (Meta.has Meta.Optional cf.cf_meta) && not (PMap.mem n !fields) then n :: acc else acc) field_map [] with | [] -> () | [n] -> raise_or_display ctx [Unify_custom ("Object requires field " ^ n)] p @@ -867,7 +867,7 @@ and type_object_decl ctx fl with_type p = let e = type_expr ctx e (WithType.named_structure_field f) in (match follow e.etype with TAbstract({a_path=[],"Void"},_) -> raise_typing_error "Fields of type Void are not allowed in structures" e.epos | _ -> ()); let cf = mk_field f e.etype (punion pf e.epos) pf in - if ctx.in_display && DisplayPosition.display_position#enclosed_in pf then DisplayEmitter.display_field ctx Unknown CFSMember cf pf; + if ctx.f.in_display && DisplayPosition.display_position#enclosed_in pf then DisplayEmitter.display_field ctx Unknown CFSMember cf pf; (((f,pf,qs),e) :: l, if is_valid then begin if starts_with f '$' then raise_typing_error "Field names starting with a dollar are not allowed" p; PMap.add f cf acc @@ -875,7 +875,7 @@ and type_object_decl ctx fl with_type p = in let fields , types = List.fold_left loop ([],PMap.empty) fl in let x = ref Const in - ctx.opened <- x :: ctx.opened; + ctx.e.opened <- x :: ctx.e.opened; mk (TObjectDecl (List.rev fields)) (mk_anon ~fields:types x) p in (match a with @@ -1017,11 +1017,11 @@ and type_new ctx ptp el with_type force_inline p = tl_or_monos info.build_params in let restore = - ctx.call_argument_stack <- el :: ctx.call_argument_stack; - ctx.with_type_stack <- with_type :: ctx.with_type_stack; + ctx.e.call_argument_stack <- el :: ctx.e.call_argument_stack; + ctx.e.with_type_stack <- with_type :: ctx.e.with_type_stack; (fun () -> - ctx.with_type_stack <- List.tl ctx.with_type_stack; - ctx.call_argument_stack <- List.tl ctx.call_argument_stack + ctx.e.with_type_stack <- List.tl ctx.e.with_type_stack; + ctx.e.call_argument_stack <- List.tl ctx.e.call_argument_stack ) in let t = try @@ -1122,12 +1122,12 @@ and type_try ctx e1 catches with_type p = check_unreachable acc1 t2 (pos e_ast); let locals = save_locals ctx in let v = add_local_with_origin ctx TVOCatchVariable v t pv in - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in pv then + if ctx.m.is_display_file && DisplayPosition.display_position#enclosed_in pv then DisplayEmitter.display_variable ctx v pv; let e = type_expr ctx e_ast with_type in (* If the catch position is the display position it means we get completion on the catch keyword or some punctuation. Otherwise we wouldn't reach this point. *) - if ctx.is_display_file && DisplayPosition.display_position#enclosed_in pc then ignore(TyperDisplay.display_expr ctx e_ast e DKMarked MGet with_type pc); + if ctx.m.is_display_file && DisplayPosition.display_position#enclosed_in pc then ignore(TyperDisplay.display_expr ctx e_ast e DKMarked MGet with_type pc); v.v_type <- t2; locals(); ((v,e) :: acc1),(e :: acc2) @@ -1153,11 +1153,11 @@ and type_map_declaration ctx e1 el with_type p = | TInst({cl_path=["haxe";"ds"],"IntMap"},[tv]) -> ctx.t.tint,tv,true | TInst({cl_path=["haxe";"ds"],"StringMap"},[tv]) -> ctx.t.tstring,tv,true | TInst({cl_path=["haxe";"ds"],("ObjectMap" | "EnumValueMap")},[tk;tv]) -> tk,tv,true - | _ -> spawn_monomorph ctx p,spawn_monomorph ctx p,false + | _ -> spawn_monomorph ctx.e p,spawn_monomorph ctx.e p,false in match with_type with | WithType.WithType(t,_) -> get_map_params t - | _ -> (spawn_monomorph ctx p,spawn_monomorph ctx p,false) + | _ -> (spawn_monomorph ctx.e p,spawn_monomorph ctx.e p,false) in let keys = Hashtbl.create 0 in let check_key e_key = @@ -1227,12 +1227,12 @@ and type_local_function ctx kind f with_type p = | None -> None,p | Some (v,pn) -> Some v,pn ) in - let old_tp,old_in_loop = ctx.type_params,ctx.in_loop in + let old_tp,old_in_loop = ctx.type_params,ctx.e.in_loop in ctx.type_params <- params @ ctx.type_params; - if not inline then ctx.in_loop <- false; + if not inline then ctx.e.in_loop <- false; let rt = Typeload.load_type_hint ctx p f.f_type in let type_arg _ opt t p = Typeload.load_type_hint ~opt ctx p t in - let args = new FunctionArguments.function_arguments ctx type_arg false ctx.in_display None f.f_args in + let args = new FunctionArguments.function_arguments ctx type_arg false ctx.f.in_display None f.f_args in let targs = args#for_type in let maybe_unify_arg t1 t2 = match follow t1 with @@ -1330,15 +1330,15 @@ and type_local_function ctx kind f with_type p = if params <> [] then v.v_extra <- Some (var_extra params None); Some v ) in - let curfun = match ctx.curfun with + let curfun = match ctx.e.curfun with | FunStatic -> FunStatic | FunMemberAbstract | FunMemberAbstractLocal -> FunMemberAbstractLocal | _ -> FunMemberClassLocal in - let e = TypeloadFunction.type_function ctx args rt curfun f.f_expr ctx.in_display p in + let e = TypeloadFunction.type_function ctx args rt curfun f.f_expr ctx.f.in_display p in ctx.type_params <- old_tp; - ctx.in_loop <- old_in_loop; + ctx.e.in_loop <- old_in_loop; let tf = { tf_args = args#for_expr; tf_type = rt; @@ -1351,7 +1351,7 @@ and type_local_function ctx kind f with_type p = Typeload.generate_args_meta ctx.com None (fun m -> v.v_meta <- m :: v.v_meta) f.f_args; let open LocalUsage in if params <> [] || inline then v.v_extra <- Some (var_extra params (if inline then Some e else None)); - if ctx.in_display && DisplayPosition.display_position#enclosed_in v.v_pos then + if ctx.f.in_display && DisplayPosition.display_position#enclosed_in v.v_pos then DisplayEmitter.display_variable ctx v v.v_pos; let rec loop = function | LocalUsage.Block f | LocalUsage.Loop f | LocalUsage.Function f -> f loop @@ -1369,7 +1369,7 @@ and type_local_function ctx kind f with_type p = (mk (TVar (v,Some (mk (TConst TNull) ft p))) ctx.t.tvoid p) :: (mk (TBinop (OpAssign,mk (TLocal v) ft p,e)) ft p) :: exprs - end else if inline && not ctx.is_display_file then + end else if inline && not ctx.m.is_display_file then (mk (TBlock []) ctx.t.tvoid p) :: exprs (* do not add variable since it will be inlined *) else (mk (TVar (v,Some e)) ctx.t.tvoid p) :: exprs @@ -1428,7 +1428,7 @@ and type_array_decl ctx el with_type p = let t = try unify_min_raise ctx el with Error ({ err_message = Unify _ } as err) -> - if !allow_array_dynamic || ctx.untyped || ignore_error ctx.com then + if !allow_array_dynamic || ctx.f.untyped || ignore_error ctx.com then t_dynamic else begin display_error ctx.com "Arrays of mixed types are only allowed if the type is forced to Array" err.err_pos; @@ -1444,7 +1444,7 @@ and type_array_decl ctx el with_type p = mk (TArrayDecl el) (ctx.t.tarray t) p) and type_array_comprehension ctx e with_type p = - let v = gen_local ctx (spawn_monomorph ctx p) p in + let v = gen_local ctx (spawn_monomorph ctx.e p) p in let ev = mk (TLocal v) v.v_type p in let e_ref = snd (store_typed_expr ctx.com ev p) in let et = ref (EConst(Ident "null"),p) in @@ -1480,14 +1480,14 @@ and type_array_comprehension ctx e with_type p = ]) v.v_type p and type_return ?(implicit=false) ctx e with_type p = - let is_abstract_ctor = ctx.curfun = FunMemberAbstract && ctx.curfield.cf_name = "_new" in + let is_abstract_ctor = ctx.e.curfun = FunMemberAbstract && ctx.f.curfield.cf_name = "_new" in match e with | None when is_abstract_ctor -> - let e_cast = mk (TCast(get_this ctx p,None)) ctx.ret p in + let e_cast = mk (TCast(get_this ctx p,None)) ctx.e.ret p in mk (TReturn (Some e_cast)) (mono_or_dynamic ctx with_type p) p | None -> let v = ctx.t.tvoid in - unify ctx v ctx.ret p; + unify ctx v ctx.e.ret p; let expect_void = match with_type with | WithType.WithType(t,_) -> ExtType.is_void (follow t) | WithType.Value (Some ImplicitReturn) -> true @@ -1502,16 +1502,16 @@ and type_return ?(implicit=false) ctx e with_type p = end; try let with_expected_type = - if ExtType.is_void (follow ctx.ret) then WithType.no_value - else if implicit then WithType.of_implicit_return ctx.ret - else WithType.with_type ctx.ret + if ExtType.is_void (follow ctx.e.ret) then WithType.no_value + else if implicit then WithType.of_implicit_return ctx.e.ret + else WithType.with_type ctx.e.ret in let e = type_expr ctx e with_expected_type in - match follow ctx.ret with + match follow ctx.e.ret with | TAbstract({a_path=[],"Void"},_) when implicit -> e | _ -> - let e = AbstractCast.cast_or_unify ctx ctx.ret e p in + let e = AbstractCast.cast_or_unify ctx ctx.e.ret e p in match follow e.etype with | TAbstract({a_path=[],"Void"},_) -> begin match (Texpr.skip e).eexpr with @@ -1592,9 +1592,9 @@ and type_if ctx e e1 e2 with_type is_ternary p = make_if_then_else ctx e e1 e2 with_type p and type_meta ?(mode=MGet) ctx m e1 with_type p = - if ctx.is_display_file then DisplayEmitter.check_display_metadata ctx [m]; - let old = ctx.meta in - ctx.meta <- m :: ctx.meta; + if ctx.m.is_display_file then DisplayEmitter.check_display_metadata ctx [m]; + let old = ctx.f.meta in + ctx.f.meta <- m :: ctx.f.meta; let e () = type_expr ~mode ctx e1 with_type in let e = match m with | (Meta.ToString,_,_) -> @@ -1617,7 +1617,7 @@ and type_meta ?(mode=MGet) ctx m e1 with_type p = | (Meta.StoredTypedExpr,_,_) -> type_stored_expr ctx e1 | (Meta.NoPrivateAccess,_,_) -> - ctx.meta <- List.filter (fun(m,_,_) -> m <> Meta.PrivateAccess) ctx.meta; + ctx.f.meta <- List.filter (fun(m,_,_) -> m <> Meta.PrivateAccess) ctx.f.meta; e() | (Meta.Fixed,_,_) when ctx.com.platform=Cpp -> let e = e() in @@ -1626,10 +1626,10 @@ and type_meta ?(mode=MGet) ctx m e1 with_type p = let e = e() in {e with eexpr = TMeta(m,e)} | (Meta.BypassAccessor,_,p) -> - let old_counter = ctx.bypass_accessor in - ctx.bypass_accessor <- old_counter + 1; + let old_counter = ctx.e.bypass_accessor in + ctx.e.bypass_accessor <- old_counter + 1; let e = e () in - (if ctx.bypass_accessor > old_counter then display_error ctx.com "Field access expression expected after @:bypassAccessor metadata" p); + (if ctx.e.bypass_accessor > old_counter then display_error ctx.com "Field access expression expected after @:bypassAccessor metadata" p); e | (Meta.Inline,_,pinline) -> begin match fst e1 with @@ -1670,7 +1670,7 @@ and type_meta ?(mode=MGet) ctx m e1 with_type p = else e() in - ctx.meta <- old; + ctx.f.meta <- old; e and type_call_target ctx e el with_type p_inline = @@ -1775,8 +1775,8 @@ and type_call_builtin ctx e el mode with_type p = | (EDisplay((EConst (Ident "super"),_ as e1),dk),_),_ -> TyperDisplay.handle_display ctx (ECall(e1,el),p) dk mode with_type | (EConst (Ident "super"),sp) , el -> - if ctx.curfun <> FunConstructor then raise_typing_error "Cannot call super constructor outside class constructor" p; - let el, t = (match ctx.curclass.cl_super with + if ctx.e.curfun <> FunConstructor then raise_typing_error "Cannot call super constructor outside class constructor" p; + let el, t = (match ctx.c.curclass.cl_super with | None -> raise_typing_error "Current class does not have a super" p | Some (c,params) -> let fa = FieldAccess.get_constructor_access c params p in @@ -1801,7 +1801,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = | EField(_,n,_) when starts_with n '$' -> raise_typing_error "Field names starting with $ are not allowed" p | EConst (Ident s) -> - if s = "super" && with_type <> WithType.NoValue && not ctx.in_display then raise_typing_error "Cannot use super as value" p; + if s = "super" && with_type <> WithType.NoValue && not ctx.f.in_display then raise_typing_error "Cannot use super as value" p; let e = maybe_type_against_enum ctx (fun () -> type_ident ctx s p mode with_type) with_type false p in acc_get ctx e | EField _ @@ -1924,18 +1924,18 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = | EIf (e,e1,e2) -> type_if ctx e e1 e2 with_type false p | EWhile (cond,e,NormalWhile) -> - let old_loop = ctx.in_loop in + let old_loop = ctx.e.in_loop in let cond = type_expr ctx cond WithType.value in let cond = AbstractCast.cast_or_unify ctx ctx.t.tbool cond p in - ctx.in_loop <- true; + ctx.e.in_loop <- true; let e = type_expr ctx (Expr.ensure_block e) WithType.NoValue in - ctx.in_loop <- old_loop; + ctx.e.in_loop <- old_loop; mk (TWhile (cond,e,NormalWhile)) ctx.t.tvoid p | EWhile (cond,e,DoWhile) -> - let old_loop = ctx.in_loop in - ctx.in_loop <- true; + let old_loop = ctx.e.in_loop in + ctx.e.in_loop <- true; let e = type_expr ctx (Expr.ensure_block e) WithType.NoValue in - ctx.in_loop <- old_loop; + ctx.e.in_loop <- old_loop; let cond = type_expr ctx cond WithType.value in let cond = AbstractCast.cast_or_unify ctx ctx.t.tbool cond cond.epos in mk (TWhile (cond,e,DoWhile)) ctx.t.tvoid p @@ -1944,7 +1944,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = let e = Matcher.Match.match_expr ctx e1 cases def with_type false p in wrap e | EReturn e -> - if not ctx.in_function then begin + if not ctx.e.in_function then begin display_error ctx.com "Return outside function" p; match e with | None -> @@ -1957,10 +1957,10 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = end else type_return ctx e with_type p | EBreak -> - if not ctx.in_loop then display_error ctx.com "Break outside loop" p; + if not ctx.e.in_loop then display_error ctx.com "Break outside loop" p; mk TBreak (mono_or_dynamic ctx with_type p) p | EContinue -> - if not ctx.in_loop then display_error ctx.com "Continue outside loop" p; + if not ctx.e.in_loop then display_error ctx.com "Continue outside loop" p; mk TContinue (mono_or_dynamic ctx with_type p) p | ETry (e1,[]) -> type_expr ctx e1 with_type @@ -1981,11 +1981,11 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = | EFunction (kind,f) -> type_local_function ctx kind f with_type p | EUntyped e -> - let old = ctx.untyped in - ctx.untyped <- true; - if not (Meta.has Meta.HasUntyped ctx.curfield.cf_meta) then ctx.curfield.cf_meta <- (Meta.HasUntyped,[],p) :: ctx.curfield.cf_meta; + let old = ctx.f.untyped in + ctx.f.untyped <- true; + if not (Meta.has Meta.HasUntyped ctx.f.curfield.cf_meta) then ctx.f.curfield.cf_meta <- (Meta.HasUntyped,[],p) :: ctx.f.curfield.cf_meta; let e = type_expr ctx e with_type in - ctx.untyped <- old; + ctx.f.untyped <- old; { eexpr = e.eexpr; etype = mk_mono(); @@ -1993,7 +1993,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = } | ECast (e,None) -> let e = type_expr ctx e WithType.value in - mk (TCast (e,None)) (spawn_monomorph ctx p) p + mk (TCast (e,None)) (spawn_monomorph ctx.e p) p | ECast (e, Some t) -> type_cast ctx e t p | EDisplay (e,dk) -> @@ -2011,7 +2011,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) = if tp.path.tparams <> [] then display_error ctx.com "Type parameters are not supported for the `is` operator" p_t; let e = type_expr ctx e WithType.value in let mt = Typeload.load_type_def ctx p_t tp.path in - if ctx.in_display && DisplayPosition.display_position#enclosed_in p_t then + if ctx.f.in_display && DisplayPosition.display_position#enclosed_in p_t then DisplayEmitter.display_module_type ctx mt p_t; let e_t = type_module_type ctx mt p_t in Texpr.Builder.resolve_and_make_static_call ctx.com.std "isOfType" [e;e_t] p diff --git a/src/typing/typerBase.ml b/src/typing/typerBase.ml index 5cfc5f70074..829ad9fa104 100644 --- a/src/typing/typerBase.ml +++ b/src/typing/typerBase.ml @@ -149,31 +149,31 @@ let is_lower_ident s p = with Invalid_argument msg -> raise_typing_error msg p let get_this ctx p = - match ctx.curfun with + match ctx.e.curfun with | FunStatic -> raise_typing_error "Cannot access this from a static function" p | FunMemberClassLocal | FunMemberAbstractLocal -> - let v = match ctx.vthis with + let v = match ctx.f.vthis with | None -> - let v = if ctx.curfun = FunMemberAbstractLocal then begin - let v = PMap.find "this" ctx.locals in + let v = if ctx.e.curfun = FunMemberAbstractLocal then begin + let v = PMap.find "this" ctx.f.locals in add_var_flag v VUsedByTyper; v end else - add_local ctx VGenerated (Printf.sprintf "%sthis" gen_local_prefix) ctx.tthis p + add_local ctx VGenerated (Printf.sprintf "%sthis" gen_local_prefix) ctx.c.tthis p in - ctx.vthis <- Some v; + ctx.f.vthis <- Some v; v | Some v -> - ctx.locals <- PMap.add v.v_name v ctx.locals; + ctx.f.locals <- PMap.add v.v_name v ctx.f.locals; v in - mk (TLocal v) ctx.tthis p + mk (TLocal v) ctx.c.tthis p | FunMemberAbstract -> - let v = (try PMap.find "this" ctx.locals with Not_found -> raise_typing_error "Cannot reference this abstract here" p) in + let v = (try PMap.find "this" ctx.f.locals with Not_found -> raise_typing_error "Cannot reference this abstract here" p) in mk (TLocal v) v.v_type p | FunConstructor | FunMember -> - mk (TConst TThis) ctx.tthis p + mk (TConst TThis) ctx.c.tthis p let get_stored_typed_expr ctx id = let e = ctx.com.stored_typed_exprs#find id in @@ -184,11 +184,11 @@ let type_stored_expr ctx e1 = get_stored_typed_expr ctx id let assign_to_this_is_allowed ctx = - match ctx.curclass.cl_kind with + match ctx.c.curclass.cl_kind with | KAbstractImpl _ -> - (match ctx.curfield.cf_kind with + (match ctx.f.curfield.cf_kind with | Method MethInline -> true - | Method _ when ctx.curfield.cf_name = "_new" -> true + | Method _ when ctx.f.curfield.cf_name = "_new" -> true | _ -> false ) | _ -> false @@ -211,7 +211,7 @@ let type_module_type ctx t p = | TEnumDecl e -> mk (TTypeExpr (TEnumDecl e)) e.e_type p | TTypeDecl s -> - let t = apply_typedef s (List.map (fun _ -> spawn_monomorph ctx p) s.t_params) in + let t = apply_typedef s (List.map (fun _ -> spawn_monomorph ctx.e p) s.t_params) in DeprecationCheck.check_typedef (create_deprecation_context ctx) s p; (match follow t with | TEnum (e,params) -> @@ -334,7 +334,7 @@ let get_abstract_froms ctx a pl = let l = List.map (apply_params a.a_params pl) a.a_from in List.fold_left (fun acc (t,f) -> (* We never want to use the @:from we're currently in because that's recursive (see #10604) *) - if f == ctx.curfield then + if f == ctx.f.curfield then acc else if (AbstractFromConfig.update_config_from_meta (AbstractFromConfig.make ()) f.cf_meta).ignored_by_inference then acc diff --git a/src/typing/typerDisplay.ml b/src/typing/typerDisplay.ml index ac504cbe7bf..9470e8bae60 100644 --- a/src/typing/typerDisplay.ml +++ b/src/typing/typerDisplay.ml @@ -178,7 +178,7 @@ let raise_toplevel ctx dk with_type (subject,psubject) = DisplayToplevel.collect_and_raise ctx (match dk with DKPattern _ -> TKPattern psubject | _ -> TKExpr psubject) with_type (CRToplevel expected_type) (subject,psubject) psubject let display_dollar_type ctx p make_type = - let mono = spawn_monomorph ctx p in + let mono = spawn_monomorph ctx.e p in let doc = doc_from_string "Outputs type of argument as a warning and uses argument as value" in let arg = ["expression",false,mono] in begin match ctx.com.display.dms_kind with @@ -194,7 +194,7 @@ let display_dollar_type ctx p make_type = end let rec handle_signature_display ctx e_ast with_type = - ctx.in_display <- true; + ctx.f.in_display <- true; let p = pos e_ast in let handle_call tl el p0 = let rec follow_with_callable (t,doc,values) = match follow t with @@ -340,7 +340,7 @@ let rec handle_signature_display ctx e_ast with_type = | _ -> raise_typing_error "Call expected" p and display_expr ctx e_ast e dk mode with_type p = - let get_super_constructor () = match ctx.curclass.cl_super with + let get_super_constructor () = match ctx.c.curclass.cl_super with | None -> raise_typing_error "Current class does not have a super" p | Some (c,params) -> let fa = get_constructor_access c params p in @@ -419,7 +419,7 @@ and display_expr ctx e_ast e dk mode with_type p = () end | TConst TSuper -> - begin match ctx.curclass.cl_super with + begin match ctx.c.curclass.cl_super with | None -> () | Some (c,_) -> Display.ReferencePosition.set (snd c.cl_path,c.cl_name_pos,SKClass c); end @@ -476,7 +476,7 @@ and display_expr ctx e_ast e dk mode with_type p = [] end | TConst TSuper -> - begin match ctx.curclass.cl_super with + begin match ctx.c.curclass.cl_super with | None -> [] | Some (c,_) -> [c.cl_name_pos] end @@ -541,9 +541,9 @@ and display_expr ctx e_ast e dk mode with_type p = raise_fields fields (CRField(item,e.epos,iterator,keyValueIterator)) (make_subject None (DisplayPosition.display_position#with_pos p)) let handle_display ctx e_ast dk mode with_type = - let old = ctx.in_display,ctx.in_call_args in - ctx.in_display <- true; - ctx.in_call_args <- false; + let old = ctx.f.in_display,ctx.f.in_call_args in + ctx.f.in_display <- true; + ctx.f.in_call_args <- false; let tpair t = let ct = CompletionType.from_type (get_import_status ctx) t in (t,ct) @@ -595,10 +595,10 @@ let handle_display ctx e_ast dk mode with_type = begin match mt.has_constructor with | Yes -> true | YesButPrivate -> - if (Meta.has Meta.PrivateAccess ctx.meta) then true + if (Meta.has Meta.PrivateAccess ctx.f.meta) then true else begin - match ctx.curclass.cl_kind with + match ctx.c.curclass.cl_kind with | KAbstractImpl { a_path = (pack, name) } -> pack = mt.pack && name = mt.name | _ -> false end @@ -610,7 +610,7 @@ let handle_display ctx e_ast dk mode with_type = | Some(c,_) -> loop c | None -> false in - loop ctx.curclass + loop ctx.c.curclass end | No -> false | Maybe -> @@ -640,7 +640,7 @@ let handle_display ctx e_ast dk mode with_type = | (EField(_,"new",_),_), TFunction { tf_expr = { eexpr = TReturn (Some ({ eexpr = TNew _ } as e1))} } -> e1 | _ -> e in - let is_display_debug = Meta.has (Meta.Custom ":debug.display") ctx.curfield.cf_meta in + let is_display_debug = Meta.has (Meta.Custom ":debug.display") ctx.f.curfield.cf_meta in if is_display_debug then begin print_endline (Printf.sprintf "expected type: %s" (WithType.to_string with_type)); print_endline (Printf.sprintf "typed expr:\n%s" (s_expr_ast true "" (s_type (print_context())) e)); @@ -657,14 +657,14 @@ let handle_display ctx e_ast dk mode with_type = if is_display_debug then begin print_endline (Printf.sprintf "cast expr:\n%s" (s_expr_ast true "" (s_type (print_context())) e)); end; - ctx.in_display <- fst old; - ctx.in_call_args <- snd old; + ctx.f.in_display <- fst old; + ctx.f.in_call_args <- snd old; let f () = display_expr ctx e_ast e dk mode with_type p in - if ctx.in_overload_call_args then begin + if ctx.f.in_overload_call_args then begin try f() with DisplayException de -> - ctx.delayed_display <- Some de; + ctx.g.delayed_display <- Some de; e end else f() diff --git a/src/typing/typerEntry.ml b/src/typing/typerEntry.ml index 27637158004..a624db3b880 100644 --- a/src/typing/typerEntry.ml +++ b/src/typing/typerEntry.ml @@ -36,6 +36,7 @@ let create com macros = get_build_info = InstanceBuilder.get_build_info; do_format_string = format_string; do_load_core_class = Typeload.load_core_class; + delayed_display = None; }; m = { curmod = null_module; @@ -44,36 +45,19 @@ let create com macros = enum_with_type = None; module_using = []; import_statements = []; + is_display_file = false; }; - is_display_file = false; - bypass_accessor = 0; - meta = []; - with_type_stack = []; - call_argument_stack = []; + c = { + curclass = null_class; + tthis = t_dynamic; + get_build_infos = (fun() -> None); + }; + f = TyperManager.create_ctx_f null_field; + e = TyperManager.create_ctx_e (); pass = PBuildModule; - macro_depth = 0; - untyped = false; - curfun = FunStatic; - in_function = false; - in_loop = false; - in_display = false; allow_inline = true; allow_transform = true; - get_build_infos = (fun() -> None); - ret = mk_mono(); - locals = PMap.empty; type_params = []; - curclass = null_class; - curfield = null_field; - tthis = mk_mono(); - opened = []; - vthis = None; - in_call_args = false; - in_overload_call_args = false; - delayed_display = None; - monomorphs = { - perfunction = []; - }; memory_marker = Typecore.memory_marker; } in ctx.g.std_types <- (try From d9fc90a8501a02580fa2dbf7492a30ef785cc913 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sat, 3 Feb 2024 09:20:47 +0100 Subject: [PATCH 08/20] [hxb] remove writer stats I broke parts of it already anyway. --- src/compiler/compilationCache.ml | 4 +- src/compiler/generate.ml | 2 +- src/compiler/hxb/hxbWriter.ml | 83 ++------------------------------ src/context/common.ml | 3 -- src/context/commonCache.ml | 3 +- 5 files changed, 9 insertions(+), 86 deletions(-) diff --git a/src/compiler/compilationCache.ml b/src/compiler/compilationCache.ml index b7c8ea854cc..0b4b2a0b455 100644 --- a/src/compiler/compilationCache.ml +++ b/src/compiler/compilationCache.ml @@ -69,12 +69,12 @@ class context_cache (index : int) (sign : Digest.t) = object(self) method find_module_extra path = try (Hashtbl.find modules path).m_extra with Not_found -> (Hashtbl.find binary_cache path).mc_extra - method cache_module config warn anon_identification hxb_writer_stats path m = + method cache_module config warn anon_identification path m = match m.m_extra.m_kind with | MImport -> Hashtbl.add modules m.m_path m | _ -> - let writer = HxbWriter.create config warn anon_identification hxb_writer_stats in + let writer = HxbWriter.create config warn anon_identification in HxbWriter.write_module writer m; let chunks = HxbWriter.get_chunks writer in Hashtbl.replace binary_cache path { diff --git a/src/compiler/generate.ml b/src/compiler/generate.ml index e12e22e372b..04718ece5e0 100644 --- a/src/compiler/generate.ml +++ b/src/compiler/generate.ml @@ -42,7 +42,7 @@ let export_hxb com config cc platform zip m = with Not_found -> let anon_identification = new tanon_identification in let warn w s p = com.Common.warning w com.warning_options s p in - let writer = HxbWriter.create config warn anon_identification com.hxb_writer_stats in + let writer = HxbWriter.create config warn anon_identification in HxbWriter.write_module writer m; let out = IO.output_string () in HxbWriter.export writer out; diff --git a/src/compiler/hxb/hxbWriter.ml b/src/compiler/hxb/hxbWriter.ml index 39cde88c266..cc2d1c1065c 100644 --- a/src/compiler/hxb/hxbWriter.ml +++ b/src/compiler/hxb/hxbWriter.ml @@ -45,63 +45,6 @@ let unop_index op flag = match op,flag with | NegBits,Postfix -> 10 | Spread,Postfix -> 11 -type hxb_writer_stats = { - type_instance_kind_writes : int array; - texpr_writes : int array; - type_instance_immediate : int ref; - type_instance_cache_hits : int ref; - type_instance_cache_misses : int ref; - pos_writes_full : int ref; - pos_writes_min : int ref; - pos_writes_max : int ref; - pos_writes_minmax : int ref; - pos_writes_eq : int ref; - chunk_sizes : (string,int ref * int ref) Hashtbl.t; -} - -let create_hxb_writer_stats () = { - type_instance_kind_writes = Array.make 255 0; - texpr_writes = Array.make 255 0; - type_instance_immediate = ref 0; - type_instance_cache_hits = ref 0; - type_instance_cache_misses = ref 0; - pos_writes_full = ref 0; - pos_writes_min = ref 0; - pos_writes_max = ref 0; - pos_writes_minmax = ref 0; - pos_writes_eq = ref 0; - chunk_sizes = Hashtbl.create 0; -} - -let dump_stats name stats = - let sort_and_filter_array a = - let _,kind_writes = Array.fold_left (fun (index,acc) writes -> - (index + 1,if writes = 0 then acc else (index,writes) :: acc) - ) (0,[]) a in - let kind_writes = List.sort (fun (_,writes1) (_,writes2) -> compare writes2 writes1) kind_writes in - List.map (fun (index,writes) -> Printf.sprintf " %3i: %9i" index writes) kind_writes - in - let t_kind_writes = sort_and_filter_array stats.type_instance_kind_writes in - print_endline (Printf.sprintf "hxb_writer stats for %s" name); - print_endline " type instance kind writes:"; - List.iter print_endline t_kind_writes; - let texpr_writes = sort_and_filter_array stats.texpr_writes in - print_endline " texpr writes:"; - List.iter print_endline texpr_writes; - - print_endline " type instance writes:"; - print_endline (Printf.sprintf " immediate: %9i" !(stats.type_instance_immediate)); - print_endline (Printf.sprintf " cache hits: %9i" !(stats.type_instance_cache_hits)); - print_endline (Printf.sprintf " cache miss: %9i" !(stats.type_instance_cache_misses)); - print_endline " pos writes:"; - print_endline (Printf.sprintf " full: %9i\n min: %9i\n max: %9i\n minmax: %9i\n equal: %9i" !(stats.pos_writes_full) !(stats.pos_writes_min) !(stats.pos_writes_max) !(stats.pos_writes_minmax) !(stats.pos_writes_eq)); - (* let chunk_sizes = Hashtbl.fold (fun name (imin,imax) acc -> (name,!imin,!imax) :: acc) stats.chunk_sizes [] in - let chunk_sizes = List.sort (fun (_,imin1,imax1) (_,imin2,imax2) -> compare imax1 imax2) chunk_sizes in - print_endline "chunk sizes:"; - List.iter (fun (name,imin,imax) -> - print_endline (Printf.sprintf " %s: %i - %i" name imin imax) - ) chunk_sizes *) - module StringHashtbl = Hashtbl.Make(struct type t = string @@ -400,17 +343,10 @@ module Chunk = struct let write_bool io b = write_u8 io (if b then 1 else 0) - let export : 'a . hxb_writer_stats -> t -> 'a IO.output -> unit = fun stats io chex -> + let export : 'a . t -> 'a IO.output -> unit = fun io chex -> let bytes = get_bytes io in let length = Bytes.length bytes in write_chunk_prefix io.kind length chex; - (* begin try - let (imin,imax) = Hashtbl.find stats.chunk_sizes io.name in - if length < !imin then imin := length; - if length > !imax then imax := length - with Not_found -> - Hashtbl.add stats.chunk_sizes io.name (ref length,ref length); - end; *) IO.nwrite chex bytes let write_string chunk s = @@ -438,22 +374,19 @@ end module PosWriter = struct type t = { - stats : hxb_writer_stats; mutable p_file : string; mutable p_min : int; mutable p_max : int; } let do_write_pos (chunk : Chunk.t) (p : pos) = - (* incr stats.pos_writes_full; *) Chunk.write_string chunk p.pfile; Chunk.write_leb128 chunk p.pmin; Chunk.write_leb128 chunk p.pmax - let create stats chunk p = + let create chunk p = do_write_pos chunk p; { - stats; p_file = p.pfile; p_min = p.pmin; p_max = p.pmax; @@ -470,7 +403,6 @@ module PosWriter = struct end else if p.pmin <> pw.p_min then begin if p.pmax <> pw.p_max then begin (* pmin and pmax changed *) - (* incr stats.pos_writes_minmax; *) Chunk.write_u8 chunk (3 + offset); Chunk.write_leb128 chunk p.pmin; Chunk.write_leb128 chunk p.pmax; @@ -478,19 +410,16 @@ module PosWriter = struct pw.p_max <- p.pmax; end else begin (* pmin changed *) - (* incr stats.pos_writes_min; *) Chunk.write_u8 chunk (1 + offset); Chunk.write_leb128 chunk p.pmin; pw.p_min <- p.pmin; end end else if p.pmax <> pw.p_max then begin (* pmax changed *) - (* incr stats.pos_writes_max; *) Chunk.write_u8 chunk (2 + offset); Chunk.write_leb128 chunk p.pmax; pw.p_max <- p.pmax; end else begin - (* incr stats.pos_writes_eq; *) if write_equal then Chunk.write_u8 chunk offset; end @@ -514,7 +443,6 @@ type hxb_writer = { config : HxbWriterConfig.writer_target_config; warn : Warning.warning -> string -> Globals.pos -> unit; anon_id : Type.t Tanon_identification.tanon_identification; - stats : hxb_writer_stats; mutable current_module : module_def; chunks : Chunk.t DynArray.t; cp : StringPool.t; @@ -1794,7 +1722,7 @@ module HxbWriter = struct and start_texpr writer (p: pos) = let restore = start_temporary_chunk writer 512 in - let fctx = create_field_writer_context (PosWriter.create writer.stats writer.chunk p) in + let fctx = create_field_writer_context (PosWriter.create writer.chunk p) in fctx,(fun () -> restore(fun new_chunk -> let restore = start_temporary_chunk writer 512 in @@ -2287,13 +2215,12 @@ module HxbWriter = struct l end -let create config warn anon_id stats = +let create config warn anon_id = let cp = StringPool.create () in { config; warn; anon_id; - stats; current_module = null_module; chunks = DynArray.create (); cp = cp; @@ -2333,5 +2260,5 @@ let export : 'a . hxb_writer -> 'a IO.output -> unit = fun writer ch -> write_header ch; let l = HxbWriter.get_sorted_chunks writer in List.iter (fun io -> - Chunk.export writer.stats io ch + Chunk.export io ch ) l diff --git a/src/context/common.ml b/src/context/common.ml index e1e3577f8b0..db30ae055ee 100644 --- a/src/context/common.ml +++ b/src/context/common.ml @@ -420,7 +420,6 @@ type context = { mutable basic : basic_types; memory_marker : float array; hxb_reader_stats : HxbReader.hxb_reader_stats; - hxb_writer_stats : HxbWriter.hxb_writer_stats; mutable hxb_writer_config : HxbWriterConfig.t option; } @@ -883,7 +882,6 @@ let create compilation_step cs version args display_mode = report_mode = RMNone; is_macro_context = false; hxb_reader_stats = HxbReader.create_hxb_reader_stats (); - hxb_writer_stats = HxbWriter.create_hxb_writer_stats (); hxb_writer_config = None; } in com @@ -935,7 +933,6 @@ let clone com is_macro_context = overload_cache = new hashtbl_lookup; module_lut = new module_lut; hxb_reader_stats = HxbReader.create_hxb_reader_stats (); - hxb_writer_stats = HxbWriter.create_hxb_writer_stats (); std = null_class; empty_class_path = new ClassPath.directory_class_path "" User; class_paths = new ClassPaths.class_paths; diff --git a/src/context/commonCache.ml b/src/context/commonCache.ml index 312d5cc723c..d2c7db7796c 100644 --- a/src/context/commonCache.ml +++ b/src/context/commonCache.ml @@ -95,7 +95,7 @@ let rec cache_context cs com = (* If we have a signature mismatch, look-up cache for module. Physical equality check is fine as a heueristic. *) let cc = if m.m_extra.m_sign = sign then cc else cs#get_context m.m_extra.m_sign in let warn w s p = com.warning w com.warning_options s p in - cc#cache_module config warn anon_identification com.hxb_writer_stats m.m_path m; + cc#cache_module config warn anon_identification m.m_path m; in List.iter cache_module com.modules; begin match com.get_macros() with @@ -104,7 +104,6 @@ let rec cache_context cs com = end; if Define.raw_defined com.defines "hxb.stats" then begin HxbReader.dump_stats (platform_name com.platform) com.hxb_reader_stats; - HxbWriter.dump_stats (platform_name com.platform) com.hxb_writer_stats end let maybe_add_context_sign cs com desc = From 4260da3c6f98dd55b64c001f4ae7896531d5e864 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sat, 3 Feb 2024 09:48:23 +0100 Subject: [PATCH 09/20] Remove some API from haxe.macro.Compiler (#11540) * remove some API from haxe.macro.Compiler * js fixes * never mind --- src/context/typecore.ml | 1 - src/macro/macroApi.ml | 10 -- src/typing/macroContext.ml | 46 ------- src/typing/typeloadFields.ml | 70 ----------- src/typing/typeloadModule.ml | 6 - src/typing/typerEntry.ml | 1 - std/haxe/macro/Compiler.hx | 115 +----------------- tests/misc/es6/Test.hx | 2 +- .../user-defined-define-json-fail.hxml.stderr | 2 +- .../user-defined-meta-json-fail.hxml.stderr | 2 +- ...-defined-meta-json-indent-fail.hxml.stderr | 2 +- ...-defined-meta-json-pretty-fail.hxml.stderr | 4 +- tests/misc/projects/Issue4660/Include.hx | 2 +- tests/misc/projects/Issue8567/compile.hxml | 3 - tests/misc/projects/Issue8567/src/Main.hx | 4 - tests/misc/projects/Issue8567/src/test.txt | 0 16 files changed, 12 insertions(+), 258 deletions(-) delete mode 100644 tests/misc/projects/Issue8567/compile.hxml delete mode 100644 tests/misc/projects/Issue8567/src/Main.hx delete mode 100644 tests/misc/projects/Issue8567/src/test.txt diff --git a/src/context/typecore.ml b/src/context/typecore.ml index 180b14daaf7..730c05259b8 100644 --- a/src/context/typecore.ml +++ b/src/context/typecore.ml @@ -114,7 +114,6 @@ type typer_globals = { mutable core_api : typer option; mutable macros : ((unit -> unit) * typer) option; mutable std_types : module_def; - type_patches : (path, (string * bool, type_patch) Hashtbl.t * type_patch) Hashtbl.t; mutable module_check_policies : (string list * module_check_policy list * bool) list; mutable global_using : (tclass * pos) list; (* Indicates that Typer.create() finished building this instance *) diff --git a/src/macro/macroApi.ml b/src/macro/macroApi.ml index d7b1b8f97eb..155ed8c08ce 100644 --- a/src/macro/macroApi.ml +++ b/src/macro/macroApi.ml @@ -38,8 +38,6 @@ type 'value compiler_api = { resolve_complex_type : Ast.type_hint -> Ast.type_hint; store_typed_expr : Type.texpr -> Ast.expr; allow_package : string -> unit; - type_patch : string -> string -> bool -> string option -> unit; - meta_patch : string -> string -> string option -> bool -> pos -> unit; set_js_generator : (Genjs.ctx -> unit) -> unit; get_local_type : unit -> t option; get_expected_type : unit -> t option; @@ -1953,14 +1951,6 @@ let macro_api ccom get_api = (get_api()).allow_package (decode_string s); vnull ); - "type_patch", vfun4 (fun t f s v -> - (get_api()).type_patch (decode_string t) (decode_string f) (decode_bool s) (opt decode_string v); - vnull - ); - "meta_patch", vfun4 (fun m t f s -> - (get_api()).meta_patch (decode_string m) (decode_string t) (opt decode_string f) (decode_bool s) (get_api_call_pos ()); - vnull - ); "add_global_metadata_impl", vfun5 (fun s1 s2 b1 b2 b3 -> (get_api()).add_global_metadata (decode_string s1) (decode_string s2) (decode_bool b1,decode_bool b2,decode_bool b3) (get_api_call_pos()); vnull diff --git a/src/typing/macroContext.ml b/src/typing/macroContext.ml index b76ddbec32c..b17f1a2b103 100644 --- a/src/typing/macroContext.ml +++ b/src/typing/macroContext.ml @@ -51,28 +51,6 @@ let safe_decode com v expected t p f = close_out ch; raise_typing_error (Printf.sprintf "Expected %s but got %s (see %s.txt for details)" expected (Interp.value_string v) (String.concat "/" path)) p -let get_type_patch ctx t sub = - let new_patch() = - { tp_type = None; tp_remove = false; tp_meta = [] } - in - let path = Ast.parse_path t in - let h, tp = (try - Hashtbl.find ctx.g.type_patches path - with Not_found -> - let h = Hashtbl.create 0 in - let tp = new_patch() in - Hashtbl.add ctx.g.type_patches path (h,tp); - h, tp - ) in - match sub with - | None -> tp - | Some k -> - try - Hashtbl.find h k - with Not_found -> - let tp = new_patch() in - Hashtbl.add h k tp; - tp let macro_timer com l = Timer.timer (if Common.defined com Define.MacroTimes then ("macro" :: l) else ["macro"]) @@ -222,12 +200,6 @@ let make_macro_com_api com mcom p = snd (Typecore.store_typed_expr com te p) ); allow_package = (fun v -> Common.allow_package com v); - type_patch = (fun t f s v -> - Interp.exc_string "unsupported" - ); - meta_patch = (fun m t f s p -> - Interp.exc_string "unsupported" - ); set_js_generator = (fun gen -> com.js_gen <- Some (fun() -> Path.mkdir_from_path com.file; @@ -434,24 +406,6 @@ let make_macro_api ctx mctx p = MacroApi.flush_context = (fun f -> typing_timer ctx true f ); - MacroApi.type_patch = (fun t f s v -> - typing_timer ctx false (fun() -> - let v = (match v with None -> None | Some s -> - match ParserEntry.parse_string Grammar.parse_complex_type ctx.com.defines s null_pos raise_typing_error false with - | ParseSuccess((ct,_),_,_) -> Some ct - | ParseError(_,(msg,p),_) -> Parser.error msg p (* p is null_pos, but we don't have anything else here... *) - ) in - let tp = get_type_patch ctx t (Some (f,s)) in - match v with - | None -> tp.tp_remove <- true - | Some t -> tp.tp_type <- Some t - ); - ); - MacroApi.meta_patch = (fun m t f s p -> - let ml = parse_metadata m p in - let tp = get_type_patch ctx t (match f with None -> None | Some f -> Some (f,s)) in - tp.tp_meta <- tp.tp_meta @ (List.map (fun (m,el,_) -> (m,el,p)) ml); - ); MacroApi.get_local_type = (fun() -> match ctx.c.get_build_infos() with | Some (mt,tl,_) -> diff --git a/src/typing/typeloadFields.ml b/src/typing/typeloadFields.ml index 1c335511c76..f49140384ff 100644 --- a/src/typing/typeloadFields.ml +++ b/src/typing/typeloadFields.ml @@ -282,75 +282,6 @@ let transform_abstract_field com this_t a_t a f = | _ -> f -let patch_class ctx c fields = - let path = match c.cl_kind with - | KAbstractImpl a -> a.a_path - | _ -> c.cl_path - in - let h = (try Some (Hashtbl.find ctx.g.type_patches path) with Not_found -> None) in - match h with - | None -> fields - | Some (h,hcl) -> - c.cl_meta <- c.cl_meta @ hcl.tp_meta; - let patch_getter t fn = - { fn with f_type = t } - in - let patch_setter t fn = - match fn.f_args with - | [(name,opt,meta,_,expr)] -> - { fn with f_args = [(name,opt,meta,t,expr)]; f_type = t } - | _ -> fn - in - let rec loop acc accessor_acc = function - | [] -> acc, accessor_acc - | f :: l -> - (* patch arguments types *) - (match f.cff_kind with - | FFun ff -> - let param (((n,pn),opt,m,_,e) as p) = - try - let t2 = (try Hashtbl.find h (("$" ^ (fst f.cff_name) ^ "__" ^ n),false) with Not_found -> Hashtbl.find h (("$" ^ n),false)) in - (n,pn), opt, m, (match t2.tp_type with None -> None | Some t -> Some (t,null_pos)), e - with Not_found -> - p - in - f.cff_kind <- FFun { ff with f_args = List.map param ff.f_args } - | _ -> ()); - (* other patches *) - match (try Some (Hashtbl.find h (fst f.cff_name,List.mem_assoc AStatic f.cff_access)) with Not_found -> None) with - | None -> loop (f :: acc) accessor_acc l - | Some { tp_remove = true } -> loop acc accessor_acc l - | Some p -> - f.cff_meta <- f.cff_meta @ p.tp_meta; - let accessor_acc = - match p.tp_type with - | None -> accessor_acc - | Some t -> - match f.cff_kind with - | FVar (_,e) -> - f.cff_kind <- FVar (Some (t,null_pos),e); accessor_acc - | FProp (get,set,_,eo) -> - let typehint = Some (t,null_pos) in - let accessor_acc = if fst get = "get" then ("get_" ^ fst f.cff_name, patch_getter typehint) :: accessor_acc else accessor_acc in - let accessor_acc = if fst set = "set" then ("set_" ^ fst f.cff_name, patch_setter typehint) :: accessor_acc else accessor_acc in - f.cff_kind <- FProp (get,set,typehint,eo); accessor_acc - | FFun fn -> - f.cff_kind <- FFun { fn with f_type = Some (t,null_pos) }; accessor_acc - in - loop (f :: acc) accessor_acc l - in - let fields, accessor_patches = loop [] [] fields in - List.iter (fun (accessor_name, patch) -> - try - let f_accessor = List.find (fun f -> fst f.cff_name = accessor_name) fields in - match f_accessor.cff_kind with - | FFun fn -> f_accessor.cff_kind <- FFun (patch fn) - | _ -> () - with Not_found -> - () - ) accessor_patches; - List.rev fields - let lazy_display_type ctx f = f () @@ -1710,7 +1641,6 @@ let check_functional_interface ctx c = let init_class ctx_c cctx c p herits fields = let com = ctx_c.com in if cctx.is_class_debug then print_endline ("Created class context: " ^ dump_class_context cctx); - let fields = patch_class ctx_c c fields in let fields = build_fields (ctx_c,cctx) c fields in if cctx.is_core_api && com.display.dms_check_core_api then delay ctx_c PForce (fun() -> init_core_api ctx_c c); if not cctx.is_lib then begin diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 1966c5eb1d5..35889603d3a 100644 --- a/src/typing/typeloadModule.ml +++ b/src/typing/typeloadModule.ml @@ -450,13 +450,7 @@ module TypeLevel = struct if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then DisplayEmitter.display_module_type ctx_m (TEnumDecl e) (pos d.d_name); let ctx_en = TyperManager.clone_for_enum ctx_m e in - let h = (try Some (Hashtbl.find ctx_en.g.type_patches e.e_path) with Not_found -> None) in TypeloadCheck.check_global_metadata ctx_en e.e_meta (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None; - (match h with - | None -> () - | Some (h,hcl) -> - Hashtbl.iter (fun _ _ -> raise_typing_error "Field type patch not supported for enums" e.e_pos) h; - e.e_meta <- e.e_meta @ hcl.tp_meta); let constructs = ref d.d_data in let get_constructs() = List.map (fun c -> diff --git a/src/typing/typerEntry.ml b/src/typing/typerEntry.ml index a624db3b880..72ae8d3bf57 100644 --- a/src/typing/typerEntry.ml +++ b/src/typing/typerEntry.ml @@ -13,7 +13,6 @@ let create com macros = g = { core_api = None; macros = macros; - type_patches = Hashtbl.create 0; module_check_policies = []; delayed = Array.init all_typer_passes_length (fun _ -> { tasks = []}); delayed_min_index = 0; diff --git a/std/haxe/macro/Compiler.hx b/std/haxe/macro/Compiler.hx index 03701de4b96..1ba1ed88e6f 100644 --- a/std/haxe/macro/Compiler.hx +++ b/std/haxe/macro/Compiler.hx @@ -77,64 +77,9 @@ class Compiler { } #if (!neko && !eval) - private static function typePatch(cl:String, f:String, stat:Bool, t:String) {} - - private static function metaPatch(meta:String, cl:String, f:String, stat:Bool) {} - private static function addGlobalMetadataImpl(pathFilter:String, meta:String, recursive:Bool, toTypes:Bool, toFields:Bool) {} #end - /** - Removes a (static) field from a given class by name. - An error is thrown when `className` or `field` is invalid. - **/ - @:deprecated - public static function removeField(className:String, field:String, ?isStatic:Bool) { - if (!path.match(className)) - throw "Invalid " + className; - if (!ident.match(field)) - throw "Invalid " + field; - #if (neko || eval) - Context.onAfterInitMacros(() -> load("type_patch", 4)(className, field, isStatic == true, null)); - #else - typePatch(className, field, isStatic == true, null); - #end - } - - /** - Set the type of a (static) field at a given class by name. - An error is thrown when `className` or `field` is invalid. - **/ - @:deprecated - public static function setFieldType(className:String, field:String, type:String, ?isStatic:Bool) { - if (!path.match(className)) - throw "Invalid " + className; - if (!ident.match((field.charAt(0) == "$") ? field.substr(1) : field)) - throw "Invalid " + field; - #if (neko || eval) - Context.onAfterInitMacros(() -> load("type_patch", 4)(className, field, isStatic == true, type)); - #else - typePatch(className, field, isStatic == true, type); - #end - } - - /** - Add metadata to a (static) field or class by name. - An error is thrown when `className` or `field` is invalid. - **/ - @:deprecated - public static function addMetadata(meta:String, className:String, ?field:String, ?isStatic:Bool) { - if (!path.match(className)) - throw "Invalid " + className; - if (field != null && !ident.match(field)) - throw "Invalid " + field; - #if (neko || eval) - Context.onAfterInitMacros(() -> load("meta_patch", 4)(meta, className, field, isStatic == true)); - #else - metaPatch(meta, className, field, isStatic == true); - #end - } - /** Add a class path where ".hx" source files or packages (sub-directories) can be found. @@ -374,61 +319,6 @@ class Compiler { }); } - /** - Load a type patch file that can modify the field types within declared classes and enums. - **/ - public static function patchTypes(file:String):Void { - var file = Context.resolvePath(file); - var f = sys.io.File.read(file, true); - try { - while (true) { - var r = StringTools.trim(f.readLine()); - if (r == "" || r.substr(0, 2) == "//") - continue; - if (StringTools.endsWith(r, ";")) - r = r.substr(0, -1); - if (r.charAt(0) == "-") { - r = r.substr(1); - var isStatic = StringTools.startsWith(r, "static "); - if (isStatic) - r = r.substr(7); - var p = r.split("."); - var field = p.pop(); - removeField(p.join("."), field, isStatic); - continue; - } - if (r.charAt(0) == "@") { - var rp = r.split(" "); - var type = rp.pop(); - var isStatic = rp[rp.length - 1] == "static"; - if (isStatic) - rp.pop(); - var meta = rp.join(" "); - var p = type.split("."); - var field = if (p.length > 1 && p[p.length - 2].charAt(0) >= "a") null else p.pop(); - addMetadata(meta, p.join("."), field, isStatic); - continue; - } - if (StringTools.startsWith(r, "enum ")) { - define("enumAbstract:" + r.substr(5)); - continue; - } - var rp = r.split(" : "); - if (rp.length > 1) { - r = rp.shift(); - var isStatic = StringTools.startsWith(r, "static "); - if (isStatic) - r = r.substr(7); - var p = r.split("."); - var field = p.pop(); - setFieldType(p.join("."), field, rp.join(" : "), isStatic); - continue; - } - throw "Invalid type patch " + r; - } - } catch (e:haxe.io.Eof) {} - } - /** Marks types or packages to be kept by DCE. @@ -487,6 +377,11 @@ class Compiler { #end } + public static function addMetadata(meta:String, className:String, ?field:String, ?isStatic:Bool) { + var pathFilter = field == null ? className : '$className.$field'; + addGlobalMetadata(pathFilter, meta, true, field == null, field != null); + } + /** Reference a json file describing user-defined metadata See https://github.com/HaxeFoundation/haxe/blob/development/src-json/meta.json diff --git a/tests/misc/es6/Test.hx b/tests/misc/es6/Test.hx index 4fec1638c16..7592383dc77 100644 --- a/tests/misc/es6/Test.hx +++ b/tests/misc/es6/Test.hx @@ -32,7 +32,7 @@ class F extends E { } extern class ExtNoCtor { - static function __init__():Void haxe.macro.Compiler.includeFile("./extern.js", "top"); + static function __init__():Void haxe.macro.Compiler.includeFile("./extern.js"); } class Base extends ExtNoCtor { diff --git a/tests/misc/projects/Issue10844/user-defined-define-json-fail.hxml.stderr b/tests/misc/projects/Issue10844/user-defined-define-json-fail.hxml.stderr index 1e7dc411b9f..71888302865 100644 --- a/tests/misc/projects/Issue10844/user-defined-define-json-fail.hxml.stderr +++ b/tests/misc/projects/Issue10844/user-defined-define-json-fail.hxml.stderr @@ -1,3 +1,3 @@ (unknown) : Uncaught exception Could not read file define.jsno -$$normPath(::std::)/haxe/macro/Compiler.hx:506: characters 11-39 : Called from here +$$normPath(::std::)/haxe/macro/Compiler.hx:401: characters 11-39 : Called from here (unknown) : Called from here diff --git a/tests/misc/projects/Issue10844/user-defined-meta-json-fail.hxml.stderr b/tests/misc/projects/Issue10844/user-defined-meta-json-fail.hxml.stderr index 3e26bc6c365..9f77e04b2fb 100644 --- a/tests/misc/projects/Issue10844/user-defined-meta-json-fail.hxml.stderr +++ b/tests/misc/projects/Issue10844/user-defined-meta-json-fail.hxml.stderr @@ -1,3 +1,3 @@ (unknown) : Uncaught exception Could not read file meta.jsno -$$normPath(::std::)/haxe/macro/Compiler.hx:495: characters 11-39 : Called from here +$$normPath(::std::)/haxe/macro/Compiler.hx:390: characters 11-39 : Called from here (unknown) : Called from here diff --git a/tests/misc/projects/Issue10844/user-defined-meta-json-indent-fail.hxml.stderr b/tests/misc/projects/Issue10844/user-defined-meta-json-indent-fail.hxml.stderr index 4e87b73bfb0..5a81672cb2a 100644 --- a/tests/misc/projects/Issue10844/user-defined-meta-json-indent-fail.hxml.stderr +++ b/tests/misc/projects/Issue10844/user-defined-meta-json-indent-fail.hxml.stderr @@ -1,3 +1,3 @@ (unknown) : Uncaught exception Could not read file meta.jsno - $$normPath(::std::)/haxe/macro/Compiler.hx:495: characters 11-39 : Called from here + $$normPath(::std::)/haxe/macro/Compiler.hx:390: characters 11-39 : Called from here (unknown) : Called from here diff --git a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr b/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr index 29619b177df..6c235767c49 100644 --- a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr +++ b/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr @@ -2,9 +2,9 @@ | Uncaught exception Could not read file meta.jsno - -> $$normPath(::std::)/haxe/macro/Compiler.hx:495: characters 11-39 + -> $$normPath(::std::)/haxe/macro/Compiler.hx:390: characters 11-39 - 495 | var f = sys.io.File.getContent(path); + 390 | var f = sys.io.File.getContent(path); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Called from here diff --git a/tests/misc/projects/Issue4660/Include.hx b/tests/misc/projects/Issue4660/Include.hx index f738186b431..90825a58f7e 100644 --- a/tests/misc/projects/Issue4660/Include.hx +++ b/tests/misc/projects/Issue4660/Include.hx @@ -1,5 +1,5 @@ class Include { static function use() { - haxe.macro.Compiler.includeFile("include.js", Top); + haxe.macro.Compiler.includeFile("include.js"); } } diff --git a/tests/misc/projects/Issue8567/compile.hxml b/tests/misc/projects/Issue8567/compile.hxml deleted file mode 100644 index eb9ce292099..00000000000 --- a/tests/misc/projects/Issue8567/compile.hxml +++ /dev/null @@ -1,3 +0,0 @@ --cp src --main Main ---macro patchTypes("src/test.txt") \ No newline at end of file diff --git a/tests/misc/projects/Issue8567/src/Main.hx b/tests/misc/projects/Issue8567/src/Main.hx deleted file mode 100644 index 17c7d3e7b5d..00000000000 --- a/tests/misc/projects/Issue8567/src/Main.hx +++ /dev/null @@ -1,4 +0,0 @@ -class Main { - static function main() { - } -} diff --git a/tests/misc/projects/Issue8567/src/test.txt b/tests/misc/projects/Issue8567/src/test.txt deleted file mode 100644 index e69de29bb2d..00000000000 From 2f56f2cb21bb13b8c4e8b73600dcc8873e8c29fb Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sat, 3 Feb 2024 18:01:58 +0100 Subject: [PATCH 10/20] don't recurse --- std/haxe/macro/Compiler.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/haxe/macro/Compiler.hx b/std/haxe/macro/Compiler.hx index 1ba1ed88e6f..c1996cfddaf 100644 --- a/std/haxe/macro/Compiler.hx +++ b/std/haxe/macro/Compiler.hx @@ -379,7 +379,7 @@ class Compiler { public static function addMetadata(meta:String, className:String, ?field:String, ?isStatic:Bool) { var pathFilter = field == null ? className : '$className.$field'; - addGlobalMetadata(pathFilter, meta, true, field == null, field != null); + addGlobalMetadata(pathFilter, meta, false, field == null, field != null); } /** From 23c865f56c92a7541fb70da927c7abfedfba9070 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 21:40:15 +0100 Subject: [PATCH 11/20] [tests] update test for #3500 --- tests/misc/projects/Issue3500/Main.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/misc/projects/Issue3500/Main.hx b/tests/misc/projects/Issue3500/Main.hx index 4b9e8577129..ba8e6f064b3 100644 --- a/tests/misc/projects/Issue3500/Main.hx +++ b/tests/misc/projects/Issue3500/Main.hx @@ -9,7 +9,7 @@ class Main { var t = haxe.macro.Context.getType("A"); switch (t) { case TAbstract(a, _): - var hasTestMeta = Lambda.exists(a.get().impl.get().meta.get(), function(m) return m.name == ":test"); + var hasTestMeta = Lambda.exists(a.get().meta.get(), function(m) return m.name == ":test"); if (!hasTestMeta) { fail("Abstract implementation class has no @:test metadata"); } From 769917217358d0b9d54e0ef9bd78aa3171b1019e Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 21:43:02 +0100 Subject: [PATCH 12/20] [typer] move abstract -> impl meta inheritance to after addGlobalMetadata --- src/typing/typeloadModule.ml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 35889603d3a..701dd8913ee 100644 --- a/src/typing/typeloadModule.ml +++ b/src/typing/typeloadModule.ml @@ -219,12 +219,6 @@ module ModuleLevel = struct let acc = make_decl acc (EClass { d_name = (fst d.d_name) ^ "_Impl_",snd d.d_name; d_flags = [HPrivate]; d_data = fields; d_doc = None; d_params = []; d_meta = !meta },p) in (match !decls with | (TClassDecl c,_) :: _ -> - List.iter (fun m -> match m with - | ((Meta.Using | Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.HlNative | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpGlobal | Meta.PublicFields),_,_) -> - c.cl_meta <- m :: c.cl_meta; - | _ -> - () - ) a.a_meta; a.a_impl <- Some c; c.cl_kind <- KAbstractImpl a; add_class_flag c CFinal; @@ -574,6 +568,14 @@ module TypeLevel = struct if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then DisplayEmitter.display_module_type ctx_m (TAbstractDecl a) (pos d.d_name); TypeloadCheck.check_global_metadata ctx_m a.a_meta (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None; + Option.may (fun c -> + List.iter (fun m -> match m with + | ((Meta.Using | Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.HlNative | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpGlobal | Meta.PublicFields),_,_) -> + c.cl_meta <- m :: c.cl_meta; + | _ -> + () + ) a.a_meta; + ) a.a_impl; let ctx_a = TyperManager.clone_for_abstract ctx_m a in let is_type = ref false in let load_type t from = From 75c573c588caf81f0f2d5f4a07485e4a54afd9b7 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:15:31 +0100 Subject: [PATCH 13/20] [tests] remove test with pretty errors that brings nothing but pain --- .../user-defined-meta-json-pretty-fail.hxml | 4 ---- .../user-defined-meta-json-pretty-fail.hxml.stderr | 12 ------------ 2 files changed, 16 deletions(-) delete mode 100644 tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml delete mode 100644 tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr diff --git a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml b/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml deleted file mode 100644 index 68353040073..00000000000 --- a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml +++ /dev/null @@ -1,4 +0,0 @@ -user-defined-meta-json-fail.hxml --D message.reporting=pretty --D message.no-color - diff --git a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr b/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr deleted file mode 100644 index 6c235767c49..00000000000 --- a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr +++ /dev/null @@ -1,12 +0,0 @@ -[ERROR] --macro haxe.macro.Compiler.registerMetadataDescriptionFile('meta.jsno', 'myapp') - - | Uncaught exception Could not read file meta.jsno - - -> $$normPath(::std::)/haxe/macro/Compiler.hx:390: characters 11-39 - - 390 | var f = sys.io.File.getContent(path); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Called from here - - | Called from here - From 48b51891485048c76dee9e6566e54c54d6eac814 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:15:50 +0100 Subject: [PATCH 14/20] [std] deprecate Compiler.addMetadata again --- std/haxe/macro/Compiler.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/std/haxe/macro/Compiler.hx b/std/haxe/macro/Compiler.hx index c1996cfddaf..854082e4e31 100644 --- a/std/haxe/macro/Compiler.hx +++ b/std/haxe/macro/Compiler.hx @@ -377,6 +377,7 @@ class Compiler { #end } + @:deprecated public static function addMetadata(meta:String, className:String, ?field:String, ?isStatic:Bool) { var pathFilter = field == null ? className : '$className.$field'; addGlobalMetadata(pathFilter, meta, false, field == null, field != null); From 2cecaff3f0492129cbfa920dcad190c527b29f52 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:16:34 +0100 Subject: [PATCH 15/20] [tests] misc tests: ignore position changes for std modules Closes #11539 --- tests/misc/src/Main.hx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 4f387cc95d1..63607bdd21a 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -151,6 +151,9 @@ class Main { .filter(s -> 0 != s.indexOf('Picked up JAVA_TOOL_OPTIONS:')) .join('\n'); + content = hideStdPositions(content); + expected = hideStdPositions(expected); + if (StringTools.startsWith(content, '{"jsonrpc":')) { try { content = haxe.Json.stringify(haxe.Json.parse(content).result.result); @@ -178,6 +181,15 @@ class Main { return true; } + static function hideStdPositions(content:String):String { + var std = Path.removeTrailingSlashes(getStd()); + var regex = new EReg(std + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + + return content.split("\n") + .map(line -> regex.replace(line, "$1:???:")) + .join("\n"); + } + static macro function getStd() { var std = Compiler.getConfiguration().stdPath; return macro $v{std.shift()}; From 8a255c841b33b602437f9aa5db57cb7c5a26c46a Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:27:02 +0100 Subject: [PATCH 16/20] [tests] improve std position hiding a bit --- tests/misc/src/Main.hx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 63607bdd21a..006fcfad174 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -151,15 +151,15 @@ class Main { .filter(s -> 0 != s.indexOf('Picked up JAVA_TOOL_OPTIONS:')) .join('\n'); - content = hideStdPositions(content); - expected = hideStdPositions(expected); - if (StringTools.startsWith(content, '{"jsonrpc":')) { try { content = haxe.Json.stringify(haxe.Json.parse(content).result.result); // Reorder fields from expected too expected = haxe.Json.stringify(haxe.Json.parse(expected)); } catch (_) {} + } else { + content = hideStdPositions(content); + expected = hideStdPositions(expected); } if (content != expected) { @@ -182,8 +182,7 @@ class Main { } static function hideStdPositions(content:String):String { - var std = Path.removeTrailingSlashes(getStd()); - var regex = new EReg(std + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + var regex = new EReg(getStd() + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); return content.split("\n") .map(line -> regex.replace(line, "$1:???:")) From 732be46cad4ac7edef88886d3612a71c726b54a7 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sun, 4 Feb 2024 08:10:27 +0100 Subject: [PATCH 17/20] remove all "Something went wrong" errors --- src/generators/genjvm.ml | 2 +- src/generators/genshared.ml | 9 +++++---- src/macro/eval/evalEmitter.ml | 4 ++-- src/macro/eval/evalExceptions.ml | 6 +++--- src/macro/eval/evalJit.ml | 2 +- src/typing/matcher/texprConverter.ml | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/generators/genjvm.ml b/src/generators/genjvm.ml index ca7cbfcb533..ea90c8c5868 100644 --- a/src/generators/genjvm.ml +++ b/src/generators/genjvm.ml @@ -1675,7 +1675,7 @@ class texpr_to_jvm info.super_call_fields <- tl; hd | _ -> - Error.raise_typing_error "Something went wrong" e1.epos + Error.raise_typing_error "Could not find field information for super call, please report this" e1.epos in let kind = get_construction_mode c cf in begin match kind with diff --git a/src/generators/genshared.ml b/src/generators/genshared.ml index aa6c7bab126..9aa67cea7b3 100644 --- a/src/generators/genshared.ml +++ b/src/generators/genshared.ml @@ -128,14 +128,15 @@ object(self) | None -> die "" __LOC__ | Some(c,_) -> c,cf in - let rec promote_this_before_super c cf = match self#get_field_info cf.cf_meta with - | None -> failwith "Something went wrong" + let rec promote_this_before_super c cf p = match self#get_field_info cf.cf_meta with + | None -> + Error.raise_typing_error (Printf.sprintf "Could not determine field information for %s in a this-before-super case, please report this" cf.cf_name) p | Some info -> if not info.has_this_before_super then begin make_haxe cf; (* print_endline (Printf.sprintf "promoted this_before_super to %s.new : %s" (s_type_path c.cl_path) (s_type (print_context()) cf.cf_type)); *) info.has_this_before_super <- true; - List.iter (fun (c,cf) -> promote_this_before_super c cf) info.super_call_fields + List.iter (fun (c,cf) -> promote_this_before_super c cf p) info.super_call_fields end in let rec loop e = @@ -153,7 +154,7 @@ object(self) (* print_endline (Printf.sprintf "inferred this_before_super on %s.new : %s" (s_type_path c.cl_path) (s_type (print_context()) cf.cf_type)); *) end; let c,cf = find_super_ctor el in - if !this_before_super then promote_this_before_super c cf; + if !this_before_super then promote_this_before_super c cf e.epos; DynArray.add super_call_fields (c,cf); | _ -> Type.iter loop e diff --git a/src/macro/eval/evalEmitter.ml b/src/macro/eval/evalEmitter.ml index 56de9326e61..7663674aac7 100644 --- a/src/macro/eval/evalEmitter.ml +++ b/src/macro/eval/evalEmitter.ml @@ -754,8 +754,8 @@ let process_arguments fl vl env = loop fl [] | [],[] -> () - | _ -> - exc_string "Something went wrong" + | l1,l2 -> + exc_string (Printf.sprintf "Bad number of arguments: %i vs. %i" (List.length l1) (List.length l2)) in loop fl vl [@@inline] diff --git a/src/macro/eval/evalExceptions.ml b/src/macro/eval/evalExceptions.ml index f1c146d98d6..b3954e20692 100644 --- a/src/macro/eval/evalExceptions.ml +++ b/src/macro/eval/evalExceptions.ml @@ -137,7 +137,7 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p = in (Error.Custom (value_string v1), v2) end else - Error.raise_typing_error "Something went wrong" null_pos + Error.raise_typing_error (Printf.sprintf "Unexpected value where haxe.macro.Error was expected: %s" (s_value 0 v).sstring) null_pos ) (EvalArray.to_list sub) | _ -> [] in @@ -165,8 +165,8 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p = | [] -> Error.raise_msg s.sstring p | _ -> Error.raise_error (Error.make_error ~sub:(List.map (fun (msg,p) -> Error.make_error msg p) stack) (Error.Custom s.sstring) p) ); - | _ -> - Error.raise_typing_error "Something went wrong" null_pos + | v -> + Error.raise_typing_error (Printf.sprintf "Invalid exception value where string was expected: %s" (s_value 0 v).sstring) null_pos end else begin (* Careful: We have to get the message before resetting the context because toString() might access it. *) let stack = match eval_stack with diff --git a/src/macro/eval/evalJit.ml b/src/macro/eval/evalJit.ml index d2c21a539a1..89c428641ce 100644 --- a/src/macro/eval/evalJit.ml +++ b/src/macro/eval/evalJit.ml @@ -235,7 +235,7 @@ and jit_expr jit return e = List.iter (fun var -> ignore(get_capture_slot jit var)) jit_closure.captures_outside_scope; let captures = ExtList.List.filter_map (fun (i,vid,declared) -> if declared then None - else Some (i,fst (try Hashtbl.find jit.captures vid with Not_found -> Error.raise_typing_error "Something went wrong" e.epos)) + else Some (i,fst (try Hashtbl.find jit.captures vid with Not_found -> Error.raise_typing_error (Printf.sprintf "Could not find capture variable %i" vid) e.epos)) ) captures in let mapping = Array.of_list captures in emit_closure ctx mapping eci hasret exec fl diff --git a/src/typing/matcher/texprConverter.ml b/src/typing/matcher/texprConverter.ml index 87f92657803..dfe269d63f9 100644 --- a/src/typing/matcher/texprConverter.ml +++ b/src/typing/matcher/texprConverter.ml @@ -25,7 +25,7 @@ let constructor_to_texpr ctx con = | ConArray i -> make_int ctx.com.basic i p | ConTypeExpr mt -> TyperBase.type_module_type ctx mt p | ConStatic(c,cf) -> make_static_field c cf p - | ConFields _ -> raise_typing_error "Something went wrong" p + | ConFields _ -> raise_typing_error "Unexpected matching on ConFields, please report this" p let s_subject v_lookup s e = let rec loop top s e = match e.eexpr with From 782c520c556a9f2f8769da448f6ad7e2c48a5ceb Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sun, 4 Feb 2024 08:34:25 +0100 Subject: [PATCH 18/20] [tests] well ofc there's windows too.. --- tests/misc/src/Main.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 006fcfad174..67684712571 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -182,7 +182,7 @@ class Main { } static function hideStdPositions(content:String):String { - var regex = new EReg(getStd() + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + var regex = new EReg(getStd() + '([a-z/\\\\]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); return content.split("\n") .map(line -> regex.replace(line, "$1:???:")) From 61fae054de31a5f04070263d2caa5859f1248d04 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sun, 4 Feb 2024 09:21:41 +0100 Subject: [PATCH 19/20] [tests] need to escape those slashes on windows --- tests/misc/src/Main.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 67684712571..7e05e1da364 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -182,7 +182,7 @@ class Main { } static function hideStdPositions(content:String):String { - var regex = new EReg(getStd() + '([a-z/\\\\]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + var regex = new EReg(StringTools.replace(getStd(), '\\', '(?:\\\\|/)') + '([a-z/\\\\]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); return content.split("\n") .map(line -> regex.replace(line, "$1:???:")) From c55da75267dbe1c6011432a1b30644da2b7ba79d Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sun, 4 Feb 2024 13:44:36 +0100 Subject: [PATCH 20/20] [typer] don't consider @:structInit + @:from when inferring closes #11535 --- src/typing/matcher/exprToPattern.ml | 2 +- src/typing/typer.ml | 30 +++++++++------------ src/typing/typerBase.ml | 8 ++++-- tests/unit/src/unit/issues/Issue11535.hx | 34 ++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 tests/unit/src/unit/issues/Issue11535.hx diff --git a/src/typing/matcher/exprToPattern.ml b/src/typing/matcher/exprToPattern.ml index 3db86b92e1a..4ca68a1c4a2 100644 --- a/src/typing/matcher/exprToPattern.ml +++ b/src/typing/matcher/exprToPattern.ml @@ -315,7 +315,7 @@ let rec make pctx toplevel t e = PatConstructor(con_array (List.length patterns) (pos e),patterns) | TAbstract(a,tl) as t when not (List.exists (fun t' -> shallow_eq t t') seen) -> begin match TyperBase.get_abstract_froms ctx a tl with - | [t2] -> pattern (t :: seen) t2 + | [(_,t2)] -> pattern (t :: seen) t2 | _ -> fail() end | _ -> diff --git a/src/typing/typer.ml b/src/typing/typer.ml index 13aca40a8de..57778ec4f16 100644 --- a/src/typing/typer.ml +++ b/src/typing/typer.ml @@ -96,7 +96,7 @@ let maybe_type_against_enum ctx f with_type iscall p = false,a.a_path,fields,TAbstractDecl a | TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> begin match get_abstract_froms ctx a pl with - | [t2] -> + | [(_,t2)] -> if (List.exists (shallow_eq t) stack) then raise Exit; loop (t :: stack) t2 | _ -> raise Exit @@ -782,14 +782,15 @@ and type_object_decl ctx fl with_type p = let dynamic_parameter = ref None in let a = (match with_type with | WithType.WithType(t,_) -> - let rec loop seen t = + let rec loop had_cast seen t = match follow t with - | TAnon a -> ODKWithStructure a + | TAnon a -> + ODKWithStructure a | TAbstract (a,pl) as t when not (Meta.has Meta.CoreType a.a_meta) && not (List.exists (fun t' -> shallow_eq t t') seen) -> let froms = get_abstract_froms ctx a pl in - let fold = fun acc t' -> match loop (t :: seen) t' with ODKPlain -> acc | t -> t :: acc in + let fold = fun acc (fk,t') -> match loop (fk = FromField) (t :: seen) t' with ODKPlain -> acc | t -> t :: acc in begin match List.fold_left fold [] froms with | [] -> ODKPlain (* If the abstract has no casts in the first place, we can assume plain typing (issue #10730) *) | [t] -> t @@ -801,12 +802,12 @@ and type_object_decl ctx fl with_type p = a_status = ref Closed; a_fields = PMap.empty; } - | TInst(c,tl) when Meta.has Meta.StructInit c.cl_meta -> + | TInst(c,tl) when not had_cast && Meta.has Meta.StructInit c.cl_meta -> ODKWithClass(c,tl) | _ -> ODKPlain in - loop [] t + loop false [] t | _ -> ODKPlain ) in @@ -1296,14 +1297,14 @@ and type_local_function ctx kind f with_type p = maybe_unify_ret tr | TAbstract(a,tl) -> begin match get_abstract_froms ctx a tl with - | [t2] -> + | [(_,t2)] -> if not (List.exists (shallow_eq t) stack) then loop (t :: stack) t2 | l -> (* For cases like nested EitherType, we want a flat list of all possible candidates. This might be controversial because those could be considered transitive casts, but it's unclear if that's a bad thing for this kind of inference (issue #10982). *) let rec loop stack acc l = match l with - | t :: l -> + | (_,t) :: l -> begin match follow t with | TAbstract(a,tl) as t when not (List.exists (shallow_eq t) stack) -> loop (t :: stack) acc (l @ get_abstract_froms ctx a tl) @@ -1398,15 +1399,10 @@ and type_array_decl ctx el with_type p = with Not_found -> None) | TAbstract (a,pl) as t when not (List.exists (fun t' -> shallow_eq t t') seen) -> - let types = - List.fold_left - (fun acc t' -> match loop (t :: seen) t' with - | None -> acc - | Some t -> t :: acc - ) - [] - (get_abstract_froms ctx a pl) - in + let types = List.fold_left (fun acc (_,t') -> match loop (t :: seen) t' with + | None -> acc + | Some t -> t :: acc + ) [] (get_abstract_froms ctx a pl) in (match types with | [t] -> Some t | _ -> None) diff --git a/src/typing/typerBase.ml b/src/typing/typerBase.ml index 829ad9fa104..fa7bdefb8e2 100644 --- a/src/typing/typerBase.ml +++ b/src/typing/typerBase.ml @@ -330,8 +330,12 @@ let unify_static_extension ctx e t p = e end +type from_kind = + | FromType + | FromField + let get_abstract_froms ctx a pl = - let l = List.map (apply_params a.a_params pl) a.a_from in + let l = List.map (fun t -> FromType,apply_params a.a_params pl t) a.a_from in List.fold_left (fun acc (t,f) -> (* We never want to use the @:from we're currently in because that's recursive (see #10604) *) if f == ctx.f.curfield then @@ -342,7 +346,7 @@ let get_abstract_froms ctx a pl = | TFun ([_,_,v],t) -> (try ignore(type_eq EqStrict t (TAbstract(a,List.map duplicate pl))); (* unify fields monomorphs *) - v :: acc + (FromField,v) :: acc with Unify_error _ -> acc) | _ -> diff --git a/tests/unit/src/unit/issues/Issue11535.hx b/tests/unit/src/unit/issues/Issue11535.hx new file mode 100644 index 00000000000..2ce98ab3245 --- /dev/null +++ b/tests/unit/src/unit/issues/Issue11535.hx @@ -0,0 +1,34 @@ +package unit.issues; + +@:structInit +private class BarImpl { + public function new() {} +} + +@:structInit +private class FooImpl { + public var x:Int; + + public function new(x:Int) { + this.x = x; + } +} + +@:forward +private abstract Foo(FooImpl) from FooImpl to FooImpl { + public function new(x:Int) { + this = new FooImpl(x); + } + + @:from + static public function fromVec4(v:BarImpl):Foo { + return new Foo(1); + } +} + +class Issue11535 extends Test { + function test() { + var v:Foo = {x: 2}; + eq(2, v.x); + } +}