From bf329ea9d3805162266345a72b15d95e9b60e408 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sun, 28 Jan 2024 12:30:37 +0100 Subject: [PATCH 01/32] group com.main/main_class --- src/compiler/args.ml | 8 ++++---- src/compiler/compiler.ml | 4 ++-- src/compiler/displayProcessing.ml | 4 ++-- src/context/common.ml | 23 ++++++++++++++++------- src/generators/gencpp.ml | 6 +++--- src/generators/genhl.ml | 2 +- src/generators/genjs.ml | 2 +- src/generators/genlua.ml | 2 +- src/generators/genneko.ml | 2 +- src/generators/genphp7.ml | 2 +- src/generators/genpy.ml | 2 +- src/generators/genswf9.ml | 4 ++-- src/macro/eval/evalStdLib.ml | 2 +- src/macro/macroApi.ml | 6 +++--- src/typing/finalization.ml | 2 +- src/typing/macroContext.ml | 3 +-- 16 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/compiler/args.ml b/src/compiler/args.ml index 81721e90f68..1f7d09b0d00 100644 --- a/src/compiler/args.ml +++ b/src/compiler/args.ml @@ -111,9 +111,9 @@ let parse_args com = ),"","generate code for a custom target"); ("Target",[],["-x"], Arg.String (fun cl -> let cpath = Path.parse_type_path cl in - (match com.main_class with + (match com.main.main_class with | Some c -> if cpath <> c then raise (Arg.Bad "Multiple --main classes specified") - | None -> com.main_class <- Some cpath); + | None -> com.main.main_class <- Some cpath); actx.classes <- cpath :: actx.classes; Common.define com Define.Interp; set_platform com Eval ""; @@ -138,9 +138,9 @@ let parse_args com = actx.hxb_libs <- lib :: actx.hxb_libs ),"","add a hxb library"); ("Compilation",["-m";"--main"],["-main"],Arg.String (fun cl -> - if com.main_class <> None then raise (Arg.Bad "Multiple --main classes specified"); + if com.main.main_class <> None then raise (Arg.Bad "Multiple --main classes specified"); let cpath = Path.parse_type_path cl in - com.main_class <- Some cpath; + com.main.main_class <- Some cpath; actx.classes <- cpath :: actx.classes ),"","select startup class"); ("Compilation",["-L";"--library"],["-lib"],Arg.String (fun _ -> ()),"","use a haxelib library"); diff --git a/src/compiler/compiler.ml b/src/compiler/compiler.ml index 078b63fa1a7..3654a6e0a5d 100644 --- a/src/compiler/compiler.ml +++ b/src/compiler/compiler.ml @@ -336,7 +336,7 @@ let finalize_typing ctx tctx = enter_stage com CFilteringStart; ServerMessage.compiler_stage com; let main, types, modules = run_or_diagnose ctx (fun () -> Finalization.generate tctx) in - com.main <- main; + com.main.main_expr <- main; com.types <- types; com.modules <- modules; t() @@ -344,7 +344,7 @@ let finalize_typing ctx tctx = let filter ctx tctx before_destruction = let t = Timer.timer ["filters"] in DeprecationCheck.run ctx.com; - run_or_diagnose ctx (fun () -> Filters.run tctx ctx.com.main before_destruction); + run_or_diagnose ctx (fun () -> Filters.run tctx ctx.com.main.main_expr before_destruction); t() let compile ctx actx callbacks = diff --git a/src/compiler/displayProcessing.ml b/src/compiler/displayProcessing.ml index 29e1fccbf46..d2dde9cef58 100644 --- a/src/compiler/displayProcessing.ml +++ b/src/compiler/displayProcessing.ml @@ -143,7 +143,7 @@ let process_display_file com actx = DPKNone | DFPOnly when (DisplayPosition.display_position#get).pfile = file_input_marker -> actx.classes <- []; - com.main_class <- None; + com.main.main_class <- None; begin match com.file_contents with | [_, Some input] -> com.file_contents <- []; @@ -154,7 +154,7 @@ let process_display_file com actx = | dfp -> if dfp = DFPOnly then begin actx.classes <- []; - com.main_class <- None; + com.main.main_class <- None; end; let real = Path.get_real_path (DisplayPosition.display_position#get).pfile in let path = match get_module_path_from_file_path com real with diff --git a/src/context/common.ml b/src/context/common.ml index 6512b412c52..59359f5d01a 100644 --- a/src/context/common.ml +++ b/src/context/common.ml @@ -340,6 +340,11 @@ class virtual abstract_hxb_lib = object(self) method virtual get_file_path : string end +type context_main = { + mutable main_class : path option; + mutable main_expr : texpr option; +} + type context = { compilation_step : int; mutable stage : compiler_stage; @@ -359,7 +364,7 @@ type context = { mutable config : platform_config; empty_class_path : ClassPath.class_path; class_paths : ClassPaths.class_paths; - mutable main_class : path option; + main : context_main; mutable package_rules : (string,package_rule) PMap.t; mutable report_mode : report_mode; (* communication *) @@ -400,7 +405,6 @@ type context = { mutable file : string; mutable features : (string,bool) Hashtbl.t; mutable modules : Type.module_def list; - mutable main : Type.texpr option; mutable types : Type.module_type list; mutable resources : (string,string) Hashtbl.t; (* target-specific *) @@ -819,7 +823,10 @@ let create compilation_step cs version args display_mode = run_command_args = (fun s args -> com.run_command (Printf.sprintf "%s %s" s (String.concat " " args))); empty_class_path = new ClassPath.directory_class_path "" User; class_paths = new ClassPaths.class_paths; - main_class = None; + main = { + main_class = None; + main_expr = None; + }; package_rules = PMap.empty; file = ""; types = []; @@ -828,7 +835,6 @@ let create compilation_step cs version args display_mode = modules = []; module_lut = new module_lut; module_nonexistent_lut = new hashtbl_lookup; - main = None; flash_version = 10.; resources = Hashtbl.create 0; net_std = []; @@ -907,7 +913,10 @@ let clone com is_macro_context = tbool = mk_mono(); tstring = mk_mono(); }; - main_class = None; + main = { + main_class = None; + main_expr = None; + }; features = Hashtbl.create 0; callbacks = new compiler_callbacks; display_information = { @@ -1231,6 +1240,6 @@ let get_entry_point com = | Some c when (PMap.mem "main" c.cl_statics) -> c | _ -> Option.get (ExtList.List.find_map (fun t -> match t with TClassDecl c when c.cl_path = path -> Some c | _ -> None) m.m_types) in - let e = Option.get com.main in (* must be present at this point *) + let e = Option.get com.main.main_expr in (* must be present at this point *) (snd path, c, e) - ) com.main_class + ) com.main.main_class diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index a5c7a2d965b..05fcb19cf10 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -8478,7 +8478,7 @@ let generate_cppia ctx = ); ) common_ctx.types; - (match common_ctx.main with + (match common_ctx.main.main_expr with | None -> script#writeOpLine IaNoMain; | Some e -> script#writeOpLine IaMain; script#gen_expression e @@ -8590,7 +8590,7 @@ let generate_source ctx = List.iter (fun job -> job () ) !jobs; - (match common_ctx.main with + (match common_ctx.main.main_expr with | None -> generate_dummy_main common_ctx | Some e -> let main_field = { (mk_field "__main__" t_dynamic e.epos null_pos) with @@ -8653,7 +8653,7 @@ let generate_source ctx = end; end; - let output_name = match common_ctx.main_class with + let output_name = match common_ctx.main.main_class with | Some path -> (snd path) | _ -> "output" in diff --git a/src/generators/genhl.ml b/src/generators/genhl.ml index ccfbb8d028d..e3ba1481b68 100644 --- a/src/generators/genhl.ml +++ b/src/generators/genhl.ml @@ -4187,7 +4187,7 @@ let generate com = let ctx = create_context com false dump in add_types ctx com.types; - let code = build_code ctx com.types com.main in + let code = build_code ctx com.types com.main.main_expr in Array.sort (fun (lib1,_,_,_) (lib2,_,_,_) -> lib1 - lib2) code.natives; if dump then begin (match ctx.dump_out with None -> () | Some ch -> IO.close_out ch); diff --git a/src/generators/genjs.ml b/src/generators/genjs.ml index 72ab5dad9c6..05eae361308 100644 --- a/src/generators/genjs.ml +++ b/src/generators/genjs.ml @@ -1970,7 +1970,7 @@ let generate com = end; List.iter (gen_block_element ~newline_after:true ~keep_blocks:(ctx.es_version >= 6) ctx) (List.rev ctx.inits); List.iter (generate_static ctx) (List.rev ctx.statics); - (match com.main with + (match com.main.main_expr with | None -> () | Some e -> gen_expr ctx e; newline ctx); if ctx.js_modern then begin diff --git a/src/generators/genlua.ml b/src/generators/genlua.ml index 9811be22a5d..176185edbcf 100644 --- a/src/generators/genlua.ml +++ b/src/generators/genlua.ml @@ -2200,7 +2200,7 @@ let generate com = gen_value ctx { e with eexpr = TFunction fn; etype = TFun ([],com.basic.tvoid) }; println ctx ", _hx_handle_error)"; println ctx "if not success then _G.error(err) end"; - ) com.main; + ) com.main.main_expr; if anyExposed then println ctx "return _hx_exports"; diff --git a/src/generators/genneko.ml b/src/generators/genneko.ml index 27c81c1f116..ce081ea0f7b 100644 --- a/src/generators/genneko.ml +++ b/src/generators/genneko.ml @@ -780,7 +780,7 @@ let generate com = { psource = "
"; pline = 1; } ) in let el = build ctx com.types in - let emain = (match com.main with None -> [] | Some e -> [gen_expr ctx e]) in + let emain = (match com.main.main_expr with None -> [] | Some e -> [gen_expr ctx e]) in let e = (EBlock ((header()) @ libs :: el @ emain), null_pos) in let source = Common.defined com Define.NekoSource in let use_nekoc = Common.defined com Define.UseNekoc in diff --git a/src/generators/genphp7.ml b/src/generators/genphp7.ml index 0b242cf982a..c36622206ff 100644 --- a/src/generators/genphp7.ml +++ b/src/generators/genphp7.ml @@ -4038,7 +4038,7 @@ class generator (ctx:php_generator_context) = Returns PHP code for entry point *) method private get_entry_point : (string * string) option = - match ctx.pgc_common.main with + match ctx.pgc_common.main.main_expr with | None -> None | Some expr -> let writer = new code_writer ctx ([], "") "" in diff --git a/src/generators/genpy.ml b/src/generators/genpy.ml index ab9168472e7..1a59a94fb3e 100644 --- a/src/generators/genpy.ml +++ b/src/generators/genpy.ml @@ -2410,7 +2410,7 @@ module Generator = struct List.iter (fun f -> f()) (List.rev ctx.class_inits) let gen_main ctx = - match ctx.com.main with + match ctx.com.main.main_expr with | None -> () | Some e -> diff --git a/src/generators/genswf9.ml b/src/generators/genswf9.ml index 061f47f148b..6495c7a7456 100644 --- a/src/generators/genswf9.ml +++ b/src/generators/genswf9.ml @@ -2007,7 +2007,7 @@ let generate_inits ctx = j() | _ -> () ) ctx.com.types; - (match ctx.com.main with + (match ctx.com.main.main_expr with | None -> () | Some e -> gen_expr ctx false e); write ctx HRetVoid; @@ -2888,7 +2888,7 @@ let generate com boot_name = try_scope_reg = None; for_call = false; } in - let types = if ctx.swc && com.main_class = None then + let types = if ctx.swc && com.main.main_class = None then (* make sure that both Boot and RealBoot are the first two classes in the SWC this way initializing RealBoot will also run externs __init__ blocks before diff --git a/src/macro/eval/evalStdLib.ml b/src/macro/eval/evalStdLib.ml index 7cdb911bb58..9212e689728 100644 --- a/src/macro/eval/evalStdLib.ml +++ b/src/macro/eval/evalStdLib.ml @@ -2632,7 +2632,7 @@ module StdSys = struct let programPath = vfun0 (fun () -> let ctx = get_ctx() in let com = ctx.curapi.get_com() in - match com.main_class with + match com.main.main_class with | None -> vnull | Some p -> match ctx.curapi.get_type (s_type_path p) with diff --git a/src/macro/macroApi.ml b/src/macro/macroApi.ml index 818ac473346..bea386127d7 100644 --- a/src/macro/macroApi.ml +++ b/src/macro/macroApi.ml @@ -2021,7 +2021,7 @@ let macro_api ccom get_api = let api = encode_obj [ "outputFile", encode_string com.file; "types", encode_array (List.map (fun t -> encode_type (type_of_module_type t)) com.types); - "main", (match com.main with None -> vnull | Some e -> encode_texpr e); + "main", (match com.main.main_expr with None -> vnull | Some e -> encode_texpr e); "generateValue", vfun1 (fun v -> let e = decode_texpr v in let str = Genjs.gen_single_expr js_ctx e false in @@ -2253,7 +2253,7 @@ let macro_api ccom get_api = "platform", encode_platform com.platform; "platformConfig", encode_platform_config com.config; "stdPath", encode_array (List.map (fun path -> encode_string path#path) com.class_paths#get_std_paths); - "mainClass", (match com.main_class with None -> vnull | Some path -> encode_path path); + "mainClass", (match com.main.main_class with None -> vnull | Some path -> encode_path path); "packageRules", encode_string_map encode_package_rule com.package_rules; ] ); @@ -2262,7 +2262,7 @@ let macro_api ccom get_api = vnull ); "get_main_expr", vfun0 (fun() -> - match (ccom()).main with None -> vnull | Some e -> encode_texpr e + match (ccom()).main.main_expr with None -> vnull | Some e -> encode_texpr e ); "get_module_types", vfun0 (fun() -> encode_array (List.map encode_module_type (ccom()).types) diff --git a/src/typing/finalization.ml b/src/typing/finalization.ml index 7ce75e2a14c..61953a43f75 100644 --- a/src/typing/finalization.ml +++ b/src/typing/finalization.ml @@ -9,7 +9,7 @@ open Typecore (* FINALIZATION *) let get_main ctx types = - match ctx.com.main_class with + match ctx.com.main.main_class with | None -> None | Some path -> let p = null_pos in diff --git a/src/typing/macroContext.ml b/src/typing/macroContext.ml index a9b0252c67d..5a826098df5 100644 --- a/src/typing/macroContext.ml +++ b/src/typing/macroContext.ml @@ -702,7 +702,6 @@ let create_macro_context com = let com2 = Common.clone com true in com.get_macros <- (fun() -> Some com2); com2.package_rules <- PMap.empty; - com2.main_class <- None; (* Inherit most display settings, but require normal typing. *) com2.display <- {com.display with dms_kind = DMNone; dms_full_typing = true; dms_force_macro_typing = true; dms_inline = true; }; com2.class_paths#lock_context "macro" false; @@ -1070,7 +1069,7 @@ let interpret ctx = let mctx = get_macro_context ctx in let mctx = Interp.create ctx.com (make_macro_api ctx mctx null_pos) false in Interp.add_types mctx ctx.com.types (fun t -> ()); - match ctx.com.main with + match ctx.com.main.main_expr with | None -> () | Some e -> ignore(Interp.eval_expr mctx e) From b614185627e4c74457ecbde89c87b1c1ad983320 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 08:25:04 +0100 Subject: [PATCH 02/32] [tests] add test for 10783 closes #10783 --- tests/unit/src/unit/issues/Issue10783.hx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/unit/src/unit/issues/Issue10783.hx diff --git a/tests/unit/src/unit/issues/Issue10783.hx b/tests/unit/src/unit/issues/Issue10783.hx new file mode 100644 index 00000000000..c7ce2c8d41e --- /dev/null +++ b/tests/unit/src/unit/issues/Issue10783.hx @@ -0,0 +1,17 @@ +package unit.issues; + +class Issue10783 extends Test { + function test() { + eq(4, log2Unsigned(16)); + } + + @:pure inline function log2Unsigned(n:Int):Int { + var res = 0; + + while ((n >>>= 1) != 0) { + res++; + } + + return res; + } +} From 395b5eb117d210930d6775af857bcfbe503da1cf Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 09:11:26 +0100 Subject: [PATCH 03/32] [diagnostics] use correct position for alias imports closes #11516 --- src/context/display/importHandling.ml | 2 +- tests/server/src/cases/issues/Issue11516.hx | 12 ++++++++++++ .../test/templates/issues/Issue11516/Importson.hx | 7 +++++++ .../test/templates/retyper/AbstractWithDependency.hx | 5 ----- .../retyper/AbstractWithSignatureDependency.hx | 3 --- tests/server/test/templates/retyper/DependentEnum.hx | 3 --- .../test/templates/retyper/DependentTypedef.hx | 1 - .../server/test/templates/retyper/IndependentEnum.hx | 9 --------- .../test/templates/retyper/IndependentTypedef.hx | 7 ------- .../test/templates/retyper/InterfaceDependency.hx | 1 - .../test/templates/retyper/MutualDependency.hx | 5 ----- .../templates/retyper/WithInterfaceDependency.hx | 1 - .../test/templates/retyper/WithMutualDependency.hx | 7 ------- .../test/templates/retyper/WithParentDependency.hx | 1 - .../templates/retyper/WithSignatureDependency.hx | 3 --- .../retyper/WithSignatureDependencyInferredArg.hx | 5 ----- .../WithSignatureDependencyInferredProperty.hx | 3 --- .../retyper/WithSignatureDependencyInferredRet.hx | 5 ----- .../WithSignatureDependencyInferredVariable.hx | 3 --- .../retyper/WithSignatureDependencyProperty.hx | 3 --- .../retyper/WithSignatureDependencyVariable.hx | 3 --- 21 files changed, 20 insertions(+), 69 deletions(-) create mode 100644 tests/server/src/cases/issues/Issue11516.hx create mode 100644 tests/server/test/templates/issues/Issue11516/Importson.hx delete mode 100644 tests/server/test/templates/retyper/AbstractWithDependency.hx delete mode 100644 tests/server/test/templates/retyper/AbstractWithSignatureDependency.hx delete mode 100644 tests/server/test/templates/retyper/DependentEnum.hx delete mode 100644 tests/server/test/templates/retyper/DependentTypedef.hx delete mode 100644 tests/server/test/templates/retyper/IndependentEnum.hx delete mode 100644 tests/server/test/templates/retyper/IndependentTypedef.hx delete mode 100644 tests/server/test/templates/retyper/InterfaceDependency.hx delete mode 100644 tests/server/test/templates/retyper/MutualDependency.hx delete mode 100644 tests/server/test/templates/retyper/WithInterfaceDependency.hx delete mode 100644 tests/server/test/templates/retyper/WithMutualDependency.hx delete mode 100644 tests/server/test/templates/retyper/WithParentDependency.hx delete mode 100644 tests/server/test/templates/retyper/WithSignatureDependency.hx delete mode 100644 tests/server/test/templates/retyper/WithSignatureDependencyInferredArg.hx delete mode 100644 tests/server/test/templates/retyper/WithSignatureDependencyInferredProperty.hx delete mode 100644 tests/server/test/templates/retyper/WithSignatureDependencyInferredRet.hx delete mode 100644 tests/server/test/templates/retyper/WithSignatureDependencyInferredVariable.hx delete mode 100644 tests/server/test/templates/retyper/WithSignatureDependencyProperty.hx delete mode 100644 tests/server/test/templates/retyper/WithSignatureDependencyVariable.hx diff --git a/src/context/display/importHandling.ml b/src/context/display/importHandling.ml index 1986d5b8976..cb7e9f42367 100644 --- a/src/context/display/importHandling.ml +++ b/src/context/display/importHandling.ml @@ -152,7 +152,7 @@ let init_import ctx path mode p = | Some(newname,pname) -> let mt = get_type tname in check_alias mt newname pname; - ctx.m.import_resolution#add (module_type_resolution mt (Some newname) p2) + ctx.m.import_resolution#add (module_type_resolution mt (Some newname) p) end | [tsub,p2] -> let pu = punion p1 p2 in diff --git a/tests/server/src/cases/issues/Issue11516.hx b/tests/server/src/cases/issues/Issue11516.hx new file mode 100644 index 00000000000..b37db566a83 --- /dev/null +++ b/tests/server/src/cases/issues/Issue11516.hx @@ -0,0 +1,12 @@ +package cases.issues; + +class Issue11516 extends TestCase { + function testClass(_) { + vfs.putContent("Importson.hx", getTemplate("issues/Issue11516/Importson.hx")); + var args = ["Importson", "--interp"]; + runHaxe(args); + runHaxeJsonCb(args, DisplayMethods.Diagnostics, {file: new FsPath("Importson.hx")}, res -> { + Assert.equals(0, res.length); + }); + } +} diff --git a/tests/server/test/templates/issues/Issue11516/Importson.hx b/tests/server/test/templates/issues/Issue11516/Importson.hx new file mode 100644 index 00000000000..fecef6175dd --- /dev/null +++ b/tests/server/test/templates/issues/Issue11516/Importson.hx @@ -0,0 +1,7 @@ +import haxe.Json as Son; + +class Importson { + static function main() { + Son.parse(null); + } +} diff --git a/tests/server/test/templates/retyper/AbstractWithDependency.hx b/tests/server/test/templates/retyper/AbstractWithDependency.hx deleted file mode 100644 index 98672a38bef..00000000000 --- a/tests/server/test/templates/retyper/AbstractWithDependency.hx +++ /dev/null @@ -1,5 +0,0 @@ -abstract AbstractWithDependency(String) { - public static function notMain() { - trace(Dependency.get()); - } -} diff --git a/tests/server/test/templates/retyper/AbstractWithSignatureDependency.hx b/tests/server/test/templates/retyper/AbstractWithSignatureDependency.hx deleted file mode 100644 index 44665fce269..00000000000 --- a/tests/server/test/templates/retyper/AbstractWithSignatureDependency.hx +++ /dev/null @@ -1,3 +0,0 @@ -abstract AbstractWithSignatureDependency(String) { - public static function test(d:Dependency) {} -} diff --git a/tests/server/test/templates/retyper/DependentEnum.hx b/tests/server/test/templates/retyper/DependentEnum.hx deleted file mode 100644 index d2ae45b2c62..00000000000 --- a/tests/server/test/templates/retyper/DependentEnum.hx +++ /dev/null @@ -1,3 +0,0 @@ -enum DependentEnum { - Constructor(s:Dependency); -} diff --git a/tests/server/test/templates/retyper/DependentTypedef.hx b/tests/server/test/templates/retyper/DependentTypedef.hx deleted file mode 100644 index 430926ec51d..00000000000 --- a/tests/server/test/templates/retyper/DependentTypedef.hx +++ /dev/null @@ -1 +0,0 @@ -typedef DependentTypedef = Dependency; diff --git a/tests/server/test/templates/retyper/IndependentEnum.hx b/tests/server/test/templates/retyper/IndependentEnum.hx deleted file mode 100644 index 7bac0b72a09..00000000000 --- a/tests/server/test/templates/retyper/IndependentEnum.hx +++ /dev/null @@ -1,9 +0,0 @@ -enum IndependentEnum { - Constructor(s:String); -} - -class MakeDependency { - static function f() { - Dependency.get(); - } -} diff --git a/tests/server/test/templates/retyper/IndependentTypedef.hx b/tests/server/test/templates/retyper/IndependentTypedef.hx deleted file mode 100644 index f79493af894..00000000000 --- a/tests/server/test/templates/retyper/IndependentTypedef.hx +++ /dev/null @@ -1,7 +0,0 @@ -typedef IndependentTypedef = String; - -class MakeDependency { - static function f() { - Dependency.get(); - } -} diff --git a/tests/server/test/templates/retyper/InterfaceDependency.hx b/tests/server/test/templates/retyper/InterfaceDependency.hx deleted file mode 100644 index 41f14634ac1..00000000000 --- a/tests/server/test/templates/retyper/InterfaceDependency.hx +++ /dev/null @@ -1 +0,0 @@ -interface InterfaceDependency {} diff --git a/tests/server/test/templates/retyper/MutualDependency.hx b/tests/server/test/templates/retyper/MutualDependency.hx deleted file mode 100644 index 31ec3dac92b..00000000000 --- a/tests/server/test/templates/retyper/MutualDependency.hx +++ /dev/null @@ -1,5 +0,0 @@ -class MutualDependency { - static public function get() { - return WithMutualDependency.value; - } -} diff --git a/tests/server/test/templates/retyper/WithInterfaceDependency.hx b/tests/server/test/templates/retyper/WithInterfaceDependency.hx deleted file mode 100644 index 6de758476a8..00000000000 --- a/tests/server/test/templates/retyper/WithInterfaceDependency.hx +++ /dev/null @@ -1 +0,0 @@ -class WithInterfaceDependency implements InterfaceDependency {} diff --git a/tests/server/test/templates/retyper/WithMutualDependency.hx b/tests/server/test/templates/retyper/WithMutualDependency.hx deleted file mode 100644 index 8f42bbcf31f..00000000000 --- a/tests/server/test/templates/retyper/WithMutualDependency.hx +++ /dev/null @@ -1,7 +0,0 @@ -class WithMutualDependency { - static public var value = "Hello World"; - - public static function main() { - trace(MutualDependency.get()); - } -} diff --git a/tests/server/test/templates/retyper/WithParentDependency.hx b/tests/server/test/templates/retyper/WithParentDependency.hx deleted file mode 100644 index 07d6d8fdb6a..00000000000 --- a/tests/server/test/templates/retyper/WithParentDependency.hx +++ /dev/null @@ -1 +0,0 @@ -class WithParentDependency extends Dependency {} diff --git a/tests/server/test/templates/retyper/WithSignatureDependency.hx b/tests/server/test/templates/retyper/WithSignatureDependency.hx deleted file mode 100644 index 4fab1e39ad8..00000000000 --- a/tests/server/test/templates/retyper/WithSignatureDependency.hx +++ /dev/null @@ -1,3 +0,0 @@ -class WithSignatureDependency { - public static function test(d:Dependency) {} -} diff --git a/tests/server/test/templates/retyper/WithSignatureDependencyInferredArg.hx b/tests/server/test/templates/retyper/WithSignatureDependencyInferredArg.hx deleted file mode 100644 index 0d71cf928d0..00000000000 --- a/tests/server/test/templates/retyper/WithSignatureDependencyInferredArg.hx +++ /dev/null @@ -1,5 +0,0 @@ -class WithSignatureDependency { - public static function test(d) { - d = new Dependency(); - } -} diff --git a/tests/server/test/templates/retyper/WithSignatureDependencyInferredProperty.hx b/tests/server/test/templates/retyper/WithSignatureDependencyInferredProperty.hx deleted file mode 100644 index ca47aa5f6f6..00000000000 --- a/tests/server/test/templates/retyper/WithSignatureDependencyInferredProperty.hx +++ /dev/null @@ -1,3 +0,0 @@ -class WithSignatureDependency { - public static var test(default, null) = new Dependency(); -} diff --git a/tests/server/test/templates/retyper/WithSignatureDependencyInferredRet.hx b/tests/server/test/templates/retyper/WithSignatureDependencyInferredRet.hx deleted file mode 100644 index 1e1bbde3a59..00000000000 --- a/tests/server/test/templates/retyper/WithSignatureDependencyInferredRet.hx +++ /dev/null @@ -1,5 +0,0 @@ -class WithSignatureDependency { - public static function test() { - return new Dependency(); - } -} diff --git a/tests/server/test/templates/retyper/WithSignatureDependencyInferredVariable.hx b/tests/server/test/templates/retyper/WithSignatureDependencyInferredVariable.hx deleted file mode 100644 index 8c3e7c8ca3e..00000000000 --- a/tests/server/test/templates/retyper/WithSignatureDependencyInferredVariable.hx +++ /dev/null @@ -1,3 +0,0 @@ -class WithSignatureDependency { - public static var test = new Dependency(); -} diff --git a/tests/server/test/templates/retyper/WithSignatureDependencyProperty.hx b/tests/server/test/templates/retyper/WithSignatureDependencyProperty.hx deleted file mode 100644 index 49e17954312..00000000000 --- a/tests/server/test/templates/retyper/WithSignatureDependencyProperty.hx +++ /dev/null @@ -1,3 +0,0 @@ -class WithSignatureDependency { - public static var test(default, null):Dependency; -} diff --git a/tests/server/test/templates/retyper/WithSignatureDependencyVariable.hx b/tests/server/test/templates/retyper/WithSignatureDependencyVariable.hx deleted file mode 100644 index f2e5fa60a64..00000000000 --- a/tests/server/test/templates/retyper/WithSignatureDependencyVariable.hx +++ /dev/null @@ -1,3 +0,0 @@ -class WithSignatureDependency { - public static var test:Dependency; -} From 4379eea3d527c2866d63b52cb816fcbaa699c84b Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 09:23:05 +0100 Subject: [PATCH 04/32] [typer] consume bypass_accessor only if it's actually relevant closes #11488 --- src/typing/fields.ml | 6 ++--- tests/unit/src/unit/issues/Issue11488.hx | 29 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 tests/unit/src/unit/issues/Issue11488.hx diff --git a/src/typing/fields.ml b/src/typing/fields.ml index 0e1898c32bb..212430d037b 100644 --- a/src/typing/fields.ml +++ b/src/typing/fields.ml @@ -109,7 +109,7 @@ 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.bypass_accessor > 0 then (ctx.bypass_accessor <- ctx.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 -> @@ -208,8 +208,6 @@ let field_access ctx mode f fh e pfield = | AccCall -> let m = (match mode with MSet _ -> "set_" | _ -> "get_") ^ f.cf_name in let bypass_accessor = - bypass_accessor - || ( m = ctx.curfield.cf_name && @@ -218,7 +216,7 @@ let field_access ctx mode f fh e pfield = | TLocal v -> Option.map_default (fun vthis -> v == vthis) false ctx.vthis | TTypeExpr (TClassDecl c) when c == ctx.curclass -> true | _ -> false - ) + ) || bypass_accessor () in if bypass_accessor then ( (match e.eexpr with TLocal _ when Common.defined ctx.com Define.Haxe3Compat -> warning ctx WTemp "Field set has changed here in Haxe 4: call setter explicitly to keep Haxe 3.x behaviour" pfield | _ -> ()); diff --git a/tests/unit/src/unit/issues/Issue11488.hx b/tests/unit/src/unit/issues/Issue11488.hx new file mode 100644 index 00000000000..859af58b326 --- /dev/null +++ b/tests/unit/src/unit/issues/Issue11488.hx @@ -0,0 +1,29 @@ +package unit.issues; + +private class Parent { + public var that:Parent; + public var visible(default, set) = true; + + public function new() + that = this; + + public function set_visible(v:Bool) { + throw "set_visible was called"; + } + + public function drawRec() {} +} + +private class Child extends Parent { + override function drawRec() { + @:bypassAccessor that.visible = false; + } +} + +class Issue11488 extends Test { + function test() { + var child = new Child(); + child.drawRec(); + f(child.visible); + } +} From 19a490cc2c7b9a1a43192cb229be3ae16dd9a469 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 10:12:15 +0100 Subject: [PATCH 05/32] [tests] fix see #11488 --- tests/misc/projects/Issue5039/compile2-fail.hxml.stderr | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/misc/projects/Issue5039/compile2-fail.hxml.stderr b/tests/misc/projects/Issue5039/compile2-fail.hxml.stderr index 2572b4b4397..1f8ea81c743 100644 --- a/tests/misc/projects/Issue5039/compile2-fail.hxml.stderr +++ b/tests/misc/projects/Issue5039/compile2-fail.hxml.stderr @@ -1 +1,3 @@ +Main2.hx:4: characters 37-53 : Field access expression expected after @:bypassAccessor metadata +Main2.hx:4: characters 20-36 : Field access expression expected after @:bypassAccessor metadata Main2.hx:4: characters 3-19 : Field access expression expected after @:bypassAccessor metadata From fd51af810f355e80199df5bdb984266dd55beffa Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Tue, 30 Jan 2024 11:53:42 +0100 Subject: [PATCH 06/32] [std] a bit of safety here --- std/haxe/Log.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/haxe/Log.hx b/std/haxe/Log.hx index a0f4cd78fdd..08d8b7fcead 100644 --- a/std/haxe/Log.hx +++ b/std/haxe/Log.hx @@ -30,7 +30,7 @@ class Log { /** Format the output of `trace` before printing it. **/ - public static function formatOutput(v:Dynamic, infos:PosInfos):String { + public static function formatOutput(v:Dynamic, infos:Null):String { var str = Std.string(v); if (infos == null) return str; From eee3274e186a6b98222e37c3c56cee99a7bc0094 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 12:03:03 +0100 Subject: [PATCH 07/32] Clean up TAnon field handling (#11518) * [display] clean up TAnon display field handling see #11515 * add test --- src/context/display/displayFields.ml | 83 +++++++++++++-------------- tests/display/src/cases/Issue11515.hx | 27 +++++++++ 2 files changed, 67 insertions(+), 43 deletions(-) create mode 100644 tests/display/src/cases/Issue11515.hx diff --git a/src/context/display/displayFields.ml b/src/context/display/displayFields.ml index fabfb77d091..8540e92fb99 100644 --- a/src/context/display/displayFields.ml +++ b/src/context/display/displayFields.ml @@ -250,54 +250,51 @@ let collect ctx e_ast e dk with_type p = end | _ -> items in - (* Anon own fields *) - let fields = match !(an.a_status) with - | ClassStatics c -> c.cl_statics - | _ -> an.a_fields + let iter_fields origin fields f_allow f_make = + let items = PMap.fold (fun cf acc -> + if is_new_item acc cf.cf_name && f_allow cf then begin + let ct = CompletionType.from_type (get_import_status ctx) ~values:(get_value_meta cf.cf_meta) cf.cf_type in + PMap.add cf.cf_name (f_make (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct)) acc + end else + acc + ) fields items in + items in - PMap.foldi (fun name cf acc -> - if is_new_item acc name then begin - let allow_static_abstract_access c cf = + begin match !(an.a_status) with + | ClassStatics ({cl_kind = KAbstractImpl a} as c) -> + Display.merge_core_doc ctx (TClassDecl c); + let f_allow cf = should_access c cf false && (not (has_class_field_flag cf CfImpl) || has_class_field_flag cf CfEnum) in - let ct = CompletionType.from_type (get_import_status ctx) ~values:(get_value_meta cf.cf_meta) cf.cf_type in - let add origin make_field = - PMap.add name (make_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct)) acc + let f_make ccf = + if has_class_field_flag ccf.CompletionClassField.field CfEnum then + make_ci_enum_abstract_field a ccf + else + make_ci_class_field ccf in - match !(an.a_status) with - | ClassStatics ({cl_kind = KAbstractImpl a} as c) -> - if allow_static_abstract_access c cf then - let make = if has_class_field_flag cf CfEnum then - (make_ci_enum_abstract_field a) - else - make_ci_class_field - in - add (Self (TAbstractDecl a)) make - else - acc; - | ClassStatics c -> - Display.merge_core_doc ctx (TClassDecl c); - if should_access c cf true then add (Self (TClassDecl c)) make_ci_class_field else acc; - | EnumStatics en -> - let ef = PMap.find name en.e_constrs in - PMap.add name (make_ci_enum_field (CompletionEnumField.make ef (Self (TEnumDecl en)) true) (cf.cf_type,ct)) acc - | AbstractStatics a -> - Display.merge_core_doc ctx (TAbstractDecl a); - let check = match a.a_impl with - | None -> true - | Some c -> allow_static_abstract_access c cf - in - if check then add (Self (TAbstractDecl a)) make_ci_class_field else acc; - | _ -> - let origin = match t with - | TType(td,_) -> Self (TTypeDecl td) - | _ -> AnonymousStructure an - in - add origin make_ci_class_field; - end else - acc - ) fields items + iter_fields (Self (TClassDecl c)) c.cl_statics f_allow f_make + | ClassStatics c -> + Display.merge_core_doc ctx (TClassDecl c); + let f_allow cf = should_access c cf true in + iter_fields (Self (TClassDecl c)) c.cl_statics f_allow make_ci_class_field + | AbstractStatics ({a_impl = Some c} as a) -> + Display.merge_core_doc ctx (TAbstractDecl a); + let f_allow cf = should_access c cf true in + iter_fields (Self (TAbstractDecl a)) c.cl_statics f_allow make_ci_class_field + | EnumStatics en -> + PMap.fold (fun ef acc -> + let ct = CompletionType.from_type (get_import_status ctx) ~values:(get_value_meta ef.ef_meta) ef.ef_type in + let cef = CompletionEnumField.make ef (Self (TEnumDecl en)) true in + PMap.add ef.ef_name (make_ci_enum_field cef (ef.ef_type,ct)) acc + ) en.e_constrs items + | _ -> + let origin = match t with + | TType(td,_) -> Self (TTypeDecl td) + | _ -> AnonymousStructure an + in + iter_fields origin an.a_fields (fun _ -> true) make_ci_class_field + end | TFun (args,ret) -> (* A function has no field except the magic .bind one. *) if is_new_item items "bind" then begin diff --git a/tests/display/src/cases/Issue11515.hx b/tests/display/src/cases/Issue11515.hx new file mode 100644 index 00000000000..975dbaec825 --- /dev/null +++ b/tests/display/src/cases/Issue11515.hx @@ -0,0 +1,27 @@ +package cases; + +class Issue11515 extends DisplayTestCase { + /** + import haxe.ds.Option; + + class Main { + static function main () { + Option.{-1-} + } + } + **/ + function testImport() { + eq(true, hasField(fields(pos(1)), "None", "haxe.ds.Option")); + } + + /** + class Main { + static function main () { + haxe.ds.Option.{-1-} + } + } + **/ + function testFully() { + eq(true, hasField(fields(pos(1)), "None", "haxe.ds.Option")); + } +} From c1697d4e7ded292c798c740ce6840bfa249829aa Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 12:09:59 +0100 Subject: [PATCH 08/32] Rename EvalStackTrace.ml to evalStackTrace.ml --- src/macro/eval/{EvalStackTrace.ml => evalStackTrace.ml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/macro/eval/{EvalStackTrace.ml => evalStackTrace.ml} (100%) diff --git a/src/macro/eval/EvalStackTrace.ml b/src/macro/eval/evalStackTrace.ml similarity index 100% rename from src/macro/eval/EvalStackTrace.ml rename to src/macro/eval/evalStackTrace.ml From e43e18ff8728d4e13beda3f2928a984152528c31 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 15:10:42 +0100 Subject: [PATCH 09/32] [hxb] don't write MFake deps because we cannot load them like that --- src/compiler/hxb/hxbWriter.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/hxb/hxbWriter.ml b/src/compiler/hxb/hxbWriter.ml index 9e77b5b9e4b..7f6e4aa12d4 100644 --- a/src/compiler/hxb/hxbWriter.ml +++ b/src/compiler/hxb/hxbWriter.ml @@ -2237,8 +2237,8 @@ module HxbWriter = struct let deps = DynArray.create () in PMap.iter (fun _ mdep -> match mdep.md_kind with - | MCode | MExtern | MFake when mdep.md_sign = m.m_extra.m_sign -> - DynArray.add deps mdep.md_path; + | MCode | MExtern when mdep.md_sign = m.m_extra.m_sign -> + DynArray.add deps mdep.md_path; | _ -> () ) m.m_extra.m_deps; From 050acbe657bf233d74eb521e5f3f0e1d210fd4b9 Mon Sep 17 00:00:00 2001 From: Yaroslav Sivakov Date: Tue, 30 Jan 2024 17:33:46 +0300 Subject: [PATCH 10/32] Update haxe.macro.Printer.hx (#11522) Old version generate code: ``` class MyClass ``` Compiling that code produce error "unexpected >". New version produce ``` class MyClass ``` which compile OK --- std/haxe/macro/Printer.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/haxe/macro/Printer.hx b/std/haxe/macro/Printer.hx index bf43c742be0..bce266f7239 100644 --- a/std/haxe/macro/Printer.hx +++ b/std/haxe/macro/Printer.hx @@ -200,7 +200,7 @@ class Printer { return (tpd.meta != null && tpd.meta.length > 0 ? tpd.meta.map(printMetadata).join(" ") + " " : "") + tpd.name + (tpd.params != null && tpd.params.length > 0 ? "<" + tpd.params.map(printTypeParamDecl).join(", ") + ">" : "") - + (tpd.constraints != null && tpd.constraints.length > 0 ? ":(" + tpd.constraints.map(printComplexType).join(", ") + ")" : "") + + (tpd.constraints != null && tpd.constraints.length > 0 ? ":(" + tpd.constraints.map(printComplexType).join(" & ") + ")" : "") + (tpd.defaultType != null ? "=" + printComplexType(tpd.defaultType) : ""); public function printFunctionArg(arg:FunctionArg) From a2c3714582edebe09b56cb815ee517dcab04f9de Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 17:56:57 +0100 Subject: [PATCH 11/32] [java] use BufferedInputStream in FileInput closes #11487 --- std/java/_std/sys/io/FileInput.hx | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/std/java/_std/sys/io/FileInput.hx b/std/java/_std/sys/io/FileInput.hx index 6e4a080c95a..70d435288cd 100644 --- a/std/java/_std/sys/io/FileInput.hx +++ b/std/java/_std/sys/io/FileInput.hx @@ -22,6 +22,8 @@ package sys.io; +import java.io.FileInputStream; +import java.io.BufferedInputStream; import haxe.Int64; import haxe.io.Bytes; import haxe.io.Eof; @@ -31,10 +33,12 @@ import java.io.IOException; class FileInput extends Input { var f:java.io.RandomAccessFile; + var b:BufferedInputStream; var _eof:Bool; function new(f) { this.f = f; + b = new BufferedInputStream(new FileInputStream(f.getFD())); this._eof = false; } @@ -46,29 +50,16 @@ class FileInput extends Input { } override public function readByte():Int { - try { - return f.readUnsignedByte(); - } catch (e:EOFException) { - + var i = b.read(); + if (i == -1) { _eof = true; throw new Eof(); - } catch (e:IOException) { - throw haxe.io.Error.Custom(e); } + return i; } override public function readBytes(s:Bytes, pos:Int, len:Int):Int { - var ret = 0; - try { - ret = f.read(s.getData(), pos, len); - } catch (e:EOFException) { - - _eof = true; - throw new Eof(); - } catch (e:IOException) { - throw haxe.io.Error.Custom(e); - } - + var ret = b.read(s.getData(), pos, len); if (ret == -1) { _eof = true; throw new Eof(); @@ -89,7 +80,6 @@ class FileInput extends Input { f.seek(haxe.Int64.add(f.length(), cast p)); } } catch (e:EOFException) { - _eof = true; throw new Eof(); } catch (e:IOException) { From a79f913737ece327edafd0949d8223693fca6102 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 20:29:51 +0100 Subject: [PATCH 12/32] Revert "[java] use BufferedInputStream in FileInput" This reverts commit a2c3714582edebe09b56cb815ee517dcab04f9de. --- std/java/_std/sys/io/FileInput.hx | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/std/java/_std/sys/io/FileInput.hx b/std/java/_std/sys/io/FileInput.hx index 70d435288cd..6e4a080c95a 100644 --- a/std/java/_std/sys/io/FileInput.hx +++ b/std/java/_std/sys/io/FileInput.hx @@ -22,8 +22,6 @@ package sys.io; -import java.io.FileInputStream; -import java.io.BufferedInputStream; import haxe.Int64; import haxe.io.Bytes; import haxe.io.Eof; @@ -33,12 +31,10 @@ import java.io.IOException; class FileInput extends Input { var f:java.io.RandomAccessFile; - var b:BufferedInputStream; var _eof:Bool; function new(f) { this.f = f; - b = new BufferedInputStream(new FileInputStream(f.getFD())); this._eof = false; } @@ -50,16 +46,29 @@ class FileInput extends Input { } override public function readByte():Int { - var i = b.read(); - if (i == -1) { + try { + return f.readUnsignedByte(); + } catch (e:EOFException) { + _eof = true; throw new Eof(); + } catch (e:IOException) { + throw haxe.io.Error.Custom(e); } - return i; } override public function readBytes(s:Bytes, pos:Int, len:Int):Int { - var ret = b.read(s.getData(), pos, len); + var ret = 0; + try { + ret = f.read(s.getData(), pos, len); + } catch (e:EOFException) { + + _eof = true; + throw new Eof(); + } catch (e:IOException) { + throw haxe.io.Error.Custom(e); + } + if (ret == -1) { _eof = true; throw new Eof(); @@ -80,6 +89,7 @@ class FileInput extends Input { f.seek(haxe.Int64.add(f.length(), cast p)); } } catch (e:EOFException) { + _eof = true; throw new Eof(); } catch (e:IOException) { From b0ec8625a207656a58170295e4d9afa1bb2f3413 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 21:43:25 +0100 Subject: [PATCH 13/32] Set --run args only when we're actually running (#11524) * set --run args only when we're actually running see #11087 * add test * add another test --- src/compiler/compilationContext.ml | 1 + src/compiler/compiler.ml | 3 ++- src/compiler/generate.ml | 13 ++++++++++--- src/context/common.ml | 4 +--- src/macro/eval/evalStdLib.ml | 2 +- tests/misc/projects/Issue11087/Main.hx | 9 +++++++++ tests/misc/projects/Issue11087/compile-interp.hxml | 2 ++ .../projects/Issue11087/compile-interp.hxml.stdout | 2 ++ tests/misc/projects/Issue11087/compile.hxml | 2 ++ tests/misc/projects/Issue11087/compile.hxml.stdout | 2 ++ 10 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 tests/misc/projects/Issue11087/Main.hx create mode 100644 tests/misc/projects/Issue11087/compile-interp.hxml create mode 100644 tests/misc/projects/Issue11087/compile-interp.hxml.stdout create mode 100644 tests/misc/projects/Issue11087/compile.hxml create mode 100644 tests/misc/projects/Issue11087/compile.hxml.stdout diff --git a/src/compiler/compilationContext.ml b/src/compiler/compilationContext.ml index b2df6431349..f6697e4e136 100644 --- a/src/compiler/compilationContext.ml +++ b/src/compiler/compilationContext.ml @@ -54,6 +54,7 @@ and compilation_context = { mutable has_next : bool; mutable has_error : bool; comm : communication; + mutable runtime_args : string list; } type compilation_callbacks = { diff --git a/src/compiler/compiler.ml b/src/compiler/compiler.ml index 3654a6e0a5d..26c9fb7b9c5 100644 --- a/src/compiler/compiler.ml +++ b/src/compiler/compiler.ml @@ -509,6 +509,7 @@ let create_context comm cs compilation_step params = { has_next = false; has_error = false; comm = comm; + runtime_args = []; } module HighLevel = struct @@ -614,7 +615,7 @@ module HighLevel = struct | "--run" :: cl :: args -> let acc = cl :: "-x" :: acc in let ctx = create_context (List.rev acc) in - ctx.com.sys_args <- args; + ctx.runtime_args <- args; [],Some ctx | ("-L" | "--library" | "-lib") :: name :: args -> let libs,args = find_subsequent_libs [name] args in diff --git a/src/compiler/generate.ml b/src/compiler/generate.ml index d3671463146..8066f4f4e57 100644 --- a/src/compiler/generate.ml +++ b/src/compiler/generate.ml @@ -121,9 +121,16 @@ let generate ctx tctx ext actx = | Java when not actx.jvm_flag -> Path.mkdir_from_path (com.file ^ "/.") | _ -> Path.mkdir_from_path com.file end; - if actx.interp then - Std.finally (Timer.timer ["interp"]) MacroContext.interpret tctx - else begin + if actx.interp then begin + let timer = Timer.timer ["interp"] in + let old = tctx.com.args in + tctx.com.args <- ctx.runtime_args; + let restore () = + tctx.com.args <- old; + timer () + in + Std.finally restore MacroContext.interpret tctx + end else begin let generate,name = match com.platform with | Flash -> let header = try diff --git a/src/context/common.ml b/src/context/common.ml index 59359f5d01a..2fec5ff4a2e 100644 --- a/src/context/common.ml +++ b/src/context/common.ml @@ -354,8 +354,7 @@ type context = { mutable json_out : json_api option; (* config *) version : int; - args : string list; - mutable sys_args : string list; + mutable args : string list; mutable display : DisplayTypes.DisplayMode.settings; mutable debug : bool; mutable verbose : bool; @@ -810,7 +809,6 @@ let create compilation_step cs version args display_mode = display_module_has_macro_defines = false; module_diagnostics = []; }; - sys_args = args; debug = false; display = display_mode; verbose = false; diff --git a/src/macro/eval/evalStdLib.ml b/src/macro/eval/evalStdLib.ml index 9212e689728..97b42b32310 100644 --- a/src/macro/eval/evalStdLib.ml +++ b/src/macro/eval/evalStdLib.ml @@ -2569,7 +2569,7 @@ module StdSys = struct open Common let args = vfun0 (fun () -> - encode_array (List.map create_unknown ((get_ctx()).curapi.MacroApi.get_com()).sys_args) + encode_array (List.map create_unknown ((get_ctx()).curapi.MacroApi.get_com()).args) ) let _command = vfun1 (fun cmd -> diff --git a/tests/misc/projects/Issue11087/Main.hx b/tests/misc/projects/Issue11087/Main.hx new file mode 100644 index 00000000000..dcec6730897 --- /dev/null +++ b/tests/misc/projects/Issue11087/Main.hx @@ -0,0 +1,9 @@ +macro function test() { + trace(Sys.args()); + return macro null; +} + +function main() { + test(); + trace(Sys.args()); +} diff --git a/tests/misc/projects/Issue11087/compile-interp.hxml b/tests/misc/projects/Issue11087/compile-interp.hxml new file mode 100644 index 00000000000..b30a755894b --- /dev/null +++ b/tests/misc/projects/Issue11087/compile-interp.hxml @@ -0,0 +1,2 @@ +--main Main +--interp \ No newline at end of file diff --git a/tests/misc/projects/Issue11087/compile-interp.hxml.stdout b/tests/misc/projects/Issue11087/compile-interp.hxml.stdout new file mode 100644 index 00000000000..7364ee81c61 --- /dev/null +++ b/tests/misc/projects/Issue11087/compile-interp.hxml.stdout @@ -0,0 +1,2 @@ +Main.hx:2: [--main,Main,--interp] +Main.hx:8: [] \ No newline at end of file diff --git a/tests/misc/projects/Issue11087/compile.hxml b/tests/misc/projects/Issue11087/compile.hxml new file mode 100644 index 00000000000..7c1904b0e34 --- /dev/null +++ b/tests/misc/projects/Issue11087/compile.hxml @@ -0,0 +1,2 @@ +--run Main +arg \ No newline at end of file diff --git a/tests/misc/projects/Issue11087/compile.hxml.stdout b/tests/misc/projects/Issue11087/compile.hxml.stdout new file mode 100644 index 00000000000..9a331ddd62d --- /dev/null +++ b/tests/misc/projects/Issue11087/compile.hxml.stdout @@ -0,0 +1,2 @@ +Main.hx:2: [-x,Main] +Main.hx:8: [arg] \ No newline at end of file From 9e7a820a587fb08d3ad385d4a329f80e3977c81e Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Tue, 30 Jan 2024 22:38:45 +0100 Subject: [PATCH 14/32] [typer] don't hide abstract type when resolving through @:forward closes #11526 --- src/typing/fields.ml | 2 +- .../src/TestInlineConstructors.hx | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/typing/fields.ml b/src/typing/fields.ml index 212430d037b..ffd3a75aae8 100644 --- a/src/typing/fields.ml +++ b/src/typing/fields.ml @@ -270,7 +270,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = | None -> raise Not_found in let type_field_by_et f e t = - f { e with etype = t } (follow_without_type t) + f (mk (TCast(e,None)) t e.epos) (follow_without_type t) in let type_field_by_e f e = f e (follow_without_type e.etype) diff --git a/tests/optimization/src/TestInlineConstructors.hx b/tests/optimization/src/TestInlineConstructors.hx index 9bd64113c59..5f67a63c083 100644 --- a/tests/optimization/src/TestInlineConstructors.hx +++ b/tests/optimization/src/TestInlineConstructors.hx @@ -44,6 +44,19 @@ class NestedInlineClass { } } +class P { + public var x:Float; + + public inline function new(x = 0) + this.x = x; +} + +@:forward +abstract PA(P) to P { + public inline function new(x) + this = new P(x); +} + class TestInlineConstructors extends TestBase { @:js('return [1,2,3,3];') static function testArrayInlining() { @@ -147,4 +160,10 @@ class TestInlineConstructors extends TestBase { try { a; } catch(_) { a; }; return a.a; } + + @:js('return [5];') + static function testForwardAbstract() { + var p2 = {v: new PA(5)}; + return [p2.v.x]; + } } From e2e359be130917f06802976532e6af5ab25aca0a Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Wed, 31 Jan 2024 07:53:44 +0100 Subject: [PATCH 15/32] add @:forward.accessOnAbstract and use it for cs.PointerAccess --- src-json/meta.json | 6 ++++++ src/typing/fields.ml | 17 ++++++++++++++--- std/cs/Pointer.hx | 4 +++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src-json/meta.json b/src-json/meta.json index 9df0fb365e6..ddc3f8f9b03 100644 --- a/src-json/meta.json +++ b/src-json/meta.json @@ -395,6 +395,12 @@ "targets": ["TAbstract"], "links": ["https://haxe.org/manual/types-abstract-forward.html"] }, + { + "name": "ForwardAccessOnAbstract", + "metadata": ":forward.accessOnAbstract", + "doc": "Generates @:forward field access on the abstract itself instead of the underlying type.", + "targets": ["TAbstract"] + }, { "name": "ForwardNew", "metadata": ":forward.new", diff --git a/src/typing/fields.ml b/src/typing/fields.ml index ffd3a75aae8..6df1870c565 100644 --- a/src/typing/fields.ml +++ b/src/typing/fields.ml @@ -270,7 +270,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = | None -> raise Not_found in let type_field_by_et f e t = - f (mk (TCast(e,None)) t e.epos) (follow_without_type t) + f e (follow_without_type t) in let type_field_by_e f e = f e (follow_without_type e.etype) @@ -291,7 +291,15 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = type_field_by_forward f Meta.ForwardStatics a in let type_field_by_forward_member f e a tl = - let f () = type_field_by_et f e (Abstract.get_underlying_type ~return_first:true a tl) in + let f () = + let t = Abstract.get_underlying_type ~return_first:true a tl in + let e = if Meta.has Meta.ForwardAccessOnAbstract a.a_meta then + e + else + mk (TCast(e,None)) t e.epos + in + type_field_by_et f e t + in type_field_by_forward f Meta.Forward a in let type_field_by_typedef f e td tl = @@ -374,7 +382,10 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = field_access f FHAnon ) | CTypes tl -> - type_field_by_list (fun (t,_) -> type_field_by_et type_field_by_type e t) tl + type_field_by_list (fun (t,_) -> + let e = mk (TCast(e,None)) t e.epos in + 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; diff --git a/std/cs/Pointer.hx b/std/cs/Pointer.hx index 5d18c665369..4026af75a5e 100644 --- a/std/cs/Pointer.hx +++ b/std/cs/Pointer.hx @@ -129,5 +129,7 @@ import cs.StdTypes.Int64; @:arrayAccess public static function setp(p:Pointer, at:Int64, val:T):T; } -@:forward abstract PointerAccess(T) {} +@:forward +@:forward.accessOnAbstract +abstract PointerAccess(T) {} #end From 9d1f947b1e81e50882473cc867fd7372b32d1988 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Wed, 31 Jan 2024 09:24:45 +0100 Subject: [PATCH 16/32] output binary cache memory --- src/compiler/compilationCache.ml | 2 +- src/context/memory.ml | 3 +++ std/haxe/display/Server.hx | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/compiler/compilationCache.ml b/src/compiler/compilationCache.ml index 9385453facc..fef5056b25b 100644 --- a/src/compiler/compilationCache.ml +++ b/src/compiler/compilationCache.ml @@ -108,7 +108,7 @@ class context_cache (index : int) (sign : Digest.t) = object(self) (* Pointers for memory inspection. *) method get_pointers : unit array = - [|Obj.magic files;Obj.magic modules|] + [|Obj.magic files;Obj.magic modules;Obj.magic binary_cache|] end let create_directory path mtime = { diff --git a/src/context/memory.ml b/src/context/memory.ml index 6299d454cba..c0613b9db62 100644 --- a/src/context/memory.ml +++ b/src/context/memory.ml @@ -169,6 +169,9 @@ let get_memory_json (cs : CompilationCache.t) mreq = "size",jint (mem_size cache_mem.(1)); "list",jarray l; ]; + "binaryCache",jobject [ + "size",jint (mem_size cache_mem.(2)); + ]; ] | MModule(sign,path) -> let cc = cs#get_context sign in diff --git a/std/haxe/display/Server.hx b/std/haxe/display/Server.hx index b7792084a15..0c20e60baf1 100644 --- a/std/haxe/display/Server.hx +++ b/std/haxe/display/Server.hx @@ -139,6 +139,9 @@ typedef HaxeContextMemoryResult = { final syntaxCache:{ final size:Int; }; + final binaryCache:{ + final size:Int; + }; final ?leaks:Array<{ final path:String; final leaks:Array<{ From c5f913ca14e0ee424119045cb835c80d79ea9603 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Wed, 31 Jan 2024 11:40:44 +0100 Subject: [PATCH 17/32] clean up ctx.type_params initialization closes #11528 --- src/typing/typeloadFields.ml | 10 ++++------ tests/misc/projects/Issue11528/Main.hx | 9 +++++++++ tests/misc/projects/Issue11528/compile-fail.hxml | 1 + .../misc/projects/Issue11528/compile-fail.hxml.stderr | 1 + 4 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 tests/misc/projects/Issue11528/Main.hx create mode 100644 tests/misc/projects/Issue11528/compile-fail.hxml create mode 100644 tests/misc/projects/Issue11528/compile-fail.hxml.stderr diff --git a/src/typing/typeloadFields.ml b/src/typing/typeloadFields.ml index 36ffbdbf9fa..8c85692ee7b 100644 --- a/src/typing/typeloadFields.ml +++ b/src/typing/typeloadFields.ml @@ -557,7 +557,7 @@ let create_typer_context_for_class ctx cctx p = let ctx = { ctx with curclass = c; - type_params = c.cl_params; + type_params = (match c.cl_kind with KAbstractImpl a -> a.a_params | _ -> c.cl_params); pass = PBuildClass; tthis = (match cctx.abstract with | Some a -> @@ -636,7 +636,9 @@ let create_typer_context_for_field ctx cctx fctx cff = monomorphs = { perfunction = []; }; + type_params = if fctx.is_static && not fctx.is_abstract_member then [] else ctx.type_params; } in + let c = cctx.tclass in if (fctx.is_abstract && not (has_meta Meta.LibType c.cl_meta)) then begin if fctx.is_static then @@ -1356,7 +1358,7 @@ let create_method (ctx,cctx,fctx) c f fd p = let is_override = Option.is_some fctx.override in if (is_override && fctx.is_static) then invalid_modifier_combination fctx ctx.com fctx "override" "static" p; - ctx.type_params <- if fctx.is_static && not fctx.is_abstract_member then params else params @ ctx.type_params; + ctx.type_params <- params @ ctx.type_params; let args,ret = setup_args_ret ctx cctx fctx (fst f.cff_name) fd p in let t = TFun (args#for_type,ret) in let cf = { @@ -1632,10 +1634,6 @@ let init_field (ctx,cctx,fctx) f = ); | None -> () end; - begin match cctx.abstract with - | Some a when fctx.is_abstract_member -> ctx.type_params <- a.a_params; - | _ -> () - end; let cf = match f.cff_kind with | FVar (t,e) -> diff --git a/tests/misc/projects/Issue11528/Main.hx b/tests/misc/projects/Issue11528/Main.hx new file mode 100644 index 00000000000..3b2ba84e22a --- /dev/null +++ b/tests/misc/projects/Issue11528/Main.hx @@ -0,0 +1,9 @@ +class MyClass { + public static var Null = new MyClass(); + + public function new() {} +} + +function main() { + trace(MyClass.Null); +} \ No newline at end of file diff --git a/tests/misc/projects/Issue11528/compile-fail.hxml b/tests/misc/projects/Issue11528/compile-fail.hxml new file mode 100644 index 00000000000..fab0aeecc3d --- /dev/null +++ b/tests/misc/projects/Issue11528/compile-fail.hxml @@ -0,0 +1 @@ +--main Main \ No newline at end of file diff --git a/tests/misc/projects/Issue11528/compile-fail.hxml.stderr b/tests/misc/projects/Issue11528/compile-fail.hxml.stderr new file mode 100644 index 00000000000..35bce2d0f9d --- /dev/null +++ b/tests/misc/projects/Issue11528/compile-fail.hxml.stderr @@ -0,0 +1 @@ +Main.hx:2: characters 39-40 : Type not found : T \ No newline at end of file From b3d3a2ff91f3dba25a35961f9dab67be3ade4b32 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Wed, 31 Jan 2024 12:55:45 +0100 Subject: [PATCH 18/32] Revert @:forward.accessOnAbstract, hack instead see #11527 --- src-json/meta.json | 6 ------ src/typing/fields.ml | 21 ++++++++------------- std/cs/Pointer.hx | 4 +--- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src-json/meta.json b/src-json/meta.json index ddc3f8f9b03..9df0fb365e6 100644 --- a/src-json/meta.json +++ b/src-json/meta.json @@ -395,12 +395,6 @@ "targets": ["TAbstract"], "links": ["https://haxe.org/manual/types-abstract-forward.html"] }, - { - "name": "ForwardAccessOnAbstract", - "metadata": ":forward.accessOnAbstract", - "doc": "Generates @:forward field access on the abstract itself instead of the underlying type.", - "targets": ["TAbstract"] - }, { "name": "ForwardNew", "metadata": ":forward.new", diff --git a/src/typing/fields.ml b/src/typing/fields.ml index 6df1870c565..b1c29238caf 100644 --- a/src/typing/fields.ml +++ b/src/typing/fields.ml @@ -270,6 +270,12 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = | None -> raise Not_found in let type_field_by_et f e t = + let e = match ctx.com.platform with + | Cs -> + {e with etype = t} + | _ -> + mk (TCast(e,None)) t e.epos + in f e (follow_without_type t) in let type_field_by_e f e = @@ -291,15 +297,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = type_field_by_forward f Meta.ForwardStatics a in let type_field_by_forward_member f e a tl = - let f () = - let t = Abstract.get_underlying_type ~return_first:true a tl in - let e = if Meta.has Meta.ForwardAccessOnAbstract a.a_meta then - e - else - mk (TCast(e,None)) t e.epos - in - type_field_by_et f e t - in + let f () = type_field_by_et f e (Abstract.get_underlying_type ~return_first:true a tl) in type_field_by_forward f Meta.Forward a in let type_field_by_typedef f e td tl = @@ -382,10 +380,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) = field_access f FHAnon ) | CTypes tl -> - type_field_by_list (fun (t,_) -> - let e = mk (TCast(e,None)) t e.epos in - type_field_by_et type_field_by_type e t - ) 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; diff --git a/std/cs/Pointer.hx b/std/cs/Pointer.hx index 4026af75a5e..5d18c665369 100644 --- a/std/cs/Pointer.hx +++ b/std/cs/Pointer.hx @@ -129,7 +129,5 @@ import cs.StdTypes.Int64; @:arrayAccess public static function setp(p:Pointer, at:Int64, val:T):T; } -@:forward -@:forward.accessOnAbstract -abstract PointerAccess(T) {} +@:forward abstract PointerAccess(T) {} #end From 706f607ed9c68bce3f107ae14a2d3684e964418f Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Wed, 31 Jan 2024 14:38:41 +0100 Subject: [PATCH 19/32] dodge c# static type param problem see #11527 --- src/typing/typeloadFields.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typing/typeloadFields.ml b/src/typing/typeloadFields.ml index 8c85692ee7b..80a2b395657 100644 --- a/src/typing/typeloadFields.ml +++ b/src/typing/typeloadFields.ml @@ -636,7 +636,7 @@ let create_typer_context_for_field ctx cctx fctx cff = monomorphs = { perfunction = []; }; - type_params = if fctx.is_static && not fctx.is_abstract_member then [] else ctx.type_params; + 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 let c = cctx.tclass in From ca89e04303682de586d15eef0e6f8c756e4eb933 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Wed, 31 Jan 2024 19:48:26 +0100 Subject: [PATCH 20/32] adapt to mbedtls HL changes --- extra/BUILDING.md | 2 +- tests/runci/targets/Hl.hx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/extra/BUILDING.md b/extra/BUILDING.md index dc22b45c1c9..a5c7e986f04 100644 --- a/extra/BUILDING.md +++ b/extra/BUILDING.md @@ -36,7 +36,7 @@ You need to install some native libraries as well as some OCaml libraries. To install the native libraries, use the appropriate system package manager. * Mac OS X - * Use [Homebrew](https://brew.sh/), `brew install zlib pcre2 mbedtls@2`. + * Use [Homebrew](https://brew.sh/), `brew install zlib pcre2 mbedtls`. * Debian / Ubuntu * `sudo apt install libpcre2-dev zlib1g-dev libmbedtls-dev`. * Windows (Cygwin) diff --git a/tests/runci/targets/Hl.hx b/tests/runci/targets/Hl.hx index 7bf6f207ae8..07ff7999687 100644 --- a/tests/runci/targets/Hl.hx +++ b/tests/runci/targets/Hl.hx @@ -39,7 +39,6 @@ class Hl { case "Mac": runNetworkCommand("brew", ["update", '--preinstall']); runNetworkCommand("brew", ["bundle", '--file=${hlSrc}/Brewfile']); - runNetworkCommand("brew", ["link", "mbedtls@2", "--force"]); case "Windows": //pass } From 3280f2f72ae0cfac9eb741ef83e0c8d82e654e4d Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 07:13:55 +0100 Subject: [PATCH 21/32] Hxb writer config (#11507) * start on writer config * functorize * add Compiler.setHxbWriterConfiguration * rename * add Compiler.getHxbWriterConfiguration * document * substitute $target when we actually need it * fix my favorite test * file * add generateDocumentation * don't forget the writer * (temporarily?) read until EOT immediately see #11512 --- src/compiler/args.ml | 6 +- src/compiler/compilationCache.ml | 4 +- src/compiler/compiler.ml | 12 +- src/compiler/generate.ml | 43 ++++--- src/compiler/hxb/hxbWriter.ml | 31 +++-- src/compiler/hxb/hxbWriterConfig.ml | 119 ++++++++++++++++++ src/context/common.ml | 2 + src/context/commonCache.ml | 8 +- src/core/data/dataReaderApi.ml | 17 +++ src/core/data/dataWriterApi.ml | 15 +++ src/core/data/jsonDataApi.ml | 48 +++++++ src/macro/eval/evalDataApi.ml | 61 +++++++++ src/macro/macroApi.ml | 9 ++ src/typing/macroContext.ml | 26 ++++ src/typing/typeloadModule.ml | 9 +- std/haxe/hxb/WriterConfig.hx | 51 ++++++++ std/haxe/macro/Compiler.hx | 35 ++++++ .../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/unit/compile-hxb-jvm-roundtrip.hxml | 4 +- tests/unit/hxb-config/jvm.json | 10 ++ tests/unit/src/unit/TestMain.hx | 4 +- tests/unit/src/unit/TestMainNow.hx | 9 ++ 25 files changed, 481 insertions(+), 52 deletions(-) create mode 100644 src/compiler/hxb/hxbWriterConfig.ml create mode 100644 src/core/data/dataReaderApi.ml create mode 100644 src/core/data/dataWriterApi.ml create mode 100644 src/core/data/jsonDataApi.ml create mode 100644 src/macro/eval/evalDataApi.ml create mode 100644 std/haxe/hxb/WriterConfig.hx create mode 100644 tests/unit/hxb-config/jvm.json create mode 100644 tests/unit/src/unit/TestMainNow.hx diff --git a/src/compiler/args.ml b/src/compiler/args.ml index 1f7d09b0d00..45edbf9008f 100644 --- a/src/compiler/args.ml +++ b/src/compiler/args.ml @@ -278,9 +278,9 @@ let parse_args com = ("Services",["--json"],[],Arg.String (fun file -> actx.json_out <- Some file ),"","generate JSON types description"); - ("Services",["--hxb"],[], Arg.String (fun dir -> - actx.hxb_out <- Some dir; - ),"", "generate haxe binary representation in target directory"); + ("Services",["--hxb"],[], Arg.String (fun file -> + actx.hxb_out <- Some file; + ),"", "generate haxe binary representation to target archive"); ("Optimization",["--no-output"],[], Arg.Unit (fun() -> actx.no_output <- true),"","compiles but does not generate any file"); ("Debug",["--times"],[], Arg.Unit (fun() -> Timer.measure_times := true),"","measure compilation times"); ("Optimization",["--no-inline"],[],Arg.Unit (fun () -> diff --git a/src/compiler/compilationCache.ml b/src/compiler/compilationCache.ml index fef5056b25b..b7c8ea854cc 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 warn anon_identification hxb_writer_stats path m = + method cache_module config warn anon_identification hxb_writer_stats path m = match m.m_extra.m_kind with | MImport -> Hashtbl.add modules m.m_path m | _ -> - let writer = HxbWriter.create warn anon_identification hxb_writer_stats in + let writer = HxbWriter.create config warn anon_identification hxb_writer_stats in HxbWriter.write_module writer m; let chunks = HxbWriter.get_chunks writer in Hashtbl.replace binary_cache path { diff --git a/src/compiler/compiler.ml b/src/compiler/compiler.ml index 26c9fb7b9c5..93ee2464f6b 100644 --- a/src/compiler/compiler.ml +++ b/src/compiler/compiler.ml @@ -369,6 +369,12 @@ let compile ctx actx callbacks = callbacks.after_target_init ctx; let t = Timer.timer ["init"] in List.iter (fun f -> f()) (List.rev (actx.pre_compilation)); + begin match actx.hxb_out with + | None -> + () + | Some file -> + com.hxb_writer_config <- HxbWriterConfig.process_argument file + end; t(); enter_stage com CInitialized; ServerMessage.compiler_stage com; @@ -382,7 +388,11 @@ let compile ctx actx callbacks = let is_compilation = is_compilation com in com.callbacks#add_after_save (fun () -> callbacks.after_save ctx; - if is_compilation then Generate.check_hxb_output ctx actx; + if is_compilation then match com.hxb_writer_config with + | Some config -> + Generate.check_hxb_output ctx config; + | None -> + () ); if is_diagnostics com then filter ctx tctx (fun () -> DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path) diff --git a/src/compiler/generate.ml b/src/compiler/generate.ml index 8066f4f4e57..e12e22e372b 100644 --- a/src/compiler/generate.ml +++ b/src/compiler/generate.ml @@ -21,7 +21,7 @@ let check_auxiliary_output com actx = Genjson.generate com.types file end -let export_hxb com cc platform zip m = +let export_hxb com config cc platform zip m = let open HxbData in match m.m_extra.m_kind with | MCode | MMacro | MFake | MExtern -> begin @@ -42,7 +42,7 @@ let export_hxb com 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 warn anon_identification com.hxb_writer_stats in + let writer = HxbWriter.create config warn anon_identification com.hxb_writer_stats in HxbWriter.write_module writer m; let out = IO.output_string () in HxbWriter.export writer out; @@ -51,37 +51,46 @@ let export_hxb com cc platform zip m = | _ -> () -let check_hxb_output ctx actx = +let check_hxb_output ctx config = + let open HxbWriterConfig in let com = ctx.com in - let try_write path = + let match_path_list l sl_path = + List.exists (fun sl -> Ast.match_path true sl_path sl) l + in + let try_write () = + let path = config.HxbWriterConfig.archive_path in + let path = Str.global_replace (Str.regexp "\\$target") (platform_name ctx.com.platform) path in let t = Timer.timer ["generate";"hxb"] in Path.mkdir_from_path path; let zip = new Zip_output.zip_output path 6 in - let export com = + let export com config = let cc = CommonCache.get_cache com in let target = Common.platform_name_macro com in List.iter (fun m -> let t = Timer.timer ["generate";"hxb";s_type_path m.m_path] in - Std.finally t (export_hxb com cc target zip) m + let sl_path = fst m.m_path @ [snd m.m_path] in + if not (match_path_list config.exclude sl_path) || match_path_list config.include' sl_path then + Std.finally t (export_hxb com config cc target zip) m ) com.modules; in Std.finally (fun () -> zip#close; t() ) (fun () -> - export com; - Option.may export (com.get_macros()); + if config.target_config.generate then + export com config.target_config; + begin match com.get_macros() with + | Some mcom when config.macro_config.generate -> + export mcom config.macro_config + | _ -> + () + end; ) () in - begin match actx.hxb_out with - | None -> - () - | Some path -> - try - try_write path - with Sys_error s -> - error ctx (Printf.sprintf "Could not write to %s: %s" path s) null_pos - end + try + try_write () + with Sys_error s -> + CompilationContext.error ctx (Printf.sprintf "Could not write to %s: %s" config.archive_path s) null_pos let parse_swf_header ctx h = match ExtString.String.nsplit h ":" with | [width; height; fps] -> diff --git a/src/compiler/hxb/hxbWriter.ml b/src/compiler/hxb/hxbWriter.ml index 7f6e4aa12d4..39cde88c266 100644 --- a/src/compiler/hxb/hxbWriter.ml +++ b/src/compiler/hxb/hxbWriter.ml @@ -511,6 +511,7 @@ let create_field_writer_context pos_writer = { } 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; @@ -601,13 +602,18 @@ module HxbWriter = struct Chunk.write_string writer.chunk mname; Chunk.write_string writer.chunk tname - let write_documentation writer (doc : doc_block) = - Chunk.write_option writer.chunk doc.doc_own (fun s -> - Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s) - ); - Chunk.write_list writer.chunk doc.doc_inherited (fun s -> - Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s) - ) + let maybe_write_documentation writer (doc : doc_block option) = + match doc with + | Some doc when writer.config.generate_docs -> + Chunk.write_u8 writer.chunk 1; + Chunk.write_option writer.chunk doc.doc_own (fun s -> + Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s) + ); + Chunk.write_list writer.chunk doc.doc_inherited (fun s -> + Chunk.write_uleb128 writer.chunk (StringPool.get_or_add writer.docs s) + ) + | _ -> + Chunk.write_u8 writer.chunk 0 let write_pos writer (p : pos) = Chunk.write_string writer.chunk p.pfile; @@ -753,7 +759,7 @@ module HxbWriter = struct and write_cfield writer cff = write_placed_name writer cff.cff_name; - Chunk.write_option writer.chunk cff.cff_doc (write_documentation writer); + maybe_write_documentation writer cff.cff_doc; write_pos writer cff.cff_pos; write_metadata writer cff.cff_meta; Chunk.write_list writer.chunk cff.cff_access (write_placed_access writer); @@ -1829,7 +1835,7 @@ module HxbWriter = struct let restore = start_temporary_chunk writer 512 in write_type_instance writer cf.cf_type; Chunk.write_uleb128 writer.chunk cf.cf_flags; - Chunk.write_option writer.chunk cf.cf_doc (write_documentation writer); + maybe_write_documentation writer cf.cf_doc; write_metadata writer cf.cf_meta; write_field_kind writer cf.cf_kind; let expr_chunk = match cf.cf_expr with @@ -1876,7 +1882,7 @@ module HxbWriter = struct let write_common_module_type writer (infos : tinfos) : unit = Chunk.write_bool writer.chunk infos.mt_private; - Chunk.write_option writer.chunk infos.mt_doc (write_documentation writer); + maybe_write_documentation writer infos.mt_doc; write_metadata writer infos.mt_meta; write_type_parameters_data writer infos.mt_params; Chunk.write_list writer.chunk infos.mt_using (fun (c,p) -> @@ -2141,7 +2147,7 @@ module HxbWriter = struct let t_bytes = restore (fun new_chunk -> Chunk.get_bytes new_chunk) in commit_field_type_parameters writer ef.ef_params; Chunk.write_bytes writer.chunk t_bytes; - Chunk.write_option writer.chunk ef.ef_doc (write_documentation writer); + maybe_write_documentation writer ef.ef_doc; write_metadata writer ef.ef_meta; close(); ); @@ -2281,9 +2287,10 @@ module HxbWriter = struct l end -let create warn anon_id stats = +let create config warn anon_id stats = let cp = StringPool.create () in { + config; warn; anon_id; stats; diff --git a/src/compiler/hxb/hxbWriterConfig.ml b/src/compiler/hxb/hxbWriterConfig.ml new file mode 100644 index 00000000000..a81d4caeec4 --- /dev/null +++ b/src/compiler/hxb/hxbWriterConfig.ml @@ -0,0 +1,119 @@ +open Globals +open Json +open Json.Reader + +type writer_target_config = { + mutable generate : bool; + mutable exclude : string list list; + mutable include' : string list list; + mutable hxb_version : int; + mutable generate_docs : bool; +} + +type t = { + mutable archive_path : string; + target_config : writer_target_config; + macro_config : writer_target_config; +} + +let create_target_config () = { + generate = true; + exclude = []; + include'= []; + hxb_version = HxbData.hxb_version; + generate_docs = true; +} + +let create () = { + archive_path = ""; + target_config = create_target_config (); + macro_config = create_target_config () +} +let error s = + Error.raise_typing_error s null_pos + +module WriterConfigReader (API : DataReaderApi.DataReaderApi) = struct + let read_target_config config fl = + List.iter (fun (s,data) -> match s with + | "generate" -> + config.generate <- API.read_bool data; + | "exclude" -> + API.read_optional data (fun data -> + let l = API.read_array data in + config.exclude <- List.map (fun data -> ExtString.String.nsplit (API.read_string data) ".") l + ) + | "include" -> + API.read_optional data (fun data -> + let l = API.read_array data in + config.include'<- List.map (fun data -> ExtString.String.nsplit (API.read_string data) ".") l + ) + | "hxbVersion" -> + config.hxb_version <- API.read_int data + | "generateDocumentation" -> + config.generate_docs <- API.read_bool data + | s -> + error (Printf.sprintf "Unknown key for target config: %s" s) + ) fl + + let read_writer_config config data = + let read data = + let fl = API.read_object data in + List.iter (fun (s,data) -> + match s with + | "archivePath" -> + config.archive_path <- API.read_string data; + | "targetConfig" -> + API.read_optional data (fun data -> read_target_config config.target_config (API.read_object data)) + | "macroConfig" -> + API.read_optional data (fun data -> read_target_config config.macro_config (API.read_object data)) + | s -> + error (Printf.sprintf "Unknown key for writer config: %s" s) + ) fl + in + API.read_optional data read +end + +module WriterConfigReaderJson = WriterConfigReader(JsonDataApi.JsonReaderApi) + +module WriterConfigWriter (API : DataWriterApi.DataWriterApi) = struct + let write_target_config config = + API.write_object [ + "generate",API.write_bool config.generate; + "exclude",API.write_array (List.map (fun sl -> API.write_string (String.concat "." sl)) config.exclude); + "include",API.write_array (List.map (fun sl -> API.write_string (String.concat "." sl)) config.include'); + "hxbVersion",API.write_int config.hxb_version; + "generateDocumentation",API.write_bool config.generate_docs; + ] + + let write_writer_config config = + API.write_object [ + "archivePath",API.write_string config.archive_path; + "targetConfig",write_target_config config.target_config; + "macroConfig",write_target_config config.macro_config; + ] +end + +let process_json config json = + WriterConfigReaderJson.read_writer_config config json + +let parse config input = + let lexbuf = Sedlexing.Utf8.from_string input in + let json = read_json lexbuf in + process_json config json + +let process_argument file = + let config = create () in + begin match Path.file_extension file with + | "json" -> + let file = try + open_in file + with exc -> + error (Printf.sprintf "Could not open file %s: %s" file (Printexc.to_string exc)) + in + let data = Std.input_all file in + close_in file; + parse config data; + | _ -> + config.archive_path <- file; + end; + Some config \ No newline at end of file diff --git a/src/context/common.ml b/src/context/common.ml index 2fec5ff4a2e..e1e3577f8b0 100644 --- a/src/context/common.ml +++ b/src/context/common.ml @@ -421,6 +421,7 @@ type context = { 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; } let enter_stage com stage = @@ -883,6 +884,7 @@ let create compilation_step cs version args display_mode = 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 diff --git a/src/context/commonCache.ml b/src/context/commonCache.ml index 2ad51ed2201..312d5cc723c 100644 --- a/src/context/commonCache.ml +++ b/src/context/commonCache.ml @@ -85,11 +85,17 @@ let rec cache_context cs com = let cc = get_cache com in let sign = Define.get_signature com.defines in let anon_identification = new Tanon_identification.tanon_identification in + let config = match com.hxb_writer_config with + | None -> + HxbWriterConfig.create_target_config () + | Some config -> + if com.is_macro_context then config.macro_config else config.target_config + in let cache_module m = (* 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 warn anon_identification com.hxb_writer_stats m.m_path m; + cc#cache_module config warn anon_identification com.hxb_writer_stats m.m_path m; in List.iter cache_module com.modules; begin match com.get_macros() with diff --git a/src/core/data/dataReaderApi.ml b/src/core/data/dataReaderApi.ml new file mode 100644 index 00000000000..b8539ab9ce4 --- /dev/null +++ b/src/core/data/dataReaderApi.ml @@ -0,0 +1,17 @@ +module type DataReaderApi = sig + type data + + val read_optional : data -> (data -> unit) -> unit + + val read_object : data -> (string * data) list + + val read_array : data -> data list + + val read_string : data -> string + + val read_bool : data -> bool + + val read_int : data -> int + + val data_to_string : data -> string +end \ No newline at end of file diff --git a/src/core/data/dataWriterApi.ml b/src/core/data/dataWriterApi.ml new file mode 100644 index 00000000000..bf04eafd274 --- /dev/null +++ b/src/core/data/dataWriterApi.ml @@ -0,0 +1,15 @@ +module type DataWriterApi = sig + type data + + val write_optional : data option -> data + + val write_object : (string * data) list -> data + + val write_array : data list -> data + + val write_string : string -> data + + val write_bool : bool -> data + + val write_int : int -> data +end \ No newline at end of file diff --git a/src/core/data/jsonDataApi.ml b/src/core/data/jsonDataApi.ml new file mode 100644 index 00000000000..d3620db2aa8 --- /dev/null +++ b/src/core/data/jsonDataApi.ml @@ -0,0 +1,48 @@ +open Json + +let error s = + (* TODO: should this raise something else? *) + Error.raise_typing_error s Globals.null_pos + +module JsonReaderApi = struct + type data = Json.t + + let read_optional json f = match json with + | JNull -> + () + | _ -> + f json + + let read_object json = match json with + | JObject fl -> + fl + | _ -> + error (Printf.sprintf "Expected JObject, found %s" (string_of_json json)) + + let read_array json = match json with + | JArray l -> + l + | _ -> + error (Printf.sprintf "Expected JArray, found %s" (string_of_json json)) + + let read_string json = match json with + | JString s -> + s + | _ -> + error (Printf.sprintf "Expected JString, found %s" (string_of_json json)) + + let read_int json = match json with + | JInt i -> + i + | _ -> + error (Printf.sprintf "Expected JInt, found %s" (string_of_json json)) + + let read_bool json = match json with + | JBool b -> + b + | _ -> + error (Printf.sprintf "Expected JBool, found %s" (string_of_json json)) + + let data_to_string json = + string_of_json json +end \ No newline at end of file diff --git a/src/macro/eval/evalDataApi.ml b/src/macro/eval/evalDataApi.ml new file mode 100644 index 00000000000..3814ab8827e --- /dev/null +++ b/src/macro/eval/evalDataApi.ml @@ -0,0 +1,61 @@ +open EvalValue +open EvalContext + +module EvalReaderApi = struct + open EvalDecode + + type data = value + + let read_optional v f = match v with + | VNull -> + () + | _ -> + f v + + let read_object v = + List.map (fun (i,v) -> + EvalHash.rev_hash i,v + ) (object_fields (decode_object v)) + + let read_array v = + EvalArray.to_list (decode_varray v) + + let read_string v = + decode_string v + + let read_int v = + decode_int v + + let read_bool v = + decode_bool v + + let data_to_string v = + (EvalPrinting.s_value 0 v).sstring +end + +module EvalWriterApi = struct + open EvalEncode + + type data = value + + let write_optional vo = match vo with + | None -> vnull + | Some v -> v + + let write_object fl = + encode_obj (List.map (fun (s,v) -> + EvalHash.hash s,v + ) fl) + + let write_array vl = + encode_array vl + + let write_string s = + encode_string s + + let write_bool b = + vbool b + + let write_int i = + vint i +end \ No newline at end of file diff --git a/src/macro/macroApi.ml b/src/macro/macroApi.ml index bea386127d7..d7b1b8f97eb 100644 --- a/src/macro/macroApi.ml +++ b/src/macro/macroApi.ml @@ -70,6 +70,8 @@ type 'value compiler_api = { with_imports : 'a . import list -> placed_name list list -> (unit -> 'a) -> 'a; with_options : 'a . compiler_options -> (unit -> 'a) -> 'a; exc_string : 'a . string -> 'a; + get_hxb_writer_config : unit -> 'value; + set_hxb_writer_config : 'value -> unit; } @@ -2405,5 +2407,12 @@ let macro_api ccom get_api = vbool false end ); + "get_hxb_writer_config", vfun0 (fun () -> + (get_api()).get_hxb_writer_config () + ); + "set_hxb_writer_config", vfun1 (fun v -> + (get_api()).set_hxb_writer_config v; + vnull + ) ] end diff --git a/src/typing/macroContext.ml b/src/typing/macroContext.ml index 5a826098df5..8a85aa0cdb2 100644 --- a/src/typing/macroContext.ml +++ b/src/typing/macroContext.ml @@ -34,6 +34,10 @@ module Interp = struct include BuiltApi end + +module HxbWriterConfigReaderEval = HxbWriterConfig.WriterConfigReader(EvalDataApi.EvalReaderApi) +module HxbWriterConfigWriterEval = HxbWriterConfig.WriterConfigWriter(EvalDataApi.EvalWriterApi) + let macro_interp_cache = ref None let safe_decode com v expected t p f = @@ -305,6 +309,28 @@ let make_macro_com_api com mcom p = com.warning ~depth w [] msg p ); exc_string = Interp.exc_string; + get_hxb_writer_config = (fun () -> + match com.hxb_writer_config with + | Some config -> + HxbWriterConfigWriterEval.write_writer_config config + | None -> + VNull + ); + set_hxb_writer_config = (fun v -> + if v == VNull then + com.hxb_writer_config <- None + else begin + let config = match com.hxb_writer_config with + | Some config -> + config + | None -> + let config = HxbWriterConfig.create () in + com.hxb_writer_config <- Some config; + config + in + HxbWriterConfigReaderEval.read_writer_config config v + end + ); } let make_macro_api ctx mctx p = diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 5c94a9fa8a1..69380e173d5 100644 --- a/src/typing/typeloadModule.ml +++ b/src/typing/typeloadModule.ml @@ -818,12 +818,9 @@ let rec load_hxb_module ctx path p = let api = (new hxb_reader_api_typeload ctx load_module' p :> HxbReaderApi.hxb_reader_api) in let reader = new HxbReader.hxb_reader path ctx.com.hxb_reader_stats in let read = reader#read api bytes in - let m = read MTF in - delay ctx PBuildClass (fun () -> - ignore(read EOT); - delay ctx PConnectField (fun () -> - ignore(read EOM); - ); + let m = read EOT in + delay ctx PConnectField (fun () -> + ignore(read EOM); ); m with e -> diff --git a/std/haxe/hxb/WriterConfig.hx b/std/haxe/hxb/WriterConfig.hx new file mode 100644 index 00000000000..7796dfdf228 --- /dev/null +++ b/std/haxe/hxb/WriterConfig.hx @@ -0,0 +1,51 @@ +package haxe.hxb; + +typedef WriterTargetConfig = { + /** + If `false`, this target is ignored by the writer. + **/ + var ?generate:Null; + + /** + Dot paths of modules or packages to be exluded from the archive. + **/ + var ?exclude:Null>; + + /** + Dot paths of modules or packages to be included in the archive. This takes priority + over exclude. By default, all modules that aren't explicitly excluded are + included. + **/ + var ?include:Null>; + + /** + The hxb version to target. By default, the version of the Haxe compiler itself + is targeted. See https://github.com/HaxeFoundation/haxe/issues/11505 + **/ + var ?hxbVersion:Null; + + /** + If false, no documentation + **/ + var ?generateDocumentation:Null; +} + +typedef WriterConfig = { + /** + The file path for the archive. Occurrences of `$target` are replaced + by the name of the current target (js, hl, etc.). + **/ + var archivePath:String; + + /** + The configuration for the current target context. If it is `null`, all data + for the target context is generated. + **/ + var ?targetConfig:Null; + + /** + The configuration for the macro context. If it is `null`, all data for the + macro context is generated. + **/ + var ?macroConfig:Null; +} diff --git a/std/haxe/macro/Compiler.hx b/std/haxe/macro/Compiler.hx index a2d581985d0..03701de4b96 100644 --- a/std/haxe/macro/Compiler.hx +++ b/std/haxe/macro/Compiler.hx @@ -24,6 +24,7 @@ package haxe.macro; import haxe.display.Display; import haxe.macro.Expr; +import haxe.hxb.WriterConfig; /** All these methods can be called for compiler configuration macros. @@ -576,6 +577,40 @@ class Compiler { } } #end + + /** + Gets the current hxb writer configuration, if any. + **/ + static public function getHxbWriterConfiguration():Null { + #if macro + return load("get_hxb_writer_config", 0)(); + #else + return null; + #end + } + + /** + Sets the hxb writer configuration to `config`. If no hxb writer configuration + exists, it is created. + + The intended usage is + + ``` + var config = Compiler.getHxbWriterConfiguration(); + config.archivePath = "newPath.zip"; + // Other changes + Compiler.setHxbWriterConfiguration(config); + ``` + + If `config` is `null`, hxb writing is disabled. + + @see haxe.hxb.WriterConfig + **/ + static public function setHxbWriterConfiguration(config:Null) { + #if macro + load("set_hxb_writer_config", 1)(config); + #end + } } enum abstract IncludePosition(String) from String to String { 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 60cf3bac680..1e7dc411b9f 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:505: characters 11-39 : Called from here +$$normPath(::std::)/haxe/macro/Compiler.hx:506: 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 ced31cb8f78..3e26bc6c365 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:494: characters 11-39 : Called from here +$$normPath(::std::)/haxe/macro/Compiler.hx:495: 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 9a4f93d7093..4e87b73bfb0 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:494: characters 11-39 : Called from here + $$normPath(::std::)/haxe/macro/Compiler.hx:495: 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 2160c2c1753..29619b177df 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:494: characters 11-39 + -> $$normPath(::std::)/haxe/macro/Compiler.hx:495: characters 11-39 - 494 | var f = sys.io.File.getContent(path); + 495 | var f = sys.io.File.getContent(path); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Called from here diff --git a/tests/unit/compile-hxb-jvm-roundtrip.hxml b/tests/unit/compile-hxb-jvm-roundtrip.hxml index 90646475c41..121de138f11 100644 --- a/tests/unit/compile-hxb-jvm-roundtrip.hxml +++ b/tests/unit/compile-hxb-jvm-roundtrip.hxml @@ -1,7 +1,7 @@ compile-jvm-only.hxml ---hxb bin/hxb/jvm.zip +--hxb hxb-config/jvm.json --next compile-jvm-only.hxml ---hxb-lib bin/hxb/jvm.zip \ No newline at end of file +--hxb-lib bin/hxb/unit.java.zip \ No newline at end of file diff --git a/tests/unit/hxb-config/jvm.json b/tests/unit/hxb-config/jvm.json new file mode 100644 index 00000000000..61707a6ea6a --- /dev/null +++ b/tests/unit/hxb-config/jvm.json @@ -0,0 +1,10 @@ +{ + "archivePath": "bin/hxb/unit.$target.zip", + "targetConfig": { + "exclude": ["unit.TestMainNow"], + "generateDocumentation": false + }, + "macroConfig": { + "generateDocumentation": false + } +} \ No newline at end of file diff --git a/tests/unit/src/unit/TestMain.hx b/tests/unit/src/unit/TestMain.hx index 2fa17c82da7..044bfd3f0ee 100644 --- a/tests/unit/src/unit/TestMain.hx +++ b/tests/unit/src/unit/TestMain.hx @@ -31,9 +31,7 @@ function main() { cs.system.threading.Thread.CurrentThread.CurrentCulture = new cs.system.globalization.CultureInfo('tr-TR'); cs.Lib.applyCultureChanges(); #end - #if !macro - trace("Generated at: " + HelperMacros.getCompilationDate()); - #end + TestMainNow.printNow(); trace("START"); #if flash var tf:flash.text.TextField = untyped flash.Boot.getTrace(); diff --git a/tests/unit/src/unit/TestMainNow.hx b/tests/unit/src/unit/TestMainNow.hx new file mode 100644 index 00000000000..fa44d5fdf31 --- /dev/null +++ b/tests/unit/src/unit/TestMainNow.hx @@ -0,0 +1,9 @@ +package unit; + +class TestMainNow { + static public function printNow() { + #if !macro + trace("Generated at: " + HelperMacros.getCompilationDate()); + #end + } +} From 8e0855c742be90a73f91fdf046df5209012fdd19 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 07:34:33 +0100 Subject: [PATCH 22/32] [jvm] Assign dynamic method only if it's null (#11530) * [jvm] assign dynamic method only if it's null * finalize ctor args --- src/generators/genjvm.ml | 12 +- tests/unit/src/unit/TestMisc.hx | 457 ++++++++++++++++---------------- 2 files changed, 240 insertions(+), 229 deletions(-) diff --git a/src/generators/genjvm.ml b/src/generators/genjvm.ml index 10701eb7738..ca7cbfcb533 100644 --- a/src/generators/genjvm.ml +++ b/src/generators/genjvm.ml @@ -2392,6 +2392,7 @@ class tclass_to_jvm gctx c = object(self) let jsig_empty = method_sig [haxe_empty_constructor_sig] None in let jm_empty_ctor = jc#spawn_method "" jsig_empty [MPublic;MSynthetic] in let _,load,_ = jm_empty_ctor#add_local "_" haxe_empty_constructor_sig VarArgument in + jm_empty_ctor#finalize_arguments; jm_empty_ctor#load_this; if c.cl_constructor = None then begin let handler = new texpr_to_jvm gctx None jc jm_empty_ctor None in @@ -2432,6 +2433,7 @@ class tclass_to_jvm gctx c = object(self) let _,load,_ = jm#add_local n (jsignature_of_type gctx t) VarArgument in load(); ) tl; + jm#finalize_arguments; jm#call_super_ctor cmode jm#get_jsig; DynArray.iter (fun e -> handler#texpr RVoid e; @@ -2548,7 +2550,15 @@ class tclass_to_jvm gctx c = object(self) let ethis = mk (TConst TThis) (TInst(c,tl)) null_pos in let efield = mk (TField(ethis,FInstance(c,tl,cf))) cf.cf_type null_pos in let eop = mk (TBinop(OpAssign,efield,e)) cf.cf_type null_pos in - DynArray.add (match cf.cf_kind with Method MethDynamic -> delayed_field_inits | _ -> field_inits) eop; + begin match cf.cf_kind with + | Method MethDynamic -> + let enull = Texpr.Builder.make_null efield.etype null_pos in + let echeck = Texpr.Builder.binop OpEq efield enull gctx.com.basic.tbool null_pos in + let eif = mk (TIf(echeck,eop,None)) gctx.com.basic.tvoid null_pos in + DynArray.add delayed_field_inits eif + | _ -> + DynArray.add field_inits eop + end | Some e -> match e.eexpr with | TConst ct -> diff --git a/tests/unit/src/unit/TestMisc.hx b/tests/unit/src/unit/TestMisc.hx index 9759b2b8ec8..dc023ba45ac 100644 --- a/tests/unit/src/unit/TestMisc.hx +++ b/tests/unit/src/unit/TestMisc.hx @@ -1,9 +1,9 @@ package unit; + import unit.MyClass; class MyDynamicClass { - - var v : Int; + var v:Int; public function new(v) { this.v = v; @@ -13,74 +13,74 @@ class MyDynamicClass { return v; } - public dynamic function add(x,y) { + public dynamic function add(x, y) { return v + x + y; } - public inline function iadd(x,y) { + public inline function iadd(x, y) { return v + x + y; } static var Z = 10; - public dynamic static function staticDynamic(x,y) { + public dynamic static function staticDynamic(x, y) { return Z + x + y; } - @:isVar public static var W(get, set) : Int = 55; - static function get_W() return W + 2; - static function set_W(v) { W = v; return v; } + @:isVar public static var W(get, set):Int = 55; + + static function get_W() + return W + 2; + static function set_W(v) { + W = v; + return v; + } } class MyDynamicSubClass extends MyDynamicClass { - - override function add(x,y) { + override function add(x, y) { return (v + x + y) * 2; } - } class MyDynamicSubClass2 extends MyDynamicClass { - - override dynamic function add(x,y) { + override dynamic function add(x, y) { return (v + x + y) * 2; } - } class MyOtherDynamicClass extends MyDynamicClass { - public function new(v) { - add = function(x,y) return x + y + 10; + add = function(x, y) return x + y + 10; super(v); } - } interface IDefArgs { - public function get( x : Int = 5 ) : Int; + public function get(x:Int = 5):Int; } class BaseDefArgs { - public function get( x = 3 ) { + public function get(x = 3) { return x; } } class ExtDefArgs extends BaseDefArgs implements IDefArgs { - public function new() { - } - override function get( x = 7 ) { + public function new() {} + + override function get(x = 7) { return x; } } class BaseConstrOpt { - public var s : String; - public var i : Int; - public var b : Bool; - public function new( s = "test", i = -5, b = true ) { + public var s:String; + public var i:Int; + public var b:Bool; + + public function new(s = "test", i = -5, b = true) { this.s = s; this.i = i; this.b = b; @@ -98,8 +98,8 @@ class SubConstrOpt2 extends BaseConstrOpt { } class SubConstrOpt3 extends BaseConstrOpt { - public function new( s = "test2", i = -6 ) { - super(s,i); + public function new(s = "test2", i = -6) { + super(s, i); } } @@ -110,127 +110,125 @@ enum abstract MyEnumAbstract(Int) { } class TestMisc extends Test { - static var unit = "testing package conflict"; - function testPackageConflict() - { - eq( unit, "testing package conflict" ); + function testPackageConflict() { + eq(unit, "testing package conflict"); var unit = unit; - eq( unit, TestMisc.unit ); + eq(unit, TestMisc.unit); } function testDate() { var d = new Date(2012, 7, 17, 1, 2, 3); - eq( d.getDay(), 5 ); + eq(d.getDay(), 5); - eq( d.getDate(), 17 ); - eq( d.getMonth(), 7 ); - eq( d.getFullYear(), 2012 ); + eq(d.getDate(), 17); + eq(d.getMonth(), 7); + eq(d.getFullYear(), 2012); - eq( d.getHours(), 1 ); - eq( d.getMinutes(), 2 ); - eq( d.getSeconds(), 3 ); + eq(d.getHours(), 1); + eq(d.getMinutes(), 2); + eq(d.getSeconds(), 3); - //seems to be system-dependent? - //eq( d.getTime(), 1345158123000 ); - eq( d.toString(), "2012-08-17 01:02:03" ); + // seems to be system-dependent? + // eq( d.getTime(), 1345158123000 ); + eq(d.toString(), "2012-08-17 01:02:03"); } function testClosure() { var c = new MyClass(100); var add = c.add; - eq( c.add(1,2), 103 ); - eq( c.add.bind(1)(2), 103 ); - eq( add(1,2), 103 ); + eq(c.add(1, 2), 103); + eq(c.add.bind(1)(2), 103); + eq(add(1, 2), 103); var x = 4; var f = function() return x; - eq( f(), 4 ); + eq(f(), 4); x++; - eq( f(), 5 ); + eq(f(), 5); - var o = { f : f }; - eq( o.f(), 5 ); - eq( o.f, o.f ); // we shouldn't create a new closure here + var o = {f: f}; + eq(o.f(), 5); + eq(o.f, o.f); // we shouldn't create a new closure here - var o = { add : c.add }; - eq( o.add(1,2), 103 ); - eq( o.add, o.add ); // we shouldn't create a new closure here + var o = {add: c.add}; + eq(o.add(1, 2), 103); + eq(o.add, o.add); // we shouldn't create a new closure here - var o = { cos : Math.cos }; - eq( o.cos(0), 1. ); + var o = {cos: Math.cos}; + eq(o.cos(0), 1.); // check enum var c = MyEnum.C; - t( Type.enumEq(MyEnum.C(1,"hello"), c(1,"hello")) ); + t(Type.enumEq(MyEnum.C(1, "hello"), c(1, "hello"))); } // make sure that captured variables does not overlap each others even if in different scopes function testCaptureUnique() { var foo = null, bar = null; var flag = true; - if( flag ) { + if (flag) { var x = 1; foo = function() return x; } - if( flag ) { + if (flag) { var x = 2; bar = function() return x; } - eq( foo(), 1); - eq( bar(), 2); + eq(foo(), 1); + eq(bar(), 2); } function testCaptureUnique2() { // another more specialized test (was actually the original broken code - but not reproducible when optimization is off) var foo = id.bind(3); var bar = sq.bind(5); - eq( foo(), 3 ); - eq( bar(), 25 ); + eq(foo(), 3); + eq(bar(), 25); } function testSelfRef() { // check for self-name binding var bla = 55; var bla = function() return bla; - eq( bla(), 55); + eq(bla(), 55); } function testHiddenType() { var haxe = 20; - eq( std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e"); - eq( haxe, 20); + eq(std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e"); + eq(haxe, 20); var Std = 50; - eq( std.Std.int(45.3), 45); - eq( Std, 50); + eq(std.Std.int(45.3), 45); + eq(Std, 50); } function testHiddenTypeScope() { var flag = true; - if( flag ) { + if (flag) { var haxe = 20; var Std = 50; - eq( haxe, 20); - eq( Std, 50); + eq(haxe, 20); + eq(Std, 50); } - eq( std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e"); - eq( std.Std.int(45.3), 45); + eq(std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e"); + eq(std.Std.int(45.3), 45); } function testHiddenTypeCapture() { var flag = true; var foo = null, bar = null; - if( flag ) { + if (flag) { var haxe = 20; var Std = 50; foo = function() return haxe; bar = function() return Std; } - eq( std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e"); - eq( std.Std.int(45.3), 45); - eq( foo(), 20); - eq( bar(), 50); + eq(std.haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e"); + eq(std.Std.int(45.3), 45); + eq(foo(), 20); + eq(bar(), 50); } function id(x:T) { @@ -248,80 +246,83 @@ class TestMisc extends Test { function testInlineClosure() { var inst = new MyDynamicClass(100); var add = inst.iadd; - eq( inst.iadd(1,2), 103 ); - eq( add(1,2), 103 ); + eq(inst.iadd(1, 2), 103); + eq(add(1, 2), 103); } function testDynamicClosure() { var inst = new MyDynamicClass(100); var add = inst.add; - eq( inst.add(1,2), 103 ); - eq( inst.add.bind(1)(2), 103 ); - eq( add(1,2), 103 ); + eq(inst.add(1, 2), 103); + eq(inst.add.bind(1)(2), 103); + eq(add(1, 2), 103); // check overridden dynamic method var inst = new MyDynamicSubClass(100); var add = inst.add; - eq( inst.add(1,2), 206 ); - eq( inst.add.bind(1)(2), 206 ); - eq( add(1,2), 206 ); + eq(inst.add(1, 2), 206); + eq(inst.add.bind(1)(2), 206); + eq(add(1, 2), 206); // check overridden dynamic method var inst = new MyDynamicSubClass2(100); var add = inst.add; - eq( inst.add(1,2), 206 ); - eq( inst.add.bind(1)(2), 206 ); - eq( add(1,2), 206 ); + eq(inst.add(1, 2), 206); + eq(inst.add.bind(1)(2), 206); + eq(add(1, 2), 206); // check redefined dynamic method - inst.add = function(x,y) return inst.get() * 2 + x + y; + inst.add = function(x, y) return inst.get() * 2 + x + y; var add = inst.add; - eq( inst.add(1,2), 203 ); - eq( inst.add.bind(1)(2), 203 ); - eq( add(1,2), 203 ); + eq(inst.add(1, 2), 203); + eq(inst.add.bind(1)(2), 203); + eq(add(1, 2), 203); // check inherited dynamic method var inst = new MyOtherDynamicClass(0); var add = inst.add; - #if (!cs && !java) //see https://groups.google.com/d/msg/haxedev/TUaUykoTpq8/Q4XwcL4UyNUJ - eq( inst.add(1,2), 13 ); - eq( inst.add.bind(1)(2), 13 ); - eq( add(1,2), 13 ); + #if (!cs && (!java || jvm)) // see https://groups.google.com/d/msg/haxedev/TUaUykoTpq8/Q4XwcL4UyNUJ + eq(inst.add(1, 2), 13); + eq(inst.add.bind(1)(2), 13); + eq(add(1, 2), 13); #end // check static dynamic - eq( MyDynamicClass.staticDynamic(1,2), 13 ); - MyDynamicClass.staticDynamic = function(x,y) return x + y + 100; - eq( MyDynamicClass.staticDynamic(1,2), 103 ); + eq(MyDynamicClass.staticDynamic(1, 2), 13); + MyDynamicClass.staticDynamic = function(x, y) return x + y + 100; + eq(MyDynamicClass.staticDynamic(1, 2), 103); } - function testMakeVarArgs () { - var f = function (a:Array) { + function testMakeVarArgs() { + var f = function(a:Array) { eq(a.length, 2); return a[0] + a[1]; } var g = Reflect.makeVarArgs(f); - var res = g(1,2); + var res = g(1, 2); eq(3, res); } function testMD5() { - eq( haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e" ); - eq( haxe.crypto.Md5.encode("hello"), "5d41402abc4b2a76b9719d911017c592" ); + eq(haxe.crypto.Md5.encode(""), "d41d8cd98f00b204e9800998ecf8427e"); + eq(haxe.crypto.Md5.encode("hello"), "5d41402abc4b2a76b9719d911017c592"); // depending of ISO/UTF8 native - allow( haxe.crypto.Md5.encode("héllo"), ["1a722f7e6c801d9e470a10cb91ba406d", "be50e8478cf24ff3595bc7307fb91b50"] ); + allow(haxe.crypto.Md5.encode("héllo"), ["1a722f7e6c801d9e470a10cb91ba406d", "be50e8478cf24ff3595bc7307fb91b50"]); - eq( haxe.io.Bytes.ofString("héllo").toHex(), "68c3a96c6c6f"); - eq( haxe.crypto.Md5.make(haxe.io.Bytes.ofString("héllo")).toHex(), "be50e8478cf24ff3595bc7307fb91b50" ); + eq(haxe.io.Bytes.ofString("héllo").toHex(), "68c3a96c6c6f"); + eq(haxe.crypto.Md5.make(haxe.io.Bytes.ofString("héllo")).toHex(), "be50e8478cf24ff3595bc7307fb91b50"); } function testSHA1() { - eq( haxe.crypto.Sha1.encode(""), "da39a3ee5e6b4b0d3255bfef95601890afd80709" ); - eq( haxe.crypto.Sha1.encode("hello"), "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d" ); + eq(haxe.crypto.Sha1.encode(""), "da39a3ee5e6b4b0d3255bfef95601890afd80709"); + eq(haxe.crypto.Sha1.encode("hello"), "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d"); // depending of ISO/UTF8 native - allow( haxe.crypto.Sha1.encode("héllo"), ["028db752c14604d624e8b1c121d600c427b8a3ba","35b5ea45c5e41f78b46a937cc74d41dfea920890"] ); + allow(haxe.crypto.Sha1.encode("héllo"), [ + "028db752c14604d624e8b1c121d600c427b8a3ba", + "35b5ea45c5e41f78b46a937cc74d41dfea920890" + ]); - eq( haxe.crypto.Sha1.make(haxe.io.Bytes.ofString("héllo")).toHex(), "35b5ea45c5e41f78b46a937cc74d41dfea920890" ); + eq(haxe.crypto.Sha1.make(haxe.io.Bytes.ofString("héllo")).toHex(), "35b5ea45c5e41f78b46a937cc74d41dfea920890"); } function testBaseCode() { @@ -338,84 +339,84 @@ class TestMisc extends Test { // alternative base64 var b = new haxe.crypto.BaseCode(haxe.io.Bytes.ofString("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-")); - eq( b.encodeString("Héllow"), "iceFr6NLtM" ); - eq( b.decodeString("iceFr6NLtM"), "Héllow" ); + eq(b.encodeString("Héllow"), "iceFr6NLtM"); + eq(b.decodeString("iceFr6NLtM"), "Héllow"); // base32-hex var b = new haxe.crypto.BaseCode(haxe.io.Bytes.ofString("0123456789ABCDEFGHIJKLMNOPQRSTUV")); - eq( b.encodeString("foo"), "CPNMU" ); - eq( b.decodeString("CPNMU"), "foo" ); + eq(b.encodeString("foo"), "CPNMU"); + eq(b.decodeString("CPNMU"), "foo"); } function testUrlEncode() { - eq( StringTools.urlEncode("é"), "%C3%A9" ); - eq( StringTools.urlDecode("%C3%A9"), "é" ); + eq(StringTools.urlEncode("é"), "%C3%A9"); + eq(StringTools.urlDecode("%C3%A9"), "é"); - eq( StringTools.urlEncode("a/b+c"), "a%2Fb%2Bc"); - eq( StringTools.urlDecode("a%2Fb%2Bc"), "a/b+c"); + eq(StringTools.urlEncode("a/b+c"), "a%2Fb%2Bc"); + eq(StringTools.urlDecode("a%2Fb%2Bc"), "a/b+c"); } - function opt1( ?x : Int, ?y : String ) { - return { x : x, y : y }; + function opt1(?x:Int, ?y:String) { + return {x: x, y: y}; } - function opt2( ?x = 5, ?y = "hello" ) { - return { x : x, y : y }; + function opt2(?x = 5, ?y = "hello") { + return {x: x, y: y}; } - function opt3( ?x : Null = 5, ?y : Null = 6 ) { - return { x : x, y : y }; + function opt3(?x:Null = 5, ?y:Null = 6) { + return {x: x, y: y}; } - function opt4( x = 10 ) : Null { + function opt4(x = 10):Null { return x + 1; } function testOptionalParams() { - eq( opt1().x, null ); - eq( opt1().y, null ); - eq( opt1(55).x, 55 ); - eq( opt1(55).y, null ); - eq( opt1("str").x, null ); - eq( opt1("str").y, "str" ); - eq( opt1(66,"hello").x, 66 ); - eq( opt1(66, "hello").y, "hello" ); - - eq( opt2().x, 5 ); - eq( opt2().y, "hello" ); + eq(opt1().x, null); + eq(opt1().y, null); + eq(opt1(55).x, 55); + eq(opt1(55).y, null); + eq(opt1("str").x, null); + eq(opt1("str").y, "str"); + eq(opt1(66, "hello").x, 66); + eq(opt1(66, "hello").y, "hello"); + + eq(opt2().x, 5); + eq(opt2().y, "hello"); #if !(flash || cpp || cs || java) - eq( opt2(null, null).x, 5 ); + eq(opt2(null, null).x, 5); #end - eq( opt2(0, null).y, "hello" ); - - eq( opt3().x, 5 ); - eq( opt3().y, 6 ); - eq( opt3(9).x, 9 ); - eq( opt3(9).y, 6 ); - eq( opt3(9,10).x, 9 ); - eq( opt3(9,10).y, 10 ); - eq( opt3(null,null).x, 5 ); - eq( opt3(null,null).y, 6 ); - eq( opt3(null).x, 5 ); - eq( opt3(null).y, 6 ); - eq( opt3(null,7).x, 5 ); - eq( opt3(null, 7).y, 7 ); + eq(opt2(0, null).y, "hello"); + + eq(opt3().x, 5); + eq(opt3().y, 6); + eq(opt3(9).x, 9); + eq(opt3(9).y, 6); + eq(opt3(9, 10).x, 9); + eq(opt3(9, 10).y, 10); + eq(opt3(null, null).x, 5); + eq(opt3(null, null).y, 6); + eq(opt3(null).x, 5); + eq(opt3(null).y, 6); + eq(opt3(null, 7).x, 5); + eq(opt3(null, 7).y, 7); // skipping - eq( opt3(7.4).x, 5 ); - eq( opt3(7.4).y, 7.4 ); + eq(opt3(7.4).x, 5); + eq(opt3(7.4).y, 7.4); - eq( opt4(), 11 ); + eq(opt4(), 11); #if !static - eq( opt4(null), 11 ); + eq(opt4(null), 11); #end - var opt4b : ?Int -> Null = opt4; - eq( opt4b(), 11 ); - eq( opt4b(3), 4 ); + var opt4b:?Int->Null = opt4; + eq(opt4b(), 11); + eq(opt4b(3), 4); #if !static - eq( opt4b(null), 11 ); + eq(opt4b(null), 11); #end // don't compile because we restrict nullability of function param or return type @@ -430,107 +431,108 @@ class TestMisc extends Test { function testIncr() { var z = 0; - eq( z++, 0 ); - eq( z, 1 ); - eq( ++z, 2 ); - eq( z, 2 ); + eq(z++, 0); + eq(z, 1); + eq(++z, 2); + eq(z, 2); z++; - eq( z, 3 ); + eq(z, 3); ++z; - eq( z, 4 ); + eq(z, 4); - eq( z += 3, 7 ); + eq(z += 3, 7); var x = 0; var arr = [3]; - eq( arr[x++]++, 3 ); - eq( x, 1 ); - eq( arr[0], 4 ); + eq(arr[x++]++, 3); + eq(x, 1); + eq(arr[0], 4); x = 0; - eq( arr[x++] += 3, 7 ); - eq( arr[0], 7 ); + eq(arr[x++] += 3, 7); + eq(arr[0], 7); var x = 0; - var arr = [{ v : 3 }]; - eq( arr[x++].v++, 3 ); - eq( x, 1 ); - eq( arr[0].v, 4 ); + var arr = [{v: 3}]; + eq(arr[x++].v++, 3); + eq(x, 1); + eq(arr[0].v, 4); x = 0; - eq( arr[x++].v += 3, 7 ); - eq( arr[0].v, 7 ); + eq(arr[x++].v += 3, 7); + eq(arr[0].v, 7); x = 0; - var arr:Dynamic = [{ v : 3 }]; - eq( arr[x++].v++, 3 ); - eq( x, 1 ); - eq( arr[0].v, 4 ); + var arr:Dynamic = [{v: 3}]; + eq(arr[x++].v++, 3); + eq(x, 1); + eq(arr[0].v, 4); x = 0; - eq( arr[x++].v += 3, 7 ); - eq( arr[0].v, 7 ); + eq(arr[x++].v += 3, 7); + eq(arr[0].v, 7); } function testInitOrder() { var i = 0; var o = { - y : i++, - x : i++, - z : i++, - blabla : i++, + y: i++, + x: i++, + z: i++, + blabla: i++, }; - eq(o.y,0); - eq(o.x,1); - eq(o.z,2); - eq(o.blabla,3); + eq(o.y, 0); + eq(o.x, 1); + eq(o.z, 2); + eq(o.blabla, 3); } - static inline function foo(x) return x + 5; + static inline function foo(x) + return x + 5; function testInline() { // check that operations are correctly generated var x = 3; // prevent optimization - eq( 2 * foo(x), 16 ); - eq( -foo(x), -8 ); + eq(2 * foo(x), 16); + eq(-foo(x), -8); } function testEvalAccessOrder() { - var a = [0,0]; + var a = [0, 0]; var x = 0; a[x++]++; - eq(a[0],1); - eq(a[1],0); + eq(a[0], 1); + eq(a[1], 0); var x = 0; var a = new Array(); a[x++] = x++; - eq(a[0],1); + eq(a[0], 1); var x = 0; var foo = function() return x++; a[foo()] = foo(); - eq(a[0],1); + eq(a[0], 1); } - static var add = function (x, y) return x + y; + static var add = function(x, y) return x + y; function testStaticVarFun() { - eq( add(2,3), 5); + eq(add(2, 3), 5); } function testDefArgs() { var e = new ExtDefArgs(); - eq( e.get(), 7 ); - var b : BaseDefArgs = e; - eq( b.get(), 7 ); - var i : IDefArgs = e; - eq( i.get(), 7 ); + eq(e.get(), 7); + var b:BaseDefArgs = e; + eq(b.get(), 7); + var i:IDefArgs = e; + eq(i.get(), 7); } function testStringBuf() { var b = new StringBuf(); eq(b.length, 0); - b.add( -45); + b.add(-45); b.add(1.456); b.add(null); b.add(true); @@ -542,26 +544,23 @@ class TestMisc extends Test { eq(b.length, 30); } - function testToString():Void - { - var x = { toString : function() return "foo" }; - eq( Std.string(x), "foo" ); - - //var x1:Dynamic = new MyDynamicChildWithToString(); - //eq( Std.string(x1), "Custom toString" ); -// - //var x2:Dynamic = new MyDynamicChildWithoutToString(); - //x2.toString = function() return "foo"; - //eq( Std.string(x2), "foo" ); + function testToString():Void { + var x = {toString: function() return "foo"}; + eq(Std.string(x), "foo"); + // var x1:Dynamic = new MyDynamicChildWithToString(); + // eq( Std.string(x1), "Custom toString" ); + // + // var x2:Dynamic = new MyDynamicChildWithoutToString(); + // x2.toString = function() return "foo"; + // eq( Std.string(x2), "foo" ); } #if !macro - function testFormat() - { + function testFormat() { var x = 5; var y = 6; - eq('$x${x+y}', "511"); + eq('$x${x + y}', "511"); } #end @@ -596,16 +595,18 @@ class TestMisc extends Test { function test():String { throw "never call me"; }; - var s = try test() catch(e:String) e; - eq(s,"never call me"); + var s = try test() catch (e:String) e; + eq(s, "never call me"); - function test():String throw "never call me"; - var s = try test() catch(e:String) e; - eq(s,"never call me"); + function test():String + throw "never call me"; + var s = try test() catch (e:String) e; + eq(s, "never call me"); } static var nf1:Base = null; static var nf2:{s:String} = null; + function testNullFieldAccess() { eq("NPE", try nf1.s catch (e:Any) "NPE"); eq("NPE", try nf2.s catch (e:Any) "NPE"); From 887272dd1ca306b89c38da448aaf0103c5d14137 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 10:26:32 +0100 Subject: [PATCH 23/32] [jvm] fix invokeDynamic arity --- src/generators/jvm/jvmFunctions.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/jvm/jvmFunctions.ml b/src/generators/jvm/jvmFunctions.ml index 1d4058db9f3..af4167b0d8f 100644 --- a/src/generators/jvm/jvmFunctions.ml +++ b/src/generators/jvm/jvmFunctions.ml @@ -178,7 +178,7 @@ class typed_functions = object(self) jm#finalize_arguments; load(); jm#get_code#arraylength array_sig; - let cases = ExtList.List.init max_arity (fun i -> + let cases = ExtList.List.init (max_arity + 1) (fun i -> [Int32.of_int i],(fun () -> jm#load_this; let args = ExtList.List.init i (fun index -> From 2e17ec6c002029e694e3f700653440e5ce55878f Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 11:19:35 +0100 Subject: [PATCH 24/32] [jvm] use HashMap for IntMap too --- std/jvm/_std/haxe/ds/IntMap.hx | 91 ++++++++++++ tests/unit/src/unit/issues/Issue5862.hx | 181 ++++++++++++------------ 2 files changed, 184 insertions(+), 88 deletions(-) create mode 100644 std/jvm/_std/haxe/ds/IntMap.hx diff --git a/std/jvm/_std/haxe/ds/IntMap.hx b/std/jvm/_std/haxe/ds/IntMap.hx new file mode 100644 index 00000000000..9ae196cb388 --- /dev/null +++ b/std/jvm/_std/haxe/ds/IntMap.hx @@ -0,0 +1,91 @@ +/* + * Copyright (C)2005-2019 Haxe Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +package haxe.ds; + +@:coreApi +class IntMap implements haxe.Constraints.IMap { + var hashMap:java.util.HashMap; + + @:overload + public function new():Void { + hashMap = new java.util.HashMap(); + } + + @:overload + function new(hashMap:java.util.HashMap):Void { + this.hashMap = hashMap; + } + + public function set(key:Int, value:T):Void { + hashMap.put(key, value); + } + + public function get(key:Int):Null { + return hashMap.get(key); + } + + public function exists(key:Int):Bool { + return hashMap.containsKey(key); + } + + public function remove(key:Int):Bool { + var has = exists(key); + hashMap.remove(key); + return has; + } + + public inline function keys():Iterator { + return hashMap.keySet().iterator(); + } + + @:runtime public inline function keyValueIterator():KeyValueIterator { + return new haxe.iterators.MapKeyValueIterator(this); + } + + public inline function iterator():Iterator { + return hashMap.values().iterator(); + } + + public function copy():IntMap { + return new IntMap(hashMap.clone()); + } + + public function toString():String { + var s = new StringBuf(); + s.add("["); + var it = keys(); + for (i in it) { + s.add(Std.string(i)); + s.add(" => "); + s.add(Std.string(get(i))); + if (it.hasNext()) + s.add(", "); + } + s.add("]"); + return s.toString(); + } + + public function clear():Void { + hashMap.clear(); + } +} diff --git a/tests/unit/src/unit/issues/Issue5862.hx b/tests/unit/src/unit/issues/Issue5862.hx index 1ff8e731372..5638da7465f 100644 --- a/tests/unit/src/unit/issues/Issue5862.hx +++ b/tests/unit/src/unit/issues/Issue5862.hx @@ -1,4 +1,5 @@ package unit.issues; + import haxe.ds.*; #if java import java.NativeArray; @@ -7,105 +8,109 @@ import cs.NativeArray; #end class Issue5862 extends Test { -#if (java || cs) - public function test() { - var imap = new IntMap(); - imap.set(0, "val1"); - imap.set(1, "val2"); - imap.set(2, "val3"); - imap.set(2, "changed_val3"); + #if (java || cs) + public function test() { + var imap = new IntMap(); + imap.set(0, "val1"); + imap.set(1, "val2"); + imap.set(2, "val3"); + imap.set(2, "changed_val3"); - var v:Vector = cast @:privateAccess imap.vals; - for (i in 0...v.length) { - t(v[i] != "val3"); - } + #if !jvm + var v:Vector = cast @:privateAccess imap.vals; + for (i in 0...v.length) { + t(v[i] != "val3"); + } + #end - var smap = new StringMap(); - smap.set("v1", "val1"); - smap.set("v2", "val2"); - smap.set("v3", "val3"); - smap.set("v3", "changed_val3"); + var smap = new StringMap(); + smap.set("v1", "val1"); + smap.set("v2", "val2"); + smap.set("v3", "val3"); + smap.set("v3", "changed_val3"); - #if !jvm - var v:Vector = cast @:privateAccess smap.vals; - for (i in 0...v.length) { - t(v[i] != "val3"); - } - #end + #if !jvm + var v:Vector = cast @:privateAccess smap.vals; + for (i in 0...v.length) { + t(v[i] != "val3"); + } + #end - var omap = new ObjectMap<{}, String>(); - omap.set(imap, "val1"); - omap.set(smap, "val2"); - omap.set(omap, "val3"); - omap.set(omap, "changed_val3"); + var omap = new ObjectMap<{}, String>(); + omap.set(imap, "val1"); + omap.set(smap, "val2"); + omap.set(omap, "val3"); + omap.set(omap, "changed_val3"); - var v:Vector = cast @:privateAccess omap.vals; - for (i in 0...v.length) { - t(v[i] != "val3"); - } -#if java - var wmap = new WeakMap<{}, String>(); - wmap.set(imap, "val1"); - wmap.set(smap, "val2"); - wmap.set(omap, "val3"); - wmap.set(omap, "changed_val3"); + var v:Vector = cast @:privateAccess omap.vals; + for (i in 0...v.length) { + t(v[i] != "val3"); + } + #if java + var wmap = new WeakMap<{}, String>(); + wmap.set(imap, "val1"); + wmap.set(smap, "val2"); + wmap.set(omap, "val3"); + wmap.set(omap, "changed_val3"); - var v = @:privateAccess wmap.entries; - for (i in 0...v.length) { - t(v[i] == null || v[i].value != "val3"); - } -#end + var v = @:privateAccess wmap.entries; + for (i in 0...v.length) { + t(v[i] == null || v[i].value != "val3"); + } + #end - var imap = new IntMap(); - imap.set(0, "val1"); - imap.set(1, "val2"); - imap.set(2, "val3"); - imap.set(2, "changed_val3"); - imap.set(1, "changed_val2"); + var imap = new IntMap(); + imap.set(0, "val1"); + imap.set(1, "val2"); + imap.set(2, "val3"); + imap.set(2, "changed_val3"); + imap.set(1, "changed_val2"); - var v:Vector = cast @:privateAccess imap.vals; - for (i in 0...v.length) { - t(v[i] != "val2"); - } + #if !jvm + var v:Vector = cast @:privateAccess imap.vals; + for (i in 0...v.length) { + t(v[i] != "val2"); + } + #end - var smap = new StringMap(); - smap.set("v1", "val1"); - smap.set("v2", "val2"); - smap.set("v3", "val3"); - smap.set("v3", "changed_val3"); - smap.set("v2", "changed_val2"); + var smap = new StringMap(); + smap.set("v1", "val1"); + smap.set("v2", "val2"); + smap.set("v3", "val3"); + smap.set("v3", "changed_val3"); + smap.set("v2", "changed_val2"); - #if !jvm - var v:Vector = cast @:privateAccess smap.vals; - for (i in 0...v.length) { - t(v[i] != "val2"); - } - #end + #if !jvm + var v:Vector = cast @:privateAccess smap.vals; + for (i in 0...v.length) { + t(v[i] != "val2"); + } + #end - var omap = new ObjectMap<{}, String>(); - omap.set(imap, "val1"); - omap.set(smap, "val2"); - omap.set(omap, "val3"); - omap.set(omap, "changed_val3"); - omap.set(smap, "changed_val2"); + var omap = new ObjectMap<{}, String>(); + omap.set(imap, "val1"); + omap.set(smap, "val2"); + omap.set(omap, "val3"); + omap.set(omap, "changed_val3"); + omap.set(smap, "changed_val2"); - var v:Vector = cast @:privateAccess omap.vals; - for (i in 0...v.length) { - t(v[i] != "val2"); - } -#if java - var wmap = new WeakMap<{}, String>(); - wmap.set(imap, "val1"); - wmap.set(smap, "val2"); - wmap.set(omap, "val3"); - wmap.set(omap, "changed_val3"); - wmap.set(smap, "changed_val2"); + var v:Vector = cast @:privateAccess omap.vals; + for (i in 0...v.length) { + t(v[i] != "val2"); + } + #if java + var wmap = new WeakMap<{}, String>(); + wmap.set(imap, "val1"); + wmap.set(smap, "val2"); + wmap.set(omap, "val3"); + wmap.set(omap, "changed_val3"); + wmap.set(smap, "changed_val2"); - var v = @:privateAccess wmap.entries; - for (i in 0...v.length) { - t(v[i] == null || v[i].value != "val2"); - } -#end - } -#end + var v = @:privateAccess wmap.entries; + for (i in 0...v.length) { + t(v[i] == null || v[i].value != "val2"); + } + #end + } + #end } From 1939a7b211ca16f501fa3ebff620d1f47c917b47 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 11:32:14 +0100 Subject: [PATCH 25/32] [typer] don't type trailing optional bind arguments so weirdly (#11533) see #11531 --- src/typing/calls.ml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/typing/calls.ml b/src/typing/calls.ml index 2839847ec4a..3261058c30b 100644 --- a/src/typing/calls.ml +++ b/src/typing/calls.ml @@ -368,16 +368,10 @@ let type_bind ctx (e : texpr) (args,ret) params p = let rec loop args params given_args missing_args ordered_args = match args, params with | [], [] -> given_args,missing_args,ordered_args | [], _ -> raise_typing_error "Too many callback arguments" p - | (n,o,t) :: args , [] when o -> - let a = if is_pos_infos t then - let infos = mk_infos ctx p [] in - ordered_args @ [type_expr ctx infos (WithType.with_argument t n)] - else if ctx.com.config.pf_pad_nulls && ctx.allow_transform then - (ordered_args @ [(mk (TConst TNull) t_dynamic p)]) - else - ordered_args - in - loop args [] given_args missing_args a + | [n,o,t] , [] when o && is_pos_infos t -> + let infos = mk_infos ctx p [] in + let ordered_args = ordered_args @ [type_expr ctx infos (WithType.with_argument t n)] in + given_args,missing_args,ordered_args | (n,o,t) :: _ , (EConst(Ident "_"),p) :: _ when not ctx.com.config.pf_can_skip_non_nullable_argument && o && not (is_nullable t) -> raise_typing_error "Usage of _ is not supported for optional non-nullable arguments" p | (n,o,t) :: args , ([] as params) From 7f6d2747dfa60361bf649f3a5632d5ba3e909837 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Thu, 1 Feb 2024 19:42:40 +0100 Subject: [PATCH 26/32] 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 27/32] 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 28/32] 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 29/32] [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 30/32] [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 31/32] 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 32/32] 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