Răsfoiți Sursa

Add NativeStackTrace, Exception and ValueException as dependencies everywhere it's used

Rudy Ges 2 luni în urmă
părinte
comite
dcb17bb44b

+ 8 - 10
src/filters/exception/exceptionInit.ml

@@ -28,19 +28,19 @@ let create_exception_context tctx =
 			let t = Typeload.load_instance tctx (tp config.ec_base_throw) ParamSpawnMonos LoadNormal in
 			if is_dynamic t then t_dynamic
 			else t
-		and haxe_exception_type, haxe_exception_class =
+		and haxe_exception = Lazy.from_fun (fun () ->
 			match Typeload.load_instance tctx (tp haxe_exception_type_path) ParamSpawnMonos LoadNormal with
 			| TInst(cls,_) as t -> t,cls
-			| _ -> raise_typing_error "haxe.Exception is expected to be a class" null_pos
-		and value_exception_type, value_exception_class =
+			| _ -> raise_typing_error "haxe.Exception is expected to be a class" null_pos)
+		and value_exception = Lazy.from_fun (fun () ->
 			match Typeload.load_instance tctx (tp value_exception_type_path) ParamSpawnMonos LoadNormal with
 			| TInst(cls,_) as t -> t,cls
-			| _ -> raise_typing_error "haxe.ValueException is expected to be a class" null_pos
-		and haxe_native_stack_trace =
+			| _ -> raise_typing_error "haxe.ValueException is expected to be a class" null_pos)
+		and haxe_native_stack_trace = Lazy.from_fun (fun () ->
 			match Typeload.load_instance tctx (tp (["haxe"],"NativeStackTrace")) ParamSpawnMonos LoadNormal with
 			| TInst(cls,_) -> cls
 			| TAbstract({ a_impl = Some cls },_) -> cls
-			| _ -> raise_typing_error "haxe.NativeStackTrace is expected to be a class or an abstract" null_pos
+			| _ -> raise_typing_error "haxe.NativeStackTrace is expected to be a class or an abstract" null_pos)
 		in
 		let is_path_of_dynamic (pack,name) =
 			name = "Dynamic" && (pack = [] || pack = ["StdTypes"])
@@ -66,11 +66,9 @@ let create_exception_context tctx =
 			base_throw_type = base_throw_type;
 			throws_anything = is_path_of_dynamic config.ec_base_throw && config.ec_avoid_wrapping;
 			catches_anything = is_path_of_dynamic config.ec_wildcard_catch && config.ec_avoid_wrapping;
-			haxe_exception_class = haxe_exception_class;
-			haxe_exception_type = haxe_exception_type;
+			haxe_exception = haxe_exception;
 			haxe_native_stack_trace = haxe_native_stack_trace;
-			value_exception_type = value_exception_type;
-			value_exception_class = value_exception_class;
+			value_exception = value_exception;
 			is_of_type = is_of_type;
 		} in
 		Some ctx

+ 35 - 17
src/filters/exception/exceptions.ml

@@ -12,20 +12,38 @@ type context = {
 	base_throw_type : Type.t;
 	throws_anything : bool;
 	catches_anything : bool;
-	haxe_exception_class : tclass;
-	haxe_exception_type : Type.t;
-	haxe_native_stack_trace : tclass;
-	value_exception_type : Type.t;
-	value_exception_class : tclass;
+	haxe_exception : (Type.t * tclass) Lazy.t;
+	haxe_native_stack_trace : tclass Lazy.t;
+	value_exception : (Type.t * tclass) Lazy.t;
 	is_of_type : (tclass * tclass_field * Type.t);
 }
 
+let haxe_exception_class ctx =
+	let cls = snd (Lazy.force ctx.haxe_exception) in
+	add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
+	cls
+
+let haxe_exception_type ctx =
+	let t,cls = Lazy.force ctx.haxe_exception in
+	add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
+	t
+
+let value_exception_class ctx =
+	let cls = snd (Lazy.force ctx.value_exception) in
+	add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
+	cls
+
+let value_exception_type ctx =
+	let t,cls = Lazy.force ctx.value_exception in
+	add_dependency ctx.scom.curclass.cl_module cls.cl_module MDepFromTyping;
+	t
+
 (**
 	Generate `haxe.Exception.method_name(args)`
 *)
 let haxe_exception_static_call ctx method_name args p =
 	let method_field =
-		try PMap.find method_name ctx.haxe_exception_class.cl_statics
+		try PMap.find method_name (haxe_exception_class ctx).cl_statics
 		with Not_found -> raise_typing_error ("haxe.Exception has no field " ^ method_name) p
 	in
 	let return_type =
