Bläddra i källkod

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

Cauê Waneck 10 år sedan
förälder
incheckning
1422aee8fc
4 ändrade filer med 23 tillägg och 7 borttagningar
  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);