Bläddra i källkod

[java] Correctly allow boxed types to be used. Closes #2964

Cauê Waneck 10 år sedan
förälder
incheckning
d9d88b3f96
5 ändrade filer med 154 tillägg och 8 borttagningar
  1. 15 7
      genjava.ml
  2. 49 0
      std/java/lang/Long.hx
  3. 47 0
      tests/unit/native_java/src/haxe/test/MyClass.java
  4. 36 0
      tests/unit/src/unit/TestJava.hx
  5. 7 1
      typeload.ml

+ 15 - 7
genjava.ml

@@ -111,6 +111,14 @@ let is_bool t =
 			true
 		| _ -> false
 
+let like_bool t =
+	match follow t with
+		| TAbstract ({ a_path = ([], "Bool") },[])
+		| TAbstract ({ a_path = (["java";"lang"],"Boolean") },[])
+		| TInst ({ cl_path = (["java";"lang"],"Boolean") },[]) ->
+			true
+		| _ -> false
+
 let is_int_float gen t =
 	match follow (gen.greal_type t) with
 		| TInst( { cl_path = (["haxe"], "Int32") }, [] )
@@ -544,10 +552,10 @@ struct
 
 	let traverse gen runtime_cl =
 		let basic = gen.gcon.basic in
-		let tchar = mt_to_t_dyn ( get_type gen (["java"], "Char16") ) in
-		let tbyte = mt_to_t_dyn ( get_type gen (["java"], "Int8") ) in
-		let tshort = mt_to_t_dyn ( get_type gen (["java"], "Int16") ) in
-		let tsingle = mt_to_t_dyn ( get_type gen ([], "Single") ) in
+		(* let tchar = mt_to_t_dyn ( get_type gen (["java"], "Char16") ) in *)
+		(* let tbyte = mt_to_t_dyn ( get_type gen (["java"], "Int8") ) in *)
+		(* let tshort = mt_to_t_dyn ( get_type gen (["java"], "Int16") ) in *)
+		(* let tsingle = mt_to_t_dyn ( get_type gen ([], "Single") ) in *)
 		let string_ext = get_cl ( get_type gen (["haxe";"lang"], "StringExt")) in
 
 		let is_string t = match follow t with | TInst({ cl_path = ([], "String") }, []) -> true | _ -> false in
@@ -585,9 +593,9 @@ struct
 (*				 | TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("toString") })) }, [] ) ->
 					run ef *)
 
-				| TCast(expr, m) when is_boxed_type e.etype ->
-					(* let unboxed_type gen t tbyte tshort tchar tfloat = match follow t with *)
-					run { e with etype = unboxed_type gen e.etype tbyte tshort tchar tsingle }
+				(* | TCast(expr, m) when is_boxed_type e.etype -> *)
+				(* 	(* let unboxed_type gen t tbyte tshort tchar tfloat = match follow t with *) *)
+				(* 	run { e with etype = unboxed_type gen e.etype tbyte tshort tchar tsingle } *)
 
 				| TCast(expr, _) when is_bool e.etype ->
 					{

+ 49 - 0
std/java/lang/Long.hx

@@ -0,0 +1,49 @@
+package java.lang;
+
+@:forward abstract Long(LongClass) from LongClass to LongClass
+{
+	@:to @:extern inline public function toLong():haxe.Int64
+		return this.longValue();
+	@:from @:extern inline public static function fromLong(b:haxe.Int64):Long
+		return LongClass.valueOf(b);
+}
+
+@:native("java.lang.Long") extern class LongClass extends Number implements Comparable<Long>
+{
+	@:overload @:throws("java.lang.NumberFormatException") function new(param1 : String) : Void;
+	@:overload function new(param1 : haxe.Int64) : Void;
+	@:overload function compareTo(param1 : Dynamic) : Int;
+	@:overload function compareTo(param1 : Long) : Int;
+	@:overload function equals(param1 : Dynamic) : Bool;
+	@:overload function hashCode() : Int;
+	@:overload function toString() : String;
+	@:final static var MAX_VALUE(default,null) : haxe.Int64;
+	@:final static var MIN_VALUE(default,null) : haxe.Int64;
+	@:final static var SIZE(default,null) : Int;
+	@:final static var TYPE : Class<Long>;
+	@:overload static function bitCount(param1 : haxe.Int64) : Int;
+	@:overload static function compare(param1 : haxe.Int64, param2 : haxe.Int64) : Int;
+	@:overload @:throws("java.lang.NumberFormatException") static function decode(param1 : String) : Long;
+	@:overload static function getLong(param1 : String, param2 : Long) : Long;
+	@:overload static function getLong(param1 : String) : Long;
+	@:overload static function getLong(param1 : String, param2 : haxe.Int64) : Long;
+	@:overload static function highestOneBit(param1 : haxe.Int64) : haxe.Int64;
+	@:overload static function lowestOneBit(param1 : haxe.Int64) : haxe.Int64;
+	@:overload static function numberOfLeadingZeros(param1 : haxe.Int64) : Int;
+	@:overload static function numberOfTrailingZeros(param1 : haxe.Int64) : Int;
+	@:overload @:throws("java.lang.NumberFormatException") static function parseLong(param1 : String) : haxe.Int64;
+	@:overload @:throws("java.lang.NumberFormatException") static function parseLong(param1 : String, param2 : Int) : haxe.Int64;
+	@:overload static function reverse(param1 : haxe.Int64) : haxe.Int64;
+	@:overload static function reverseBytes(param1 : haxe.Int64) : haxe.Int64;
+	@:overload static function rotateLeft(param1 : haxe.Int64, param2 : Int) : haxe.Int64;
+	@:overload static function rotateRight(param1 : haxe.Int64, param2 : Int) : haxe.Int64;
+	@:overload static function signum(param1 : haxe.Int64) : Int;
+	@:overload static function toBinaryString(param1 : haxe.Int64) : String;
+	@:overload static function toHexString(param1 : haxe.Int64) : String;
+	@:overload static function toOctalString(param1 : haxe.Int64) : String;
+	@:native("toString") @:overload static function _toString(param1 : haxe.Int64) : String;
+	@:native("toString") @:overload static function _toString(param1 : haxe.Int64, param2 : Int) : String;
+	@:overload static function valueOf(param1 : haxe.Int64) : Long;
+	@:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String, param2 : Int) : Long;
+	@:overload @:throws("java.lang.NumberFormatException") static function valueOf(param1 : String) : Long;
+}

