瀏覽代碼

[java] Do not change parameters of recursive type parameters. Closes #3173

Cauê Waneck 10 年之前
父節點
當前提交
903d0ef47e
共有 5 個文件被更改,包括 70 次插入22 次删除
  1. 12 11
      gencommon.ml
  2. 1 1
      gencs.ml
  3. 12 2
      genjava.ml
  4. 33 0
      tests/unit/src/unit/issues/Issue3173.hx
  5. 12 8
      typeload.ml

+ 12 - 11
gencommon.ml

@@ -1354,7 +1354,8 @@ type tfield_access =
 
 let is_var f = match f.cf_kind with | Var _ -> true | _ -> false
 
-let find_first_declared_field gen orig_cl ?exact_field field =
+let find_first_declared_field gen orig_cl ?get_vmtype ?exact_field field =
+	let get_vmtype = match get_vmtype with None -> (fun t -> t) | Some f -> f in
 	let chosen = ref None in
 	let is_overload = ref false in
 	let rec loop_cl depth c tl tlch =
@@ -1368,7 +1369,7 @@ let find_first_declared_field gen orig_cl ?exact_field field =
 			| _, Some f2 ->
 				List.iter (fun f ->
 					let declared_t = apply_params c.cl_params tl f.cf_type in
-					if Typeload.same_overload_args declared_t f2.cf_type f f2 then
+					if Typeload.same_overload_args ~get_vmtype declared_t f2.cf_type f f2 then
 						chosen := Some(depth,f,c,tl,tlch)
 				) (ret :: ret.cf_overloads)
 		with | Not_found -> ());
@@ -10935,7 +10936,7 @@ struct
 		specify a explicit_fn_name function (tclass->string->string)
 		Otherwise, it expects the platform to be able to handle covariant return types
 	*)
-	let run ~explicit_fn_name gen =
+	let run ~explicit_fn_name ~get_vmtype gen =
 		let implement_explicitly = is_some explicit_fn_name in
 		let run md = match md with
 			| TClassDecl ( { cl_interface = true; cl_extern = false } as c ) ->
