Bläddra i källkod

[java] Finished the Reflect and Std apis. Added Var Args function, and Native Method Function.

Caue Waneck 13 år sedan
förälder
incheckning
b5094dbeec

+ 60 - 0
gencommon.ml

@@ -6984,6 +6984,64 @@ struct
           | _ -> ()
     ) gen.gcon.types
     
+  let implement_varargs_cl ctx cl =
+    let pos = cl.cl_pos in
+    let gen = ctx.rcf_gen in
+    let basic = gen.gcon.basic in 
+    
+    let this_t = TInst(cl, List.map snd cl.cl_types) in
+    let this = { eexpr = TConst(TThis); etype = this_t ; epos = pos } in
+    let mk_this field t = { eexpr = TField(this, field); etype = t; epos = pos } in
+    
+    let invokedyn = gen.gmk_internal_name "hx" "invokeDynamic" in
+    let idyn_t = TFun([gen.gmk_internal_name "fn" "dynargs", false, basic.tarray t_dynamic], t_dynamic) in
+    let this_idyn = mk_this invokedyn idyn_t in
+    
+    let map_fn arity ret vars api =
+      
+      let rec loop i acc =
+        if i < 0 then 
+          acc
+        else
+          let obj = api i t_dynamic None in
+          loop (i - 1) (obj :: acc)
+      in
+      
+      let call_arg = if arity = (-1) then 
+        api (-1) t_dynamic None
+      else if arity = 0 then
+        null (basic.tarray t_empty) pos
+      else
+        { eexpr = TArrayDecl(loop (arity - 1) []); etype = basic.tarray t_empty; epos = pos }
+      in
+      
+      let expr = {
+        eexpr = TCall(
+          this_idyn, 
+          [ call_arg ]
+        );
+        etype = t_dynamic;
+        epos = pos
+      } in
+      
+      let expr = match follow ret with
+        | TInst({ cl_path = ([], "Float") }, []) -> mk_cast ret expr
+        | _ -> expr
+      in
+      
+      [], mk_return expr
+    in
+    
+    let all_cfs = List.filter (fun cf -> cf.cf_name <> "new" && cf.cf_name <> (invokedyn) && match cf.cf_kind with Method _ -> true | _ -> false) (ctx.rcf_ft.map_base_classfields cl true map_fn) in
+    
+    cl.cl_ordered_fields <- cl.cl_ordered_fields @ all_cfs;
+    List.iter (fun cf -> 
+      cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields
+    ) all_cfs;
+    
+    List.iter (fun cf ->
+      cl.cl_overrides <- cf.cf_name :: cl.cl_overrides
+    ) cl.cl_ordered_fields
   
   let implement_closure_cl ctx cl =
     let pos = cl.cl_pos in
@@ -7017,6 +7075,8 @@ struct
       
       let call_arg = if arity = (-1) then 
         api (-1) t_dynamic None
+      else if arity = 0 then
+        null (basic.tarray t_empty) pos
       else
         { eexpr = TArrayDecl(loop (arity - 1) []); etype = basic.tarray t_empty; epos = pos }
       in

+ 1 - 0
genjava.ml

@@ -1494,6 +1494,7 @@ let configure gen =
   
   let closure_func = ReflectionCFs.implement_closure_cl rcf_ctx ( get_cl (Hashtbl.find gen.gtypes (["haxe";"lang"],"Closure")) ) in
   
+  ReflectionCFs.implement_varargs_cl rcf_ctx ( get_cl (get_type gen (["haxe";"lang"], "VarArgsBase")) );
   
   ReflectionCFs.configure rcf_ctx;
   

+ 2 - 0
std/StringTools.hx