+ 47 - 0
tests/unit/native_java/src/haxe/test/MyClass.java

@@ -23,6 +23,53 @@ public class MyClass
 
 	}
 
+	public int boolTest1(Boolean value)
+	{
+		if (value == null)
+			return 100;
+		return value.booleanValue() ? 1 : 0;
+	}
+
+	public boolean boolTest1(boolean i)
+	{
+		return i;
+	}
+
+	public int boolTest2(Boolean value)
+	{
+		if (value == null)
+			return 100;
+		return value.booleanValue() ? 1 : 0;
+	}
+
+	public int intTest2(Integer value)
+	{
+		if (value == null)
+			return 100;
+		return value.intValue();
+	}
+
+	public int intTest1(Integer value)
+	{
+		if (value == null)
+			return 100;
+		return value.intValue();
+	}
+
+	public long intTest1(Long value)
+	{
+		if (value == null)
+			return -100L;
+		return -value.longValue();
+	}
+
+	public long longTest(Long value)
+	{
+		if (value == null)
+			return 100L;
+		return value.longValue();
+	}
+
 	public void normalOverload(long a)
 	{
 

+ 36 - 0
tests/unit/src/unit/TestJava.hx

@@ -29,6 +29,42 @@ class TestJava extends Test
     catch(e:Dynamic) throw e; //shouldn't throw any exception
   }
 
+	public function testIssue2964()
+	{
+		var cl = new MyClass();
+		var bbool:java.lang.Boolean = null;
+		eq(cl.boolTest1(bbool), 100);
+		eq(cl.boolTest1(true), true);
+		eq(cl.boolTest1(false), false);
+		bbool = true;
+		eq(cl.boolTest1(bbool), 1);
+		bbool = false;
+		eq(cl.boolTest1(bbool), 0);
+		eq(cl.boolTest2(null), 100);
+		eq(cl.boolTest2(true), 1);
+		eq(cl.boolTest2(false), 0);
+
+		var i:java.lang.Integer = null;
+		eq(cl.intTest1(i), 100);
+		eq(cl.intTest1(cast(-1, java.lang.Integer)),-1);
+		eq(cl.intTest1(cast(1000, java.lang.Integer)),1000);
+		i = -1;
+		eq(cl.intTest1(i), -1);
+		i = null;
+		eq(cl.intTest2(i), 100);
+		eq(cl.intTest2(-1),-1);
+		eq(cl.intTest2(1000),1000);
+		i = -1;
+		eq(cl.intTest2(i), -1);
+
+		var i:java.lang.Long = null;
+		eq(cl.longTest(i), 100);
+		eq(cl.longTest(haxe.Int64.ofInt(-1)),-1);
+		eq(cl.longTest(haxe.Int64.ofInt(1000)),1000);
+		i = 10;
+		eq(cl.longTest(i), 10);
+	}
+
 	public function testVarClash()
 	{
 		var ic = new Base_InnerClass2();

+ 7 - 1
typeload.ml

@@ -1798,6 +1798,12 @@ let build_enum_abstract ctx c a fields p =
 	) fields;
 	EVars ["",Some (CTAnonymous fields),None],p
 
+let is_java_native_function meta = try
+	match Meta.get Meta.Native meta with
+		| (Meta.Native,[],_) -> true
+		| _ -> false
+	with | Not_found -> false
+
 let build_module_def ctx mt meta fvars context_init fbuild =
 	let rec loop = function
 		| (Meta.Build,args,p) :: l ->
@@ -2391,7 +2397,7 @@ let init_class ctx c p context_init herits fields =
 					) in
 					let display_field = display_file && (f.cff_pos.pmin <= cp.pmin && f.cff_pos.pmax >= cp.pmax) in
 					match ctx.com.platform with
-						| Java when Meta.has Meta.Native cf.cf_meta ->
+						| Java when is_java_native_function cf.cf_meta ->
 							if fd.f_expr <> None then
 								ctx.com.warning "@:native function definitions shouldn't include an expression. This behaviour is deprecated." cf.cf_pos;
 							cf.cf_expr <- None;