@@ -33,8 +51,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.scom.curclass.cl_module ctx.haxe_exception_class.cl_module MDepFromTyping;
-	make_static_call ctx.scom ctx.haxe_exception_class method_field args return_type p
+	make_static_call ctx.scom (haxe_exception_class ctx) method_field args return_type p
 
 (**
 	Generate `haxe_exception.method_name(args)`
@@ -99,7 +116,7 @@ let is_native_catch ctx t =
 *)
 let is_haxe_wildcard_catch ctx t =
 	let t = Abstract.follow_with_abstracts t in
-	t == t_dynamic || fast_eq ctx.haxe_exception_type t
+	t == t_dynamic || fast_eq (haxe_exception_type ctx) t
 
 
 (**
@@ -179,7 +196,7 @@ class catch ctx catch_local catch_pos =
 			let v =
 				match hx_exception_var with
 				| None ->
-					let v = alloc_var VGenerated gen_local_prefix ctx.haxe_exception_type p in
+					let v = alloc_var VGenerated gen_local_prefix (haxe_exception_type ctx) p in
 					hx_exception_var <- Some v;
 					v
 				| Some v -> v
@@ -237,7 +254,7 @@ let catches_to_ifs ctx catches t p =
 					if is_haxe_exception current_t then
 						let condition =
 							(* catch(e:haxe.Exception) is a wildcard catch *)
-							if fast_eq ctx.haxe_exception_type current_t then
+							if fast_eq (haxe_exception_type ctx) current_t then
 								mk (TConst (TBool true)) ctx.basic.tbool v.v_pos
 							else
 								std_is ctx (catch#get_haxe_exception v.v_pos) v.v_type v.v_pos
@@ -358,7 +375,7 @@ let catches_as_value_exception ctx non_value_exception_catches value_exception_c
 			| Some (catch_var, _) ->
 				catch_var
 			| None ->
-				let catch_var = alloc_var VGenerated gen_local_prefix ctx.value_exception_type first_v.v_pos in
+				let catch_var = alloc_var VGenerated gen_local_prefix (value_exception_type ctx) first_v.v_pos in
 				add_var_flag catch_var VCaught;
 				catch_var
 		in
@@ -368,10 +385,10 @@ let catches_as_value_exception ctx non_value_exception_catches value_exception_c
 		(* catch_local.value *)
 		let catch_local_value =
 			let cf =
-				try PMap.find "value" ctx.value_exception_class.cl_fields
+				try PMap.find "value" (value_exception_class ctx).cl_fields
 				with Not_found -> die "haxe.ValueException is missing field \"value\"" __LOC__
 			in
-			mk (TField (catch_local, FInstance (ctx.value_exception_class,[],cf))) cf.cf_type catch_local.epos
+			mk (TField (catch_local, FInstance (value_exception_class ctx,[],cf))) cf.cf_type catch_local.epos
 		in
 		let rec traverse catches final_else =
 			match catches with
@@ -451,7 +468,7 @@ let catch_native ctx catches t p =
 				catches_as_value_exception ctx handle_as_value_exception None t p
 				:: catches_to_ifs ctx catches t p
 			)
-		| (v,_) as current :: rest when ctx.catches_anything && fast_eq ctx.value_exception_type (Abstract.follow_with_abstracts v.v_type) ->
+		| (v,_) as current :: rest when ctx.catches_anything && fast_eq (value_exception_type ctx) (Abstract.follow_with_abstracts v.v_type) ->
 			catches_as_value_exception ctx handle_as_value_exception (Some current) t p
 			:: transform [] (Some (Option.default current value_exception_catch)) rest
 		(* Keep catches for native exceptions intact *)
@@ -481,10 +498,11 @@ let catch_native ctx catches t p =
 	Transform `throw` and `try..catch` expressions.
 	`rename_locals` is required to deal with the names of temp vars.
 *)
-let filter ectx =
+let filter ectx (scom:SafeCom.t) =
 	let stub e = e in
 	match ectx with
 	| Some ctx ->
+		let ctx = { ctx with scom } in
 		let rec run e =
 			match e.eexpr with
 			| TThrow e1 ->
@@ -503,4 +521,4 @@ let filter ectx =
 			else stub e
 		)
 	| None ->
-		stub
+		stub

+ 11 - 9
src/filters/exception/saveStacks.ml

@@ -9,7 +9,12 @@ open Exceptions
 	Inserts `haxe.NativeStackTrace.saveStack(e)` in non-haxe.Exception catches.
 *)
 let insert_save_stacks ectx scom =