@@ -273,6 +273,8 @@ class StringTools {
 		return s.cca(index);
 		#elseif flash
 		return s["cca"](index);
+		#elseif java
+		return s.charCodeAt(index);
 		#else
 		return s.cca(index);
 		#end

+ 1 - 1
std/java/Boot.hx

@@ -21,7 +21,7 @@ import haxe.lang.FieldLookup;
  * @author waneck
  */
 
-class Boot 
+extern class Boot 
 {
 
 	

+ 2 - 1
std/java/Lib.hx

@@ -6,7 +6,8 @@ import java.lang.Class;
  * @author waneck
  */
 
-class Lib 
+//we cannot use the java package for custom classes, so we're redefining it as "haxe.java.Lib"
+@:native('haxe.java.Lib') class Lib 
 {
 
 	public static function toNativeReadOnlyArray<T>(arr:Array<T>, equalLengthRequired:Bool):NativeArray<T>

+ 24 - 8
std/java/_std/Reflect.hx

@@ -1,3 +1,5 @@
+import haxe.lang.Function;
+import java.Boot;
 /*
  * Copyright (c) 2005, The haXe Project Contributors
  * All rights reserved.
@@ -33,12 +35,10 @@
 		Tells if an object has a field set. This doesn't take into account the object prototype (class methods).
 	**/
 	@:functionBody('
-		//TODO make slow path
 		if (o instanceof haxe.lang.IHxObject)
 			return ((haxe.lang.IHxObject) o).__hx_getField(field, false, false, true) != haxe.lang.Runtime.undefined;
 		
-		return false;
-	
+		return haxe.lang.Runtime.slowHasField(o, field);
 	')
 	public static function hasField( o : Dynamic, field : String ) : Bool
 	{
@@ -49,12 +49,10 @@
 		Returns the field of an object, or null if [o] is not an object or doesn't have this field.
 	**/
 	@:functionBody('
-		//TODO make slow path
 		if (o instanceof haxe.lang.IHxObject)
 			return ((haxe.lang.IHxObject) o).__hx_getField(field, false, false, false);
 		
 		return haxe.lang.Runtime.slowGetField(o, field, false);
-	
 	')
 	public static function field( o : Dynamic, field : String ) : Dynamic
 	{
@@ -66,7 +64,6 @@
 		Set an object field value.
 	**/
 	@:functionBody('
-		//TODO make slow path
 		if (o instanceof haxe.lang.IHxObject)
 			((haxe.lang.IHxObject) o).__hx_setField(field, false, value);
 		
@@ -114,7 +111,26 @@
 			((haxe.lang.IHxObject) o).__hx_getFields(ret, false);
 			return ret;
 		} else {
-			return null;
+			Array<String> ret = new Array<String>();
+			
+			if (o instanceof java.lang.Class)
+			{
+				Class<?> cl = (java.lang.Class) o;
+				
+				for(java.lang.reflect.Field f : cl.getFields())
+				{
+					if (java.lang.reflect.Modifier.isStatic(f.getModifiers()))
+						ret.push(f.getName());
+				}
+				
+				for(java.lang.reflect.Method m : cl.getMethods())
+				{
+					if (java.lang.reflect.Modifier.isStatic(m.getModifiers()))
+						ret.push(m.getName());
+				}
+			}
+			
+			return ret;
 		}
 	')
 	public static function fields( o : Dynamic ) : Array<String>
@@ -207,7 +223,7 @@
 	**/
 	public static function makeVarArgs( f : Array<Dynamic> -> Dynamic ) : Dynamic
 	{
-		return null;
+		return new VarArgsFunction(f);
 	}
 	
 	

+ 1 - 1
std/java/_std/Std.hx

@@ -50,7 +50,7 @@ import haxe.lang.Exceptions;
 	}
 
 	public static inline function string( s : Dynamic ) : String {
-		return cast s;
+		return s + "";
 	}
 
 	public static inline function int( x : Float ) : Int {

+ 43 - 4
std/java/_std/haxe/lang/Function.hx

@@ -9,7 +9,10 @@ package haxe.lang;
  */
 @:abstract @:nativegen @:native("haxe.lang.Function") private class Function 
 {
-	
+	function new(arity:Int, type:Int)
+	{
+		
+	}
 }
 
 @:nativegen @:native("haxe.lang.Closure") private class Closure extends Function
@@ -17,8 +20,44 @@ package haxe.lang;
 	
 }
 
-/*
-@:nativegen @:native("haxe.lang.VarArgsFunction") private class VarArgsFunction extends Function
+@:nativegen @:native("haxe.lang.VarArgsBase") private class VarArgsBase extends Function
+{
+	public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	{
+		throw "Abstract implementation";
+	}
+}
+
+@:nativegen class VarArgsFunction extends VarArgsBase
+{
+	private var fun:Array<Dynamic>->Dynamic;
+	
+	public function new(fun)
+	{
+		super(-1, -1);
+		this.fun = fun;
+	}
+	
+	override public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic
+	{
+		return fun(dynArgs);
+	}
+}
+
+@:nativegen class NativeMethodFunction extends VarArgsBase
 {
+	private var obj:Dynamic;
+	private var field:String;
+	
+	public function new(obj, field)
+	{
+		super(-1, -1);
+		this.obj = obj;
+		this.field = field;
+	}
 	
-}*/
+	override public function __hx_invokeDynamic(dynArgs:Array<Dynamic>):Dynamic 
+	{
+		return untyped __java__("haxe.lang.Runtime.slowCallField(this.obj, this.field, dynArgs)");
+	}
+}

+ 51 - 4
std/java/_std/haxe/lang/Runtime.hx

@@ -134,6 +134,39 @@ package haxe.lang;
 		return false;
 	}
 	
+	@:functionBody('
+		java.lang.Class cl = null;
+		if (o instanceof java.lang.Class)
+		{
+			cl = (java.lang.Class) o;
+		} else {
+			cl = o.getClass();
+		}
+		
+		try
+		{
+			java.lang.reflect.Field f = cl.getField(field);
+			return true;
+		}
+		catch(Throwable t)
+		{
+			java.lang.reflect.Method[] ms = cl.getMethods();
+			for (int i = 0; i < ms.length; i++)
+			{
+				if (ms[i].getName().equals(field))
+				{
+					return true;
+				}
+			}
+		}
+
+		return false;
+	')
+	public static function slowHasField(o:Dynamic, field:String):Bool
+	{
+		return false;
+	}
+	
 	@:functionBody('
 			if (v1 == v2)
 				return 0;
@@ -193,9 +226,9 @@ package haxe.lang;
 		else
 			return null;
 	
+	java.lang.Class cl = null;
 	try
 	{
-		java.lang.Class cl = null;
 		if (obj instanceof java.lang.Class)
 		{
 			cl = (java.lang.Class) obj;
@@ -208,6 +241,21 @@ package haxe.lang;
 		return f.get(obj);
 	} catch (Throwable t)
 	{
+		try
+		{
+			java.lang.reflect.Method[] ms = cl.getMethods();
+			for (int i = 0; i < ms.length; i++)
+			{
+				if (ms[i].getName().equals(field))
+				{
+					return new haxe.lang.NativeMethodFunction(obj, field);
+				}
+			}
+		} catch (Throwable t2)
+		{
+			
+		}
+		
 		if (throwErrors)
 			throw HaxeException.wrap(t);
 		
@@ -249,8 +297,7 @@ package haxe.lang;
 	')
 	public static function slowSetField(obj:Dynamic, field:String, value:Dynamic):Dynamic
 	{
-		//not implemented yet;
-		throw "Not implemented";
+		return null;
 	}
 	
 	@:functionBody('
@@ -374,7 +421,7 @@ package haxe.lang;
 	')
 	public static function slowCallField(obj:Dynamic, field:String, args:Array<Dynamic>):Dynamic
 	{
-		throw "not implemented";
+		return null;
 	}
 	
 	@:functionBody('