@@ -10969,7 +10970,7 @@ struct
 								| (_, cf) :: _ when Meta.has Meta.Overload cf.cf_meta -> (* overloaded function *)
 									(* try to find exact function *)
 									List.find (fun (t,f2) ->
-										Typeload.same_overload_args ftype t f f2
+										Typeload.same_overload_args ~get_vmtype ftype t f f2
 									) overloads
 								| _ :: _ ->
 									(match field_access gen (TInst(c, List.map snd c.cl_params)) f.cf_name with
@@ -10985,7 +10986,7 @@ struct
 								if List.length f.cf_params <> List.length f2.cf_params then raise Not_found;
 								replace_mono t2;
 								match follow (apply_params f2.cf_params (List.map snd f.cf_params) t2), follow real_ftype with
-								| TFun(a1,r1), TFun(a2,r2) when not implement_explicitly && not (type_iseq r1 r2) && Typeload.same_overload_args real_ftype t2 f f2 ->
+								| TFun(a1,r1), TFun(a2,r2) when not implement_explicitly && not (type_iseq r1 r2) && Typeload.same_overload_args ~get_vmtype real_ftype t2 f f2 ->
 									(* different return types are the trickiest cases to deal with *)
 									(* check for covariant return type *)
 									let is_covariant = match follow r1, follow r2 with
@@ -11011,7 +11012,7 @@ struct
 								| TFun(a1,r1), TFun(a2,r2) ->
 									(* just implement a function that will call the main one *)
 									let name, is_explicit = match explicit_fn_name with
-										| Some fn when not (type_iseq r1 r2) && Typeload.same_overload_args real_ftype t2 f f2 ->
+										| Some fn when not (type_iseq r1 r2) && Typeload.same_overload_args ~get_vmtype real_ftype t2 f f2 ->
 												fn iface itl f.cf_name, true
 										| _ -> f.cf_name, false
 									in
@@ -11061,13 +11062,13 @@ struct
 					(* find the first declared field *)
 					let is_overload = Meta.has Meta.Overload f.cf_meta in
 					let decl = if is_overload then
-						find_first_declared_field gen c ~exact_field:f f.cf_name
+						find_first_declared_field gen c ~get_vmtype ~exact_field:f f.cf_name
 					else
-						find_first_declared_field gen c f.cf_name
+						find_first_declared_field gen c ~get_vmtype f.cf_name
 					in
 					match decl with
 					| Some(f2,actual_t,_,t,declared_cl,_,_)
-						when not (Typeload.same_overload_args actual_t (get_real_fun gen f.cf_type) f2 f) ->
+						when not (Typeload.same_overload_args ~get_vmtype actual_t (get_real_fun gen f.cf_type) f2 f) ->
 							if Meta.has Meta.Overload f.cf_meta then begin
 								(* if it is overload, create another field with the requested type *)
 								let f3 = mk_class_field f.cf_name t f.cf_public f.cf_pos f.cf_kind f.cf_params in
@@ -11132,12 +11133,12 @@ struct
 		in
 		run
 
-	let configure ?explicit_fn_name gen =
+	let configure ?explicit_fn_name ~get_vmtype gen =
 		let delay () =
 			Hashtbl.clear gen.greal_field_types
 		in
 		gen.gafter_mod_filters_ended <- delay :: gen.gafter_mod_filters_ended;
-		let run = run ~explicit_fn_name:explicit_fn_name gen in
+		let run = run ~explicit_fn_name ~get_vmtype gen in
 		let map md = Some(run md) in
 		gen.gmodule_filters#add ~name:name ~priority:(PCustom priority) map
 end;;

+ 1 - 1
gencs.ml

@@ -2729,7 +2729,7 @@ let configure gen =
 		path_param_s (TClassDecl c) c.cl_path tl ^ "." ^ fname
 	in
 
-	FixOverrides.configure ~explicit_fn_name:explicit_fn_name gen;
+	FixOverrides.configure ~explicit_fn_name:explicit_fn_name ~get_vmtype:real_type gen;
 	Normalize.configure gen ~metas:(Hashtbl.create 0);
 
 	AbstractImplementationFix.configure gen;

+ 12 - 2
genjava.ml

@@ -854,7 +854,8 @@ let configure gen =
 										TType(nulltdef, [f_t])
 									(*| TType ({ t_path = [], "Null"*)
 									| TInst (cl, ((_ :: _) as p)) when cl.cl_path <> (["java"],"NativeArray") ->
-										TInst(cl, List.map (fun _ -> t_dynamic) p)
+										(* TInst(cl, List.map (fun _ -> t_dynamic) p) *)
+										TInst(cl,p)
 									| TEnum (e, ((_ :: _) as p)) ->
 										TEnum(e, List.map (fun _ -> t_dynamic) p)
 									| _ -> t
@@ -2068,7 +2069,16 @@ let configure gen =
 
 	StubClosureImpl.configure gen (StubClosureImpl.default_implementation gen float_cl 10 (fun e _ _ -> e));*)
 
-	FixOverrides.configure gen;
+	let get_vmtype t = match real_type t with
+		| TInst({ cl_path = ["java"],"NativeArray" }, tl) -> t
+		| TInst(c,tl) -> TInst(c,List.map (fun _ -> t_dynamic) tl)
+		| TEnum(e,tl) -> TEnum(e, List.map (fun _ -> t_dynamic) tl)
+		| TType(t,tl) -> TType(t, List.map (fun _ -> t_dynamic) tl)
+		| TAbstract(a,tl) -> TAbstract(a, List.map (fun _ -> t_dynamic) tl)
+		| t -> t
+	in
+
+	FixOverrides.configure ~get_vmtype gen;
 	Normalize.configure gen ~metas:(Hashtbl.create 0);
 	AbstractImplementationFix.configure gen;
 

+ 33 - 0
tests/unit/src/unit/issues/Issue3173.hx

@@ -0,0 +1,33 @@
+package unit.issues;
+import haxe.ds.StringMap;
+
+class Issue3173 extends Test
+{
+	public function test()
+	{
+		var o2 = new O2();
+		eq(o2.foo(null), 1);
+		var o:O<StringMap<Int>> = o2;
+		eq(o.foo(null), 1);
+	}
+}
+
+private class O2 extends O<StringMap<Int>>
+{
+	public function new()
+	{
+	}
+
+	@:overload override public function foo(t:StringMap<Int>):Int
+	{
+		return 1;
+	}
+}
+
+private class O<T>
+{
+	@:overload public function foo(t:T):Int
+	{
+		return 0;
+	}
+}

+ 12 - 8
typeload.ml

@@ -772,7 +772,11 @@ let copy_meta meta_src meta_target sl =
 	) meta_src;
 	!meta
 
-let same_overload_args t1 t2 f1 f2 =
+let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
+	let get_vmtype = match get_vmtype with
+		| None -> (fun f -> f)
+		| Some f -> f
+	in
 	if List.length f1.cf_params <> List.length f2.cf_params then
 		false
 	else
@@ -790,13 +794,13 @@ let same_overload_args t1 t2 f1 f2 =
 		| _ -> t
 	in
 	let same_arg t1 t2 =
-	let t1 = follow_skip_null t1 in
-	let t2 = follow_skip_null t2 in
-	match follow_skip_null t1, follow_skip_null t2 with
-		| TType _, TType _ -> type_iseq t1 t2
-		| TType _, _
-		| _, TType _ -> false
-		| _ -> type_iseq t1 t2
+		let t1 = get_vmtype (follow_skip_null t1) in
+		let t2 = get_vmtype (follow_skip_null t2) in
+		match t1, t2 with
+			| TType _, TType _ -> type_iseq t1 t2
+			| TType _, _
+			| _, TType _ -> false
+			| _ -> type_iseq t1 t2
 	in
 
 	match follow (apply_params f1.cf_params (List.map (fun (_,t) -> t) f2.cf_params) t1), follow t2 with