فهرست منبع

[java/cs] Added @:implicitCast to mark where an implicit cast took place, and penalize implicit casts on overload selection

Cauê Waneck 10 سال پیش
والد
کامیت
1422aee8fc
4فایلهای تغییر یافته به همراه23 افزوده شده و 7 حذف شده
  1. 2 1
      ast.ml
  2. 19 5
      codegen.ml
  3. 1 0
      common.ml
  4. 1 1
      tests/unit/src/unit/TestJava.hx

+ 2 - 1
ast.ml

@@ -90,6 +90,7 @@ module Meta = struct
 		| IfFeature
 		| Impl
 		| PythonImport
+		| ImplicitCast
 		| Include
 		| InitPackage
 		| Internal
@@ -747,4 +748,4 @@ let get_value_meta meta =
 			| _ -> raise Not_found
 		end
 	with Not_found ->
-		PMap.empty
+		PMap.empty

+ 19 - 5
codegen.ml

@@ -690,7 +690,10 @@ module AbstractCast = struct
 			if (Meta.has Meta.MultiType a.a_meta) then
 				mk_cast eright tleft p
 			else match a.a_impl with
-				| Some c -> recurse cf (fun () -> make_static_call ctx c cf a tl [eright] tleft p)
+				| Some c -> recurse cf (fun () ->
+					let ret = make_static_call ctx c cf a tl [eright] tleft p in
+					{ ret with eexpr = TMeta( (Meta.ImplicitCast,[],ret.epos), ret) }
+				)
 				| None -> assert false
 		in
 		if type_iseq tleft eright.etype then
@@ -1546,6 +1549,13 @@ struct
 		List.iter2 (fun f a -> if not (type_iseq f a) then incr acc) tlfun tlarg;
 		!acc
 
+	(**
+		The rate function returns an ( int * int ) type.
+		The smaller the int, the best rated the caller argument is in comparison with the callee.
+
+		The first int refers to how many "conversions" would be necessary to convert from the callee to the caller type, and
+		the second refers to the type parameters.
+	**)
 	let rec rate_conv cacc tfun targ =
 		match simplify_t tfun, simplify_t targ with
 		| TInst({ cl_interface = true } as cf, tlf), TInst(ca, tla) ->
@@ -1668,7 +1678,14 @@ struct
 				| [], [] -> acc
 				| (_,true) :: elist, _ :: args -> mk_rate acc elist args
 				| (e,false) :: elist, (n,o,t) :: args ->
-					mk_rate (rate_conv 0 t e.etype :: acc) elist args
+					(* if the argument is an implicit cast, we need to start with a penalty *)
+					(* The penalty should be higher than any other implicit cast - other than Dynamic *)
+					(* since Dynamic has a penalty of max_int, we'll impose max_int - 1 to it *)
+					(match e.eexpr with
+						| TMeta( (Meta.ImplicitCast,_,_), _) ->
+							mk_rate ((max_int - 1, 0) :: acc) elist args
+						| _ ->
+							mk_rate (rate_conv 0 t e.etype :: acc) elist args)
 				| _ -> assert false
 			in
 
@@ -1680,9 +1697,6 @@ struct
 				| _ -> assert false
 			) compatible;
 
-			print_endline "=====";
-			print_endline (s_options (!rated));
-
 			let rec loop best rem = match best, rem with
 				| _, [] -> best
 				| [], r1 :: rem -> loop [r1] rem

+ 1 - 0
common.ml

@@ -412,6 +412,7 @@ module MetaInfo = struct
 		| IfFeature -> ":ifFeature",("Causes a field to be kept by DCE if the given feature is part of the compilation",[HasParam "Feature name";UsedOn TClassField])
 		| Impl -> ":impl",("Used internally to mark abstract implementation fields",[UsedOn TAbstractField; Internal])
 		| PythonImport -> ":pythonImport",("Generates python import statement for extern classes",[Platforms [Python]; UsedOn TClass])
+		| ImplicitCast -> ":implicitCast",("Generated automatically on the AST when an implicit abstract cast happens",[Internal; UsedOn TExpr])
 		| Include -> ":include",("",[Platform Cpp])
 		| InitPackage -> ":initPackage",("?",[])
 		| Meta.Internal -> ":internal",("Generates the annotated field/class with 'internal' access",[Platforms [Java;Cs]; UsedOnEither[TClass;TEnum;TClassField]])

+ 1 - 1
tests/unit/src/unit/TestJava.hx

@@ -119,7 +119,7 @@ class TestJava extends Test
 		var c = new TestMyClass();
 		c.normalOverload(true);
 		t(c.boolCalled);
-		c.normalOverload(10);
+		c.normalOverload(6161);
 		t(c.intCalled);
 		c.normalOverload(haxe.Int64.ofInt(0));
 		t(c.int64Called);