-	let native_stack_trace_cls = ectx.haxe_native_stack_trace in
+	let native_stack_trace_cls () =
+		let cls = Lazy.force ectx.haxe_native_stack_trace in
+		add_dependency scom.curclass.cl_module cls.cl_module MDepFromTyping;
+		cls
+	in
+
 	let rec contains_insertion_points e =
 		match e.eexpr with
 		| TTry (e, catches) ->
@@ -21,7 +26,7 @@ let insert_save_stacks ectx scom =
 	in
 	let save_exception_stack catch_var =
 		let method_field =
-			try PMap.find "saveStack" native_stack_trace_cls.cl_statics
+			try PMap.find "saveStack" (native_stack_trace_cls ()).cl_statics
 			with Not_found -> raise_typing_error ("haxe.NativeStackTrace has no field saveStack") null_pos
 		in
 		let return_type =
@@ -30,10 +35,7 @@ let insert_save_stacks ectx scom =
 			| _ -> raise_typing_error ("haxe.NativeStackTrace." ^ method_field.cf_name ^ " is not a function and cannot be called") null_pos
 		in
 		let catch_local = mk (TLocal catch_var) catch_var.v_type catch_var.v_pos in
-		begin
-			add_dependency scom.curclass.cl_module native_stack_trace_cls.cl_module MDepFromTyping;
-			make_static_call scom native_stack_trace_cls method_field [catch_local] return_type catch_var.v_pos
-		end
+		make_static_call scom (native_stack_trace_cls ()) method_field [catch_local] return_type catch_var.v_pos
 	in
 	let rec run e =
 		match e.eexpr with
@@ -67,7 +69,7 @@ let insert_save_stacks ectx scom =
 	Adds `this.__shiftStack()` calls to constructors of classes which extend `haxe.Exception`
 *)
 let patch_constructors ectx =
-	match ectx.haxe_exception_type with
+	match fst (Lazy.force ectx.haxe_exception) with
 	(* Add only if `__shiftStack` method exists *)
 	| TInst(cls,_) when PMap.mem "__shiftStack" cls.cl_fields ->
 		(fun mt ->
@@ -122,6 +124,6 @@ let patch_constructors ectx =
 let patch_constructors ectx scom =
 	match ectx with
 	| Some ctx ->
-		patch_constructors {ctx with scom = scom}
+		patch_constructors {ctx with scom}
 	| None ->
-		(fun _ -> ())
+		(fun _ -> ())

+ 1 - 1
src/filters/filters.ml

@@ -432,7 +432,7 @@ let run_safe_filters ectx com (scom : SafeCom.t) all_types_array new_types_array
 	let filters_before_analyzer = [
 		"reduce_expression",Optimizer.reduce_expression;
 		"inline_constructors",InlineConstructors.inline_constructors;
-		"Exceptions_filter",(fun _ -> Exceptions.filter ectx);
+		"Exceptions_filter",Exceptions.filter ectx;
 		"captured_vars",(fun scom -> CapturedVars.captured_vars scom cv_wrapper_impl);
 	] in
 

+ 1 - 1
src/typing/macroContext.ml

@@ -656,7 +656,7 @@ and flush_macro_context mint mctx =
 		let expr_filters = [
 			"handle_abstract_casts",AbstractCast.handle_abstract_casts;
 			"local_statics",LocalStatic.run;
-			"Exceptions",(fun _ -> Exceptions.filter ectx);
+			"Exceptions",Exceptions.filter ectx;
 			"captured_vars",(fun scom -> CapturedVars.captured_vars scom mctx.com.local_wrapper);
 		] in
 		let type_filters = [

+ 11 - 0
tests/server/src/cases/ServerTests.hx

@@ -540,6 +540,17 @@ class ServerTests extends TestCase {
 		assertSuccess();
 	}
 
+	function test12289() {
+		vfs.putContent("Empty.hx", getTemplate("Empty.hx"));
+		vfs.putContent("StringTools.hx", sys.io.File.getContent(haxe.io.Path.join([Sys.getCwd(), "../../std/StringTools.hx"])));
+
+		var args = ["-main", "Empty", "-js", "out.js", "--no-output"];
+		runHaxe(args);
+		runHaxeJson([], ServerMethods.Invalidate, {file: new FsPath("StringTools.hx")});
+		runHaxe(args);
+		assertSuccess();
+	}
+
 	function test11179() {
 		vfs.putContent("Main.hx", getTemplate("issues/Issue11179/Main.hx"));
 		var args = ["-main", "Main", "--macro", 'nullSafety("Main", Strict)', "--interp"];