Prechádzať zdrojové kódy

[java] re-enabled Java and C# targets. Java target passing unit tests again.
No more abstracts warnings ;)

Caue Waneck 13 rokov pred
rodič
commit
1e1e4fccab
10 zmenil súbory, kde vykonal 360 pridanie a 198 odobranie
  1. 4 4
      Makefile
  2. 179 92
      gencommon.ml
  3. 2 0
      gencs.ml
  4. 137 66
      genjava.ml
  5. 9 10
      main.ml
  6. 2 2
      std/haxe/io/Bytes.hx
  7. 18 18
      std/haxe/io/Input.hx
  8. 3 3
      std/java/StdTypes.hx
  9. 3 0
      std/java/_std/Math.hx
  10. 3 3
      tests/unit/compile.hxml

+ 4 - 4
Makefile

@@ -29,8 +29,8 @@ RELDIR=../../..
 EXPORT=../../../projects/motionTools/haxe
 
 MODULES=ast type lexer common genxml parser typecore optimizer typeload \
-	codegen genas3 gencpp genjs genneko genphp genswf8 \
-	genswf9 genswf interp typer matcher dce main
+	codegen gencommon genas3 gencpp genjs genneko genphp genswf8 \
+	genswf9 genswf genjava gencs interp typer matcher dce main
 
 HAXE_LIBRARY_PATH=$(CURDIR)/std
 
@@ -94,9 +94,9 @@ genxml.cmx: type.cmx lexer.cmx common.cmx ast.cmx
 
 interp.cmx: typecore.cmx type.cmx lexer.cmx genneko.cmx common.cmx codegen.cmx ast.cmx genswf.cmx parser.cmx
 
-main.cmx: dce.cmx matcher.cmx typer.cmx typeload.cmx typecore.cmx type.cmx parser.cmx optimizer.cmx lexer.cmx interp.cmx genxml.cmx genswf.cmx genphp.cmx genneko.cmx genjs.cmx gencpp.cmx genas3.cmx common.cmx codegen.cmx ast.cmx
-
 matcher.cmx: codegen.cmx typecore.cmx type.cmx typer.cmx common.cmx ast.cmx
+
+main.cmx: dce.cmx matcher.cmx typer.cmx typeload.cmx typecore.cmx type.cmx parser.cmx optimizer.cmx lexer.cmx interp.cmx genxml.cmx genswf.cmx genphp.cmx genneko.cmx genjs.cmx genjava.cmx gencs.cmx gencpp.cmx genas3.cmx common.cmx codegen.cmx ast.cmx
 
 optimizer.cmx: typecore.cmx type.cmx parser.cmx common.cmx ast.cmx
 

+ 179 - 92
gencommon.ml

@@ -57,11 +57,26 @@ let debug_type_ctor = function
   | TAnon _ -> "TAnon"
   | TDynamic _ -> "TDynamic"
   | TLazy _ -> "TLazy"
+  | TAbstract _ -> "TAbstract"
   
 let debug_type = (s_type (print_context()))
 
 let debug_expr = s_expr debug_type
 
+let rec like_float t =
+  match follow t with
+    | TAbstract({ a_path = ([], "Float") },[])
+    | TAbstract({ a_path = ([], "Int") },[]) -> true
+    | TAbstract(a, _) -> List.exists like_float a.a_super || List.exists like_float a.a_sub
+    | _ -> false
+
+let rec like_int t =
+  match follow t with
+    | TAbstract({ a_path = ([], "Int") },[]) -> true
+    | TAbstract(a, _) -> List.exists like_int a.a_super || List.exists like_float a.a_sub
+    | _ -> false
+
+
 let follow_once t =
   match t with
 	| TMono r ->
@@ -97,7 +112,7 @@ struct
   
   let mk_heetype = function
     | TMono _ -> 0 | TEnum _ -> 1 | TInst _ -> 2 | TType _ -> 3 | TFun _ -> 4
-    | TAnon _ -> 5 | TDynamic _ -> 6 | TLazy _ -> 7
+    | TAnon _ -> 5 | TDynamic _ -> 6 | TLazy _ -> 7 | TAbstract _ -> 8
   
   let mk_type e =
     {
@@ -180,9 +195,16 @@ let anon_of_enum e =
     a_status = ref (EnumStatics e)
   }
 
+let anon_of_abstract a =
+  TAnon {
+    a_fields = PMap.empty;
+    a_status = ref (AbstractStatics a)
+  }
+
 let anon_of_mt mt = match mt with
   | TClassDecl cl -> anon_of_classtype cl
   | TEnumDecl e -> anon_of_enum e
+  | TAbstractDecl a -> anon_of_abstract a
   | _ -> assert false
   
 let anon_class t =
@@ -191,6 +213,7 @@ let anon_class t =
         (match !(anon.a_status) with
           | Statics (cl) -> Some(TClassDecl(cl))
           | EnumStatics (e) -> Some(TEnumDecl(e))
+          | AbstractStatics (a) -> Some(TAbstractDecl(a))
           | _ -> None)
       | _ -> None
 
@@ -201,10 +224,12 @@ let path_s path =
   | TInst (cl,_) -> TClassDecl cl
   | TEnum (e,_) -> TEnumDecl e
   | TType (t,_) -> TTypeDecl t
+  | TAbstract (a,_) -> TAbstractDecl a
   | TAnon anon ->
     (match !(anon.a_status) with
       | EnumStatics e -> TEnumDecl e
       | Statics cl -> TClassDecl cl
+      | AbstractStatics a -> TAbstractDecl a
       | _ -> assert false)
   | TLazy f -> t_to_md (!f())
   | TMono r -> (match !r with | Some t -> t_to_md t | None -> assert false)
@@ -216,7 +241,11 @@ let get_tdef mt = match mt with | TTypeDecl t -> t | _ -> assert false
       
 let mk_mt_access mt pos = { eexpr = TTypeExpr(mt); etype = anon_of_mt mt; epos = pos }
 
-let is_void t = match follow t with | TEnum({ e_path = ([], "Void") }, []) -> true | _ -> false
+let is_void t = match follow t with 
+  | TEnum({ e_path = ([], "Void") }, [])
+  | TAbstract ({ a_path = ([], "Void") },[]) -> 
+      true 
+  | _ -> false
 
 let mk_local var pos = { eexpr = TLocal(var); etype = var.v_type; epos = pos }
 
@@ -576,8 +605,6 @@ and gen_classes =
 {
   cl_reflect : tclass;
   cl_type : tclass;
-  cl_class : tclass;
-  cl_enum : tclass;
   cl_dyn : tclass;
   
   t_iterator : tdef;
@@ -588,8 +615,6 @@ and gen_tools =
 {
   (* (klass : texpr, t : t) : texpr *)
   mutable r_create_empty : texpr->t->texpr;
-  (* (expr : texpr) -> texpr *)
-  mutable r_get_class : texpr->texpr;
   (* Reflect.fields(). The bool is if we are iterating in a read-only manner. If it is read-only we might not need to allocate a new array *)
   mutable r_fields : bool->texpr->texpr;
   (* (first argument = return type. should be void in most cases) Reflect.setField(obj, field, val) *)
@@ -610,6 +635,7 @@ let get_type types path =
     | TClassDecl cl when cl.cl_path = path -> true
     | TEnumDecl e when e.e_path = path -> true
     | TTypeDecl t when t.t_path = path -> true
+    | TAbstractDecl a when a.a_path = path -> true
     | _ -> false
   ) types
 
@@ -620,16 +646,22 @@ let new_ctx con =
       | TClassDecl cl -> Hashtbl.add types cl.cl_path mt
       | TEnumDecl e -> Hashtbl.add types e.e_path mt
       | TTypeDecl t -> Hashtbl.add types t.t_path mt
+      | TAbstractDecl a -> Hashtbl.add types a.a_path mt
   ) con.types;
+
+  let cl_dyn = match get_type con.types ([], "Dynamic") with
+    | TClassDecl c -> c
+    | TAbstractDecl a ->
+        mk_class a.a_module ([], "Dynamic") a.a_pos
+    | _ -> assert false
+  in
   
   let rec gen = {
     gcon = con;
     gclasses = {
       cl_reflect = get_cl (get_type con.types ([], "Reflect"));
       cl_type = get_cl (get_type con.types ([], "Type"));
-      cl_class = get_cl (get_type con.types ([], "Class"));
-      cl_enum = get_cl (get_type con.types ([], "Enum"));
-      cl_dyn = get_cl (get_type con.types ([], "Dynamic"));
+      cl_dyn = cl_dyn; 
       
       t_iterator = get_tdef (get_type con.types ([], "Iterator"));
     };
@@ -638,11 +670,6 @@ let new_ctx con =
         let fieldcall = mk_static_field_access_infer gen.gclasses.cl_type "createEmptyInstance" eclass.epos [t] in
         { eexpr = TCall(fieldcall, [eclass]); etype = t; epos = eclass.epos }
       );
-      r_get_class = (fun expr ->
-        let fieldcall = mk_static_field_access_infer gen.gclasses.cl_type "getClass" expr.epos [expr.etype] in
-        let t = TInst(gen.gclasses.cl_class, [expr.etype]) in
-        { eexpr = TCall(fieldcall, [expr]); etype = t; epos = expr.epos }
-      );
       r_fields = (fun is_used_only_by_iteration expr ->
         let fieldcall = mk_static_field_access_infer gen.gclasses.cl_reflect "fields" expr.epos [] in
         { eexpr = TCall(fieldcall, [expr]); etype = gen.gcon.basic.tarray gen.gcon.basic.tstring; epos = expr.epos }
@@ -660,7 +687,7 @@ let new_ctx con =
       );
       
       rf_create_empty = (fun cl p pos -> 
-        gen.gtools.r_create_empty { eexpr = TTypeExpr(TClassDecl cl); epos = pos; etype = TInst(gen.gclasses.cl_class,[TInst(cl,List.map (fun _ -> t_dynamic) p)]) } (TInst(cl,p))
+        gen.gtools.r_create_empty { eexpr = TTypeExpr(TClassDecl cl); epos = pos; etype = t_dynamic } (TInst(cl,p))
       ); (* TODO: Maybe implement using normal reflection? Type.createEmpty(MyClass) *)
     };
     gmk_internal_name = (fun ns s -> sprintf "__%s_%s" ns s);
@@ -701,15 +728,7 @@ let new_ctx con =
     greal_type = (fun t -> t);
     greal_type_param = (fun _ t -> t);
     
-    (*gis_value_type = (fun t -> match follow t with
-      | TInst({ cl_path = ([],"Int") },[]) 
-      | TInst({ cl_path = "Float" },[]) 
-      | TInst({ cl_path = "Bool" },[]) -> true
-      | TInst(cl,[]) when has_meta ":struct" cl.cl_meta -> true
-      | TEnum(e,[]) when has_meta ":struct" e.e_meta -> true
-      | _ -> false);*)
-	
-    gallow_tp_dynamic_conversion = false;
+   gallow_tp_dynamic_conversion = false;
     
     guse_tp_constraints = false;
     
@@ -796,6 +815,7 @@ let run_filters_from gen t filters =
           c.cl_init <- Some (List.fold_left (fun e f -> f e) e filters));
       | TEnumDecl _ -> ()
       | TTypeDecl _ -> ()
+      | TAbstractDecl _ -> ()
 
 let run_filters gen =
   (* first of all, we have to make sure that the filters won't trigger a major Gc collection *)
@@ -827,7 +847,7 @@ let run_filters gen =
                   match t with
                     | TClassDecl cl -> cl.cl_path <- new_p
                     | TEnumDecl e -> e.e_path <- new_p
-                    | TTypeDecl t -> ()
+                    | TTypeDecl _ | TAbstractDecl _ -> ()
               in
               loop 0
             end;
@@ -947,7 +967,7 @@ let dump_descriptor gen name path_s =
           SourceWriter.write w "E ";
           SourceWriter.write w (path_s e.e_path);
           SourceWriter.newline w
-        | _ -> () (* still no typedef is generated *)
+        | _ -> () (* still no typedef or abstract is generated *)
     ) md_def.m_types
   ) gen.gcon.modules;
   SourceWriter.write w "end modules";
@@ -1045,11 +1065,13 @@ let reset_temps () = tmp_count := 0
   
 let follow_module follow_func md = match md with
   | TClassDecl _
-  | TEnumDecl _ -> md
+  | TEnumDecl _
+  | TAbstractDecl _ -> md
   | TTypeDecl tdecl -> match (follow_func (TType(tdecl, List.map snd tdecl.t_types))) with
     | TInst(cl,_) -> TClassDecl cl
     | TEnum(e,_) -> TEnumDecl e
     | TType(t,_) -> TTypeDecl t
+    | TAbstract(a,_) -> TAbstractDecl a
     | _ -> assert false
  
 (* 
@@ -1063,24 +1085,35 @@ let rec is_hxgen md =
     | TClassDecl cl -> has_meta ":hxgen" cl.cl_meta
     | TEnumDecl e -> has_meta ":hxgen" e.e_meta
     | TTypeDecl t -> has_meta ":hxgen" t.t_meta || ( match follow t.t_type with | TInst(cl,_) -> is_hxgen (TClassDecl cl) | TEnum(e,_) -> is_hxgen (TEnumDecl e) | _ -> false )
+    | TAbstractDecl a -> has_meta ":hxgen" a.a_meta
 
 let is_hxgen_t t =
   match t with
     | TInst (cl, _) -> has_meta ":hxgen" cl.cl_meta
     | TEnum (e, _) -> has_meta ":hxgen" e.e_meta
+    | TAbstract (a, _) -> has_meta ":hxgen" a.a_meta
     | TType (t, _) -> has_meta ":hxgen" t.t_meta
     | _ -> false
 
+let mt_to_t_dyn md =
+  match md with
+    | TClassDecl cl -> TInst(cl, List.map (fun _ -> t_dynamic) cl.cl_types)
+    | TEnumDecl e -> TEnum(e, List.map (fun _ -> t_dynamic) e.e_types)
+    | TAbstractDecl a -> TAbstract(a, List.map (fun _ -> t_dynamic) a.a_types)
+    | TTypeDecl t -> TType(t, List.map (fun _ -> t_dynamic) t.t_types)
+
 let mt_to_t mt params =
   match mt with
     | TClassDecl (cl) -> TInst(cl, params)
     | TEnumDecl (e) -> TEnum(e, params)
+    | TAbstractDecl a -> TAbstract(a, params)
     | _ -> assert false
 
 let t_to_mt t =
   match follow t with
     | TInst(cl, _) -> TClassDecl(cl)
     | TEnum(e, _) -> TEnumDecl(e)
+    | TAbstract(a, _) -> TAbstractDecl a
     | _ -> assert false
 
 let mk_paren e =
@@ -1207,7 +1240,7 @@ let field_access gen (t:t) (field:string) : (tfield_access) =
         in
         loop_find_cf hierarchy
       )
-    | TEnum(e, params) ->
+    | TEnum _ | TAbstract _ ->
       (* enums have no field *) FNotFound
     | TAnon anon ->
       (try match !(anon.a_status) with
@@ -1322,6 +1355,7 @@ struct
         
         is_hxgen_class cl
       | TEnumDecl e -> if e.e_extern then has_meta ":hxgen" e.e_meta else not (has_meta ":nativegen" e.e_meta)
+      | TAbstractDecl a -> not (has_meta ":nativegen" a.a_meta)
       | TTypeDecl t -> (* TODO see when would we use this *)
         false
   
@@ -1336,6 +1370,7 @@ struct
           | TClassDecl cl -> cl.cl_meta <- (":hxgen", [], cl.cl_pos) :: cl.cl_meta
           | TEnumDecl e -> e.e_meta <- (":hxgen", [], e.e_pos) :: e.e_meta
           | TTypeDecl t -> t.t_meta <- (":hxgen", [], t.t_pos) :: t.t_meta
+          | TAbstractDecl a -> a.a_meta <- (":hxgen", [], a.a_pos) :: a.a_meta
       end
     in
     List.iter filter gen.gcon.types
@@ -1983,9 +2018,10 @@ struct
   
   
     let get_etype_one e =
-      match follow e.etype with
-        | TInst({cl_path = ([],"Int")},[]) -> (gen.gcon.basic.tint, { eexpr = TConst(TInt(Int32.one)); etype = gen.gcon.basic.tint; epos = e.epos })
-        | _ -> (gen.gcon.basic.tfloat, { eexpr = TConst(TFloat("1.0")); etype = gen.gcon.basic.tfloat; epos = e.epos })
+      if like_int e.etype then
+        (gen.gcon.basic.tint, { eexpr = TConst(TInt(Int32.one)); etype = gen.gcon.basic.tint; epos = e.epos })
+      else
+        (gen.gcon.basic.tfloat, { eexpr = TConst(TFloat("1.0")); etype = gen.gcon.basic.tfloat; epos = e.epos })
     in
     
     let basic = gen.gcon.basic in
@@ -2343,7 +2379,7 @@ struct
             
             let actual_t = match op with 
               | Ast.Increment | Ast.Decrement -> (match follow earray.etype with
-                | TInst _ | TEnum _ -> earray.etype
+                | TInst _ | TAbstract _ | TEnum _ -> earray.etype
                 | _ -> basic.tfloat) 
               | Ast.Not -> basic.tbool 
               | _ -> basic.tint 
@@ -2662,8 +2698,10 @@ struct
       | TDynamic _
       | TAnon _
       | TMono _
+      | TAbstract(_, [])
       | TInst(_, [])
       | TEnum(_, []) -> acc
+      | TAbstract(_, params)
       | TEnum(_, params)
       | TInst(_, params) -> 
         List.fold_left get_type_params acc params
@@ -2938,11 +2976,11 @@ struct
       
       in
       
-      let rettype_real_to_func t = match follow t with
-        | TInst({ cl_path = ([], "Float") },[])
-        | TInst({ cl_path = ([], "Int") },[]) -> 
+      let rettype_real_to_func t = 
+        if like_float t then
           (1, basic.tfloat)
-        | _ -> (0, t_dynamic)
+        else
+          (0, t_dynamic)
       in
       
       let args_real_to_func_call el (pos:Ast.pos) = 
@@ -2950,12 +2988,10 @@ struct
           [{ eexpr = TArrayDecl el; etype = basic.tarray t_dynamic; epos = pos }]
         else begin
           let acc1,acc2 = List.fold_left (fun (acc_f,acc_d) e ->
-            match follow (gen.greal_type e.etype) with (* seeing if it's a basic type *)
-              | TInst({ cl_path = ([], "Int") },[])
-              | TInst({ cl_path = ([], "Float") },[]) -> 
-                ( e :: acc_f, undefined e.epos :: acc_d )
-              | _ ->
-                (null basic.tfloat e.epos :: acc_f, e :: acc_d)
+                                            if like_float (gen.greal_type e.etype) then 
+                                              ( e :: acc_f, undefined e.epos :: acc_d )
+                                            else
+                                              ( null basic.tfloat e.epos :: acc_f, e :: acc_d )
           ) ([],[]) (List.rev el) in
           acc1 @ acc2
         end
@@ -3102,10 +3138,11 @@ struct
           | TCall(tc, params) -> (tc, params)
           | _ -> assert false
         in
-          let postfix, ret_t = match follow (gen.greal_type call_expr.etype) with
-            | TInst({ cl_path = ([], "Float") },[])
-            | TInst({ cl_path = ([], "Int") },[]) -> "_f", gen.gcon.basic.tfloat
-            | _ -> "_o", t_dynamic
+          let postfix, ret_t = 
+            if like_float (gen.greal_type call_expr.etype) then
+                "_f", gen.gcon.basic.tfloat
+            else
+              "_o", t_dynamic
           in
           let params_len = List.length params in
           let ret_t = if params_len >= max_arity then t_dynamic else ret_t in
@@ -3122,7 +3159,8 @@ struct
           in
           
           let may_cast = match follow call_expr.etype with
-            | TEnum({ e_path = ([], "Void")}, []) -> fun e -> e
+            | TEnum({ e_path = ([], "Void")}, [])
+            | TAbstract ({ a_path = ([], "Void") },[]) -> (fun e -> e)
             | _ -> mk_cast call_expr.etype
           in
           
@@ -3175,10 +3213,10 @@ struct
             let vf, _ = List.nth args i in
             let vo, _ = List.nth args (i + arity) in
             
-            let needs_cast, is_float = match t, follow t with
-              | TInst({ cl_path = ([], "Float") }, []), _ -> false, true
-              | _, TInst({ cl_path = ([], "Int") }, [])
-              | _, TInst({ cl_path = ([], "Float") }, []) -> true,true
+            let needs_cast, is_float = match t, like_float t with
+              | TInst({ cl_path = ([], "Float") }, []), _
+              | TAbstract({ a_path = ([], "Float") },[]), _ -> false, true
+              | _, true -> true, true
               | _ -> false,false
             in
             
@@ -3433,7 +3471,7 @@ struct
         in
         (* let rec loop goes here *)
         let map_fn cur_arity fun_ret_type vars (api:(int->t->tconstant option->texpr)) =
-          let is_float = match follow fun_ret_type with | TInst({ cl_path = ([], "Float") },[]) -> true | _ -> false in
+          let is_float = like_float fun_ret_type in
           match cur_arity with
             | -1 ->
               let dynargs = api (-1) (t_dynamic) None in
@@ -3576,6 +3614,20 @@ struct
               Hashtbl.replace params_tbl cl.cl_path applied
           )
           
+        | TAbstract(a, params), TAbstract(a2, params2) ->
+          if a == a2 then
+            List.iter2 (get_arg) params params2
+          else begin
+            List.iter (fun t ->
+              let t = apply_params a2.a_types params2 t in
+              get_arg original t
+            ) a2.a_super;
+            List.iter (fun t ->
+              let t = apply_params a.a_types params t in
+              get_arg t applied
+            ) a.a_sub
+          end
+
         | TInst(cl, params), TInst(cl2, params2) ->
           let rec loop cl2 params2 =
             if cl == cl2 then begin
@@ -3595,6 +3647,17 @@ struct
           in
           ignore (loop cl2 params2)
           
+        | TAbstract(a, params), _ ->
+          List.iter (fun t ->
+            let t = apply_params a.a_types params t in
+            get_arg t applied
+          ) a.a_sub
+        | _, TAbstract(a2, params2) ->
+          List.iter (fun t ->
+            let t = apply_params a2.a_types params2 t in
+            get_arg original t
+          ) a2.a_super
+
         | TEnum(e, params), TEnum(e2, params2) ->
           List.iter2 (get_arg) params params2
         | TFun(params, ret), TFun(params2, ret2) ->
@@ -3685,7 +3748,8 @@ struct
     let rec has_type_params t =
       match follow t with
         | TInst( { cl_kind = KTypeParameter _ }, _) -> true
-        | TEnum (_, params)
+        | TAbstract(_, params)
+        | TEnum(_, params)
         | TInst(_, params) -> List.fold_left (fun acc t -> acc || has_type_params t) false params
         | _ -> false
     
@@ -3696,6 +3760,8 @@ struct
         not (has_meta ":$nativegeneric" e.e_meta)
       | TTypeDecl(t) ->
         not (has_meta ":$nativegeneric" t.t_meta)
+      | TAbstractDecl a ->
+        not (has_meta ":$nativegeneric" a.a_meta)
     
     let rec set_hxgeneric gen mds isfirst md = 
       let path = t_path md in
@@ -3755,7 +3821,7 @@ struct
                                 if not (Hashtbl.mem gen.gtparam_cast cl.cl_path) then true else loop cfs
                               | TEnum(e,p) when has_type_params t && is_false (set_hxgeneric gen mds isfirst (TEnumDecl e)) ->
                                 if not (Hashtbl.mem gen.gtparam_cast e.e_path) then true else loop cfs
-                              | _ -> loop cfs
+                              | _ -> loop cfs (* TAbstracts / Dynamics can't be generic *)
                       in
                       if loop cl.cl_ordered_fields then begin
                         cl.cl_meta <- (":$nativegeneric", [], cl.cl_pos) :: cl.cl_meta;
@@ -3915,6 +3981,7 @@ struct
           match follow t with
             | TInst(cl,_) -> cl.cl_path
             | TEnum(e,_) -> e.e_path
+            | TAbstract(a,_) -> a.a_path
             | TMono _
             | TDynamic _ -> ([], "Dynamic")
             | _ -> assert false
@@ -3939,7 +4006,7 @@ struct
         
         let thandle = alloc_var "__typeof__" t_dynamic in
         let mk_typehandle cl =
-          { eexpr = TCall(mk_local thandle pos, [ mk_classtype_access cl pos ]); etype = TInst(gen.gclasses.cl_class, [t_dynamic]); epos = pos }
+          { eexpr = TCall(mk_local thandle pos, [ mk_classtype_access cl pos ]); etype = t_dynamic; epos = pos }
         in
         
         let mk_eq cl1 cl2 =
@@ -4042,7 +4109,7 @@ struct
               
               add_iface iface;
               md
-            | TTypeDecl _ -> md
+            | TTypeDecl _ | TAbstractDecl _ -> md
             | TEnumDecl _ -> 
               ignore (set_hxgeneric gen md);
               md
@@ -4153,7 +4220,12 @@ struct
           i := 0;
           Hashtbl.clear found_types;
           List.iter iter_types (hd :: tl)
-        
+       
+        | TAbstractDecl { a_types = hd :: tl } ->
+          i := 0;
+          Hashtbl.clear found_types;
+          List.iter iter_types (hd :: tl)
+
         | _ -> ()
           
       ) gen.gcon.types
@@ -4239,6 +4311,9 @@ struct
     | TEnum (e1,tl1) , TEnum (e2,tl2) ->
       if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then Type.error [cannot_unify a b];
       List.iter2 (type_eq gen param) tl1 tl2
+    | TAbstract (a1,tl1) , TAbstract (a2,tl2) ->
+      if a1 != a2 && not (param = EqCoreType && a1.a_path = a2.a_path) then Type.error [cannot_unify a b];
+      List.iter2 (type_eq gen param) tl1 tl2
     | TInst (c1,tl1) , TInst (c2,tl2) ->
       if c1 != c2 && not (param = EqCoreType && c1.cl_path = c2.cl_path) && (match c1.cl_kind, c2.cl_kind with KExpr _, KExpr _ -> false | _ -> true) then Type.error [cannot_unify a b];
       List.iter2 (type_eq gen param) tl1 tl2
@@ -4329,6 +4404,17 @@ struct
         (* anonymous are never unsafe also. *)
         (* Though they will generate a cast, so if this cast is unneeded it's better to avoid them by tweaking gen.greal_type *)
         false
+      | TAbstract _, _
+      | _, TAbstract _ ->
+        (try
+          unify from_t to_t;
+          false
+        with | Unify_error _ -> 
+          try
+            unify to_t from_t; (* still not unsafe *)
+            false
+          with | Unify_error _ ->
+            true)
       | _ -> true
   
   let do_unsafe_cast gen from_t to_t e  =
@@ -4337,6 +4423,7 @@ struct
         | TInst(cl, _) -> cl.cl_path
         | TEnum(e, _) -> e.e_path
         | TType(t, _) -> t.t_path
+        | TAbstract(a, _) -> a.a_path
         | TDynamic _ -> ([], "Dynamic")
         | _ -> raise Not_found
     in
@@ -4411,7 +4498,8 @@ struct
               true
             end else 
               (*
-                if not, we're going to check if we only need a simple cast, or if we need to first cast into the dynamic version of it
+                if not, we're going to check if we only need a simple cast, 
+                or if we need to first cast into the dynamic version of it
               *)
               try
                 List.iter2 (type_eq gen EqRightDynamic) tl params_to;
@@ -4441,6 +4529,19 @@ struct
       | TDynamic _, _ -> e
       | _, TMono _
       | _, TDynamic _ -> mk_cast to_t e
+      | TAbstract (a_to, _), TAbstract(a_from, _) when a_to == a_from ->
+        e
+      | TAbstract _, _
+      | _, TAbstract _ ->
+        (try
+          unify from_t to_t;
+          mk_cast to_t e
+        with | Unify_error _ ->
+          try
+            unify to_t from_t;
+            mk_cast to_t e
+          with | Unify_error _ ->
+            do_unsafe_cast())
       | TEnum(e_to, []), TEnum(e_from, []) ->
         if e_to == e_from then
           e
@@ -5175,7 +5276,8 @@ struct
   
   let add_assign gen add_statement expr =
     match follow expr.etype with
-      | TEnum({ e_path = ([],"Void") },[]) ->
+      | TEnum({ e_path = ([],"Void") },[])
+      | TAbstract ({ a_path = ([],"Void") },[]) ->
         add_statement expr;
         null expr.etype expr.epos
       | _ ->
@@ -5208,7 +5310,8 @@ struct
         apply_assign assign_fun p
       | _ -> 
         match follow right.etype with
-          | TEnum( { e_path = ([], "Void") }, [] ) ->
+          | TEnum( { e_path = ([], "Void") }, [] )
+          | TAbstract ({ a_path = ([], "Void") },[]) ->
             right
           | _ -> trace (debug_expr right); assert false (* a statement is required *)
   
@@ -6181,11 +6284,10 @@ struct
             | TInst ( { cl_path = ["haxe"], "Int64" }, [] ) ->
               loop tl ((name, gen.ghandle_cast t_dynamic real_t expr) :: acc) acc_f
             | _ ->
-              match follow real_t with
-                | TInst( { cl_path = [], "Float" }, [] )
-                | TInst( { cl_path = [], "Int" }, [] ) ->
-                  loop tl acc ((name, gen.ghandle_cast basic.tfloat real_t expr) :: acc_f)
-                | _ -> loop tl ((name, gen.ghandle_cast t_dynamic real_t expr) :: acc) acc_f
+              if like_float real_t then
+                loop tl acc ((name, gen.ghandle_cast basic.tfloat real_t expr) :: acc_f)
+              else
+                loop tl ((name, gen.ghandle_cast t_dynamic real_t expr) :: acc) acc_f
     in
     
     let may_hash_field s =
@@ -6527,13 +6629,6 @@ struct
       let fun_type = ref (TFun([], basic.tvoid)) in
       let fun_name = ctx.rcf_gen.gmk_internal_name "hx" ( (if is_set then "setField" else "getField") ^ (if is_float then "_f" else "") ) in
       
-      (*let maybe_cast e = if is_float then match ctx.rcf_gen.greal_type (ctx.rcf_gen.gfollow#run_f e.etype) with
-          | TInst({ cl_path = ([],"Float") }, []) -> e
-          | TInst({ cl_kind = KTypeParameter }, _) ->
-            mk_cast basic.tfloat (mk_cast t_dynamic e)
-          | _ -> mk_cast basic.tfloat e
-        else e
-      in*) (* the cast module will run after this transformation, so there's no problem here *)
       let maybe_cast e = e in
       
       let t = TInst(cl, List.map snd cl.cl_types) in
@@ -6673,9 +6768,8 @@ struct
           List.filter (fun (_,cf) -> (* TODO: maybe really apply_params in cf.cf_type. The benefits would be limited, though *)
             match follow (ctx.rcf_gen.greal_type (ctx.rcf_gen.gfollow#run_f cf.cf_type)) with
               | TDynamic _ | TMono _
-              | TInst ({ cl_kind = KTypeParameter _ }, _)
-              | TInst ({ cl_path = ([], "Float") }, [])
-              | TInst ({ cl_path = ([], "Int") }, []) -> true
+              | TInst ({ cl_kind = KTypeParameter _ }, _) -> true
+              | t when like_float t -> true
               | _ -> false
           ) ret 
         else
@@ -7029,7 +7123,7 @@ struct
       let field = gen.gmk_internal_name "hx" field in
       let t = TFun(fun_args tf_args, ret) in
       let cf = mk_class_field field t false pos (Method MethNormal) [] in
-      let is_void = match follow ret with | TEnum({ e_path = ([], "Void") },[]) -> true | _ -> false in
+      let is_void = is_void ret in
       let may_return e = if is_void then mk_block e else mk_block (mk_return e) in
       let i = ref 0 in
       cf.cf_expr <- Some({
@@ -7219,7 +7313,8 @@ struct
       (* as Array<Dynamic> *)
       let args, ret = get_args t in
       let ret = match follow ret with
-        | TEnum({ e_path = ([], "Void") }, []) -> ret
+        | TEnum({ e_path = ([], "Void") }, [])
+        | TAbstract ({ a_path = ([], "Void") },[]) -> ret
         | _ -> t_dynamic
       in
       mk_this_call_raw cf.cf_name (TFun(args, ret)) params
@@ -7391,11 +7486,8 @@ struct
         etype = t_dynamic;
         epos = pos
       } in
-      
-      let expr = match follow ret with
-        | TInst({ cl_path = ([], "Float") }, []) -> mk_cast ret expr
-        | _ -> expr
-      in
+     
+      let expr = if like_float ret && not (like_int ret) then mk_cast ret expr else expr in
       
       [], mk_return expr
     in
@@ -7467,10 +7559,7 @@ struct
         epos = pos
       } in
       
-      let expr = match follow ret with
-        | TInst({ cl_path = ([], "Float") }, []) -> mk_cast ret expr
-        | _ -> expr
-      in
+      let expr = if like_float ret && not (like_int ret) then mk_cast ret expr else expr in
       
       [], mk_return expr
     in
@@ -7581,7 +7670,7 @@ struct
           let fn_args, ret = get_fun (follow cf.cf_type) in
           
           let tf_args = List.map (fun (name,_,t) -> alloc_var name t, None) fn_args in
-          let is_void = match follow ret with | TEnum({ e_path = ([], "Void") },[]) -> true | _ -> false in
+          let is_void = is_void ret in
           let expr = {
             eexpr = TCall({
               eexpr = TField( (if static then mk_classtype_access cl pos else this), cf.cf_name);
@@ -9226,10 +9315,8 @@ struct
   let name = "int_division_synf"
   
   let priority = solve_deps name [ DAfter ExpressionUnwrap.priority; DAfter ObjectDeclMap.priority; DAfter ArrayDeclSynf.priority ]
-  
-  let is_int t = match follow t with 
-    | TInst( { cl_path = ([], "Int") }, [] ) -> true
-    | _ -> false
+ 
+  let is_int = like_int
   
   let default_implementation gen catch_int_div =
     let basic = gen.gcon.basic in
@@ -9396,4 +9483,4 @@ struct
     gen.gsyntax_filters#add ~name:name ~priority:(PCustom priority) map
   
 end;;
-*)
+*)

+ 2 - 0
gencs.ml

@@ -760,6 +760,8 @@ let configure gen =
         t_s (TEnum(e,[]))
       | TTypeDecl t ->
         t_s (TType(t, List.map (fun t -> t_dynamic) t.t_types))
+      | TAbstractDecl a ->
+        t_s (TAbstract(a, List.map(fun t -> t_dynamic) a.a_types))
   in
 
   let rec ensure_local e explain =

+ 137 - 66
genjava.ml

@@ -64,15 +64,16 @@ let is_java_basic_type t =
   match follow t with
     | TInst( { cl_path = (["haxe"], "Int32") }, [] )
     | TInst( { cl_path = (["haxe"], "Int64") }, [] )
-    | TInst( { cl_path = ([], "Int") }, [] )
-    | TInst( { cl_path = ([], "Float") }, [] )
-    | TEnum( { e_path = ([], "Bool") }, [] ) ->
+    | TInst( { cl_path = ([], "Int") }, [] ) | TAbstract( { a_path =  ([], "Int") }, [] )
+    | TInst( { cl_path = ([], "Float") }, [] ) | TAbstract( { a_path =  ([], "Float") }, [] )
+    | TEnum( { e_path = ([], "Bool") }, [] ) | TAbstract( { a_path =  ([], "Bool") }, [] ) ->
       true
     | _ -> false
 
 let is_bool t =
   match follow t with
-    | TEnum( { e_path = ([], "Bool") }, [] ) ->
+    | TEnum( { e_path = ([], "Bool") }, [] )
+    | TAbstract ({ a_path = ([], "Bool") },[]) ->
       true
     | _ -> false
 
@@ -80,9 +81,10 @@ let is_int_float gen t =
   match follow (gen.greal_type t) with
     | TInst( { cl_path = (["haxe"], "Int64") }, [] )
     | TInst( { cl_path = (["haxe"], "Int32") }, [] )
-    | TInst( { cl_path = ([], "Int") }, [] )
-    | TInst( { cl_path = ([], "Float") }, [] ) ->
+    | TInst( { cl_path = ([], "Int") }, [] ) | TAbstract( { a_path =  ([], "Int") }, [] )
+    | TInst( { cl_path = ([], "Float") }, [] ) | TAbstract( { a_path =  ([], "Float") }, [] ) ->
       true
+    | (TAbstract _ as t) when like_float t -> true
     | _ -> false
 
 let parse_explicit_iface =
@@ -148,6 +150,10 @@ struct
           mk_static_field_access_infer float_cl "POSITIVE_INFINITY" e.epos []
         | TField( { eexpr = TTypeExpr( TClassDecl( { cl_path = (["java";"lang"], "Math") }) ) }, "isNaN" ) ->
           mk_static_field_access_infer float_cl "isNaN" e.epos []
+        | TCall( ({ eexpr = TField( ({ eexpr = TTypeExpr( TClassDecl( { cl_path = (["java";"lang"], "Math") }) ) } as ef), ("ffloor" as f) ) } as fe), p)
+        | TCall( ({ eexpr = TField( ({ eexpr = TTypeExpr( TClassDecl( { cl_path = (["java";"lang"], "Math") }) ) } as ef), ("fround" as f) ) } as fe), p)
+        | TCall( ({ eexpr = TField( ({ eexpr = TTypeExpr( TClassDecl( { cl_path = (["java";"lang"], "Math") }) ) } as ef), ("fceil" as f) ) } as fe), p) ->
+            Type.map_expr run { e with eexpr = TCall({ fe with eexpr = TField(ef, String.sub f 1 (String.length f - 1))  }, p) }
         | TCall( { eexpr = TField( { eexpr = TTypeExpr( TClassDecl( { cl_path = (["java";"lang"], "Math") }) ) }, "floor" ) }, _)
         | TCall( { eexpr = TField( { eexpr = TTypeExpr( TClassDecl( { cl_path = (["java";"lang"], "Math") }) ) }, "round" ) }, _)
         | TCall( { eexpr = TField( { eexpr = TTypeExpr( TClassDecl( { cl_path = (["java";"lang"], "Math") }) ) }, "ceil" ) }, _) ->
@@ -172,7 +178,8 @@ struct
             ] ) }
           in
           (match follow_module follow md with
-            | TClassDecl({ cl_path = ([], "Float") }) ->
+            | TClassDecl({ cl_path = ([], "Float") })
+            | TAbstractDecl({ a_path = ([], "Float") }) ->
               {
                 eexpr = TCall(
                   mk_static_field_access_infer runtime_cl "isDouble" e.epos [],
@@ -181,7 +188,8 @@ struct
                 etype = basic.tbool;
                 epos = e.epos
               }
-            | TClassDecl{ cl_path = ([], "Int") } ->
+            | TClassDecl{ cl_path = ([], "Int") }
+            | TAbstractDecl{ a_path = ([], "Int") } ->
               {
                 eexpr = TCall(
                   mk_static_field_access_infer runtime_cl "isInt" e.epos [],
@@ -190,8 +198,10 @@ struct
                 etype = basic.tbool;
                 epos = e.epos
               }
+            | TAbstractDecl{ a_path = ([], "Bool") }
             | TEnumDecl{ e_path = ([], "Bool") } ->
               mk_is obj bool_md
+            | TAbstractDecl{ a_path = ([], "Dynamic") }
             | TClassDecl{ cl_path = ([], "Dynamic") } ->
               (match obj.eexpr with
                 | TLocal _ | TConst _ -> { e with eexpr = TConst(TBool true) }
@@ -484,10 +494,10 @@ struct
 
   let traverse gen runtime_cl =
     let basic = gen.gcon.basic in
-    let tchar = match ( get_type gen (["java"], "Char16") ) with | TTypeDecl t -> TType(t,[]) | _ -> assert false in
-    let tbyte = match ( get_type gen (["java"], "Int8") ) with | TTypeDecl t -> TType(t,[]) | _ -> assert false in
-    let tshort = match ( get_type gen (["java"], "Int16") ) with | TTypeDecl t -> TType(t,[]) | _ -> assert false in
-    let tsingle = match ( get_type gen ([], "Single") ) with | TTypeDecl t -> TType(t,[]) | _ -> assert false 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
@@ -541,10 +551,7 @@ struct
             | _ -> true
           in
 
-          let fun_name = match follow e.etype with
-            | TInst ({ cl_path = ([], "Float") },[]) -> "toDouble"
-            | _ -> "toInt"
-          in
+          let fun_name = if like_int e.etype then "toInt" else "toDouble" in
 
           let ret = {
             eexpr = TCall(
@@ -658,15 +665,23 @@ let configure gen =
                 let f_t = gen.gfollow#run_f t in
                 match gen.gfollow#run_f t with
                   | TEnum ({ e_path = ([], "Bool") }, [])
+                  | TAbstract ({ a_path = ([], "Bool") },[]) 
                   | TInst ({ cl_path = ([],"Float") },[])
+                  | TAbstract ({ a_path = ([],"Float") },[]) 
                   | TInst ({ cl_path = ["haxe"],"Int32" },[])
+                  | TInst ({ cl_path = ["haxe"],"Int64" },[])
                   | TInst ({ cl_path = ([],"Int") },[])
+                  | TAbstract ({ a_path = ([],"Int") },[]) 
                   | TType ({ t_path = ["haxe";"_Int64"], "NativeInt64" },[])
-                  | TType ({ t_path = ["haxe"],"Int64" },[])
+                  | TAbstract ({ a_path = ["haxe";"_Int64"], "NativeInt64" },[]) 
                   | TType ({ t_path = ["java"],"Int8" },[])
+                  | TAbstract ({ a_path = ["java"],"Int8" },[]) 
                   | TType ({ t_path = ["java"],"Int16" },[])
+                  | TAbstract ({ a_path = ["java"],"Int16" },[]) 
                   | TType ({ t_path = ["java"],"Char16" },[])
-                  | TType ({ t_path = [],"Single" },[]) -> basic.tnull f_t
+                  | TAbstract ({ a_path = ["java"],"Char16" },[]) 
+                  | TType ({ t_path = [],"Single" },[])
+                  | TAbstract ({ a_path = [],"Single" },[]) -> basic.tnull f_t
                   (*| TType ({ t_path = [], "Null"*)
                   | TInst (cl, ((_ :: _) as p)) ->
                     TInst(cl, List.map (fun _ -> t_dynamic) p)
@@ -693,18 +708,27 @@ let configure gen =
 
   gen.gfollow#add ~name:"follow_basic" (fun t -> match t with
       | TEnum ({ e_path = ([], "Bool") }, [])
+      | TAbstract ({ a_path = ([], "Bool") },[]) 
       | TEnum ({ e_path = ([], "Void") }, [])
+      | TAbstract ({ a_path = ([], "Void") },[]) 
       | TInst ({ cl_path = ([],"Float") },[])
+      | TAbstract ({ a_path = ([],"Float") },[]) 
       | TInst ({ cl_path = ([],"Int") },[])
+      | TAbstract ({ a_path = ([],"Int") },[]) 
       | TInst( { cl_path = (["haxe"], "Int32") }, [] )
       | TInst( { cl_path = (["haxe"], "Int64") }, [] )
       | TType ({ t_path = ["haxe";"_Int64"], "NativeInt64" },[])
+      | TAbstract ({ a_path = ["haxe";"_Int64"], "NativeInt64" },[]) 
       | TType ({ t_path = ["java"],"Int8" },[])
+      | TAbstract ({ a_path = ["java"],"Int8" },[]) 
       | TType ({ t_path = ["java"],"Int16" },[])
+      | TAbstract ({ a_path = ["java"],"Int16" },[]) 
       | TType ({ t_path = ["java"],"Char16" },[])
+      | TAbstract ({ a_path = ["java"],"Char16" },[]) 
       | TType ({ t_path = [],"Single" },[])
+      | TAbstract ({ a_path = [],"Single" },[]) 
       | TType ({ t_path = [],"Null" },[_]) -> Some t
-	  | TAbstract( { a_path = ([], "EnumValue") }, _  ) -> Some t_dynamic
+	    | TAbstract( { a_path = ([], "EnumValue") }, _ ) 
       | TInst( { cl_path = ([], "EnumValue") }, _  ) -> Some t_dynamic
       | _ -> None);
 
@@ -722,7 +746,7 @@ let configure gen =
       | TInst( { cl_path = (["haxe"], "Int32") }, [] ) -> gen.gcon.basic.tint
       | TInst( { cl_path = (["haxe"], "Int64") }, [] ) -> ti64
       | TAbstract( { a_path = ([], "Class") }, p  )
-      | TAbstract( { a_path = ([], "Enum") }, p  ) -> TInst(cl_cl,[t_dynamic])
+      | TAbstract( { a_path = ([], "Enum") }, p  )
       | TInst( { cl_path = ([], "Class") }, p  )
       | TInst( { cl_path = ([], "Enum") }, p  ) -> TInst(cl_cl,[t_dynamic])
       | TEnum _
@@ -733,8 +757,8 @@ let configure gen =
           | TInst( { cl_kind = KTypeParameter _ }, []) -> t_dynamic
           | _ -> real_type t
         )
-      | TType _ -> t
-      | TAnon (anon) when (match !(anon.a_status) with | Statics _ | EnumStatics _ -> true | _ -> false) -> t
+      | TType _ | TAbstract _ -> t
+      | TAnon (anon) when (match !(anon.a_status) with | Statics _ | EnumStatics _ | AbstractStatics _ -> true | _ -> false) -> t
       | TAnon _ -> dynamic_anon
       | TFun _ -> TInst(fn_cl,[])
       | _ -> t_dynamic
@@ -753,18 +777,28 @@ let configure gen =
   let rec t_s t =
     match real_type t with
       (* basic types *)
-      | TEnum ({ e_path = ([], "Bool") }, []) -> "boolean"
-      | TEnum ({ e_path = ([], "Void") }, []) -> "java.lang.Object"
-      | TInst ({ cl_path = ([],"Float") },[]) -> "double"
-      | TInst ({ cl_path = ([],"Int") },[]) -> "int"
-      | TType ({ t_path = ["haxe";"_Int64"], "NativeInt64" },[]) -> "long"
-      | TType ({ t_path = ["java"],"Int8" },[]) -> "byte"
-      | TType ({ t_path = ["java"],"Int16" },[]) -> "short"
-      | TType ({ t_path = ["java"],"Char16" },[]) -> "char"
-      | TType ({ t_path = [],"Single" },[]) -> "float"
-      | TInst ({ cl_path = ["haxe"],"Int32" },[]) -> "int"
-      | TInst ({ cl_path = ["haxe"],"Int64" },[]) -> "long"
-      | TInst ({ cl_path = ([], "Dynamic") }, _) -> "java.lang.Object"
+      | TEnum ({ e_path = ([], "Bool") }, [])
+      | TAbstract ({ a_path = ([], "Bool") },[]) -> "boolean"
+      | TEnum ({ e_path = ([], "Void") }, [])
+      | TAbstract ({ a_path = ([], "Void") },[]) -> "java.lang.Object"
+      | TInst ({ cl_path = ([],"Float") },[])
+      | TAbstract ({ a_path = ([],"Float") },[]) -> "double"
+      | TInst ({ cl_path = ([],"Int") },[])
+      | TAbstract ({ a_path = ([],"Int") },[]) -> "int"
+      | TType ({ t_path = ["haxe";"_Int64"], "NativeInt64" },[])
+      | TAbstract ({ a_path = ["haxe";"_Int64"], "NativeInt64" },[]) -> "long"
+      | TType ({ t_path = ["java"],"Int8" },[])
+      | TAbstract ({ a_path = ["java"],"Int8" },[]) -> "byte"
+      | TType ({ t_path = ["java"],"Int16" },[])
+      | TAbstract ({ a_path = ["java"],"Int16" },[]) -> "short"
+      | TType ({ t_path = ["java"],"Char16" },[])
+      | TAbstract ({ a_path = ["java"],"Char16" },[]) -> "char"
+      | TType ({ t_path = [],"Single" },[])
+      | TAbstract ({ a_path = [],"Single" },[]) -> "float"
+      | TInst ({ cl_path = ["haxe"],"Int32" },[])
+      | TAbstract ({ a_path = ["haxe"],"Int32" },[]) -> "int"
+      | TInst ({ cl_path = ["haxe"],"Int64" },[])
+      | TAbstract ({ a_path = ["haxe"],"Int64" },[]) -> "long"
       | TInst({ cl_path = (["java"], "NativeArray") }, [param]) ->
         let rec check_t_s t =
           match real_type t with
@@ -775,16 +809,17 @@ let configure gen =
         (check_t_s param) ^ "[]"
       (* end of basic types *)
       | TInst ({ cl_kind = KTypeParameter _; cl_path=p }, []) -> snd p
+      | TAbstract ({ a_path = [], "Dynamic" },[]) -> "java.lang.Object"
       | TMono r -> (match !r with | None -> "java.lang.Object" | Some t -> t_s (run_follow gen t))
       | TInst ({ cl_path = [], "String" }, []) -> "java.lang.String"
-	  | TAbstract ({ a_path = [], "Class" }, _) | TAbstract ({ a_path = [], "Enum" }, _) -> assert false (* should have been converted earlier *)
+	    | TAbstract ({ a_path = [], "Class" }, _) | TAbstract ({ a_path = [], "Enum" }, _)
       | TInst ({ cl_path = [], "Class" }, _) | TInst ({ cl_path = [], "Enum" }, _) -> assert false (* should have been converted earlier *)
       | TEnum (({e_path = p;} as e), params) -> (path_param_s (TEnumDecl e) p params)
       | TInst (({cl_path = p;} as cl), params) -> (path_param_s (TClassDecl cl) p params)
       | TType (({t_path = p;} as t), params) -> (path_param_s (TTypeDecl t) p params)
       | TAnon (anon) ->
         (match !(anon.a_status) with
-          | Statics _ | EnumStatics _ -> "java.lang.Class"
+          | Statics _ | EnumStatics _ | AbstractStatics _ -> "java.lang.Class"
           | _ -> "java.lang.Object")
       | TDynamic _ -> "java.lang.Object"
       (* No Lazy type nor Function type made. That's because function types will be at this point be converted into other types *)
@@ -792,16 +827,26 @@ let configure gen =
 
   and param_t_s t =
     match run_follow gen t with
-      | TEnum ({ e_path = ([], "Bool") }, []) -> "java.lang.Boolean"
-      | TInst ({ cl_path = ([],"Float") },[]) -> "java.lang.Double"
-      | TInst ({ cl_path = ([],"Int") },[]) -> "java.lang.Integer"
-      | TType ({ t_path = ["haxe";"_Int64"], "NativeInt64" },[]) -> "java.lang.Long"
-      | TInst ({ cl_path = ["haxe"],"Int64" },[]) -> "java.lang.Long"
-      | TInst ({ cl_path = ["haxe"],"Int32" },[]) -> "java.lang.Integer"
-      | TType ({ t_path = ["java"],"Int8" },[]) -> "java.lang.Byte"
-      | TType ({ t_path = ["java"],"Int16" },[]) -> "java.lang.Short"
-      | TType ({ t_path = ["java"],"Char16" },[]) -> "java.lang.Character"
-      | TType ({ t_path = [],"Single" },[]) -> "java.lang.Float"
+      | TEnum ({ e_path = ([], "Bool") }, [])
+      | TAbstract ({ a_path = ([], "Bool") },[]) -> "java.lang.Boolean"
+      | TInst ({ cl_path = ([],"Float") },[])
+      | TAbstract ({ a_path = ([],"Float") },[]) -> "java.lang.Double"
+      | TInst ({ cl_path = ([],"Int") },[])
+      | TAbstract ({ a_path = ([],"Int") },[]) -> "java.lang.Integer"
+      | TType ({ t_path = ["haxe";"_Int64"], "NativeInt64" },[])
+      | TAbstract ({ a_path = ["haxe";"_Int64"], "NativeInt64" },[]) -> "java.lang.Long"
+      | TInst ({ cl_path = ["haxe"],"Int64" },[])
+      | TAbstract ({ a_path = ["haxe"],"Int64" },[]) -> "java.lang.Long"
+      | TInst ({ cl_path = ["haxe"],"Int32" },[])
+      | TAbstract ({ a_path = ["haxe"],"Int32" },[]) -> "java.lang.Integer"
+      | TType ({ t_path = ["java"],"Int8" },[])
+      | TAbstract ({ a_path = ["java"],"Int8" },[]) -> "java.lang.Byte"
+      | TType ({ t_path = ["java"],"Int16" },[])
+      | TAbstract ({ a_path = ["java"],"Int16" },[]) -> "java.lang.Short"
+      | TType ({ t_path = ["java"],"Char16" },[])
+      | TAbstract ({ a_path = ["java"],"Char16" },[]) -> "java.lang.Character"
+      | TType ({ t_path = [],"Single" },[])
+      | TAbstract ({ a_path = [],"Single" },[]) -> "java.lang.Float"
       | TDynamic _ -> "?"
       | TInst (cl, params) -> t_s (TInst(cl, change_param_type (TClassDecl cl) params))
       | TType (cl, params) -> t_s (TType(cl, change_param_type (TTypeDecl cl) params))
@@ -817,7 +862,8 @@ let configure gen =
 
   let rett_s t =
     match t with
-      | TEnum ({e_path = ([], "Void")}, []) -> "void"
+      | TEnum ({e_path = ([], "Void")}, [])
+      | TAbstract ({ a_path = ([], "Void") },[]) -> "void"
       | _ -> t_s t
   in
 
@@ -865,6 +911,8 @@ let configure gen =
         t_s (TEnum(e,[]))
       | TTypeDecl t ->
         t_s (TType(t, []))
+      | TAbstractDecl a ->
+        t_s (TAbstract(a, []))
   in
 
   (*
@@ -909,9 +957,16 @@ let configure gen =
                 | TType( { t_path = (["haxe";"_Int64"], "NativeInt64") }, [] )
                 | TInst( { cl_path = (["haxe"], "Int64") }, [] ) -> write w "0L"
                 | TInst( { cl_path = (["haxe"], "Int32") }, [] )
-                | TInst({ cl_path = ([], "Int") },[]) -> expr_s w ({ e with eexpr = TConst(TInt Int32.zero) })
-                | TInst({ cl_path = ([], "Float") },[]) -> expr_s w ({ e with eexpr = TConst(TFloat "0.0") })
-                | TEnum({ e_path = ([], "Bool") }, []) -> write w "false"
+                | TInst({ cl_path = ([], "Int") },[])
+                | TAbstract ({ a_path = ([], "Int") },[]) -> expr_s w ({ e with eexpr = TConst(TInt Int32.zero) })
+                | TInst({ cl_path = ([], "Float") },[])
+                | TAbstract ({ a_path = ([], "Float") },[]) -> expr_s w ({ e with eexpr = TConst(TFloat "0.0") })
+                | TEnum({ e_path = ([], "Bool") }, [])
+                | TAbstract ({ a_path = ([], "Bool") },[]) -> write w "false"
+                | TAbstract _ when like_int e.etype ->
+                  expr_s w { e with eexpr = TConst(TInt Int32.zero) }
+                | TAbstract _ when like_float e.etype ->
+                  expr_s w { e with eexpr = TConst(TFloat "0.0") }
                 | _ -> write w "null")
             | TThis -> write w "this"
             | TSuper -> write w "super")
@@ -954,7 +1009,7 @@ let configure gen =
         | TArrayDecl el ->
           print w "new %s" (param_t_s (transform_nativearray_t e.etype));
           let is_double = match follow e.etype with
-           | TInst(_,[ t ]) -> ( match follow t with | TInst({ cl_path=([],"Float") },[]) -> Some t | _ -> None )
+           | TInst(_,[ t ]) -> if like_float t && not (like_int t) then Some t else None
            | _ -> None
           in
 
@@ -1250,7 +1305,9 @@ let configure gen =
               | TFun([_,_,t], ret) ->
                 (match (real_type t, real_type ret) with
                   | TDynamic _, TEnum( { e_path = ([], "Bool") }, [])
-                  | TAnon _, TEnum( { e_path = ([], "Bool") }, []) -> true
+                  | TDynamic _, TAbstract ({ a_path = ([], "Bool") },[]) 
+                  | TAnon _, TEnum( { e_path = ([], "Bool") }, [])
+                  | TAnon _, TAbstract ({ a_path = ([], "Bool") },[]) -> true
                   | _ -> List.mem cf.cf_name cl.cl_overrides
                 )
               | _ -> List.mem cf.cf_name cl.cl_overrides)
@@ -1267,7 +1324,8 @@ let configure gen =
             (match cf.cf_type with
               | TFun([], ret) ->
                 (match real_type ret with
-                  | TInst( { cl_path = ([], "Int") }, []) ->
+                  | TInst( { cl_path = ([], "Int") }, [])
+                  | TAbstract ({ a_path = ([], "Int") },[]) ->
                     true
                   | _ -> gen.gcon.error "A hashCode() function should return an Int!" cf.cf_pos; false
                 )
@@ -1283,7 +1341,11 @@ let configure gen =
         let cf_type = if is_override then match field_access gen (TInst(cl, List.map snd cl.cl_types)) cf.cf_name with | FClassField(_,_,_,_,actual_t) -> actual_t | _ -> assert false else cf.cf_type in
 
         let params = List.map snd cl.cl_types in
-        let ret_type, args = match cf_type, cf.cf_type with | TFun (strbtl, t), TFun(rargs, _) -> (apply_params cl.cl_types params (real_type t), List.map2 (fun(_,_,t) (n,o,_) -> (n,o,apply_params cl.cl_types params (real_type t))) strbtl rargs) | _ -> assert false in
+        let ret_type, args = match follow cf_type, follow cf.cf_type with 
+          | TFun (strbtl, t), TFun(rargs, _) -> 
+              (apply_params cl.cl_types params (real_type t), List.map2 (fun(_,_,t) (n,o,_) -> (n,o,apply_params cl.cl_types params (real_type t))) strbtl rargs) 
+          | _ -> assert false
+        in
 
         (if is_override && not is_interface then write w "@Override ");
         (* public static void funcName *)
@@ -1460,6 +1522,8 @@ let configure gen =
         (not e.e_extern)
       | TTypeDecl e ->
         false
+      | TAbstractDecl a ->
+        false
   in
 
   let module_gen w md =
@@ -1514,12 +1578,7 @@ let configure gen =
   let rcf_static_find = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "findHash" Ast.null_pos [] in
   (*let rcf_static_lookup = mk_static_field_access_infer (get_cl (get_type gen (["haxe";"lang"], "FieldLookup"))) "lookupHash" Ast.null_pos [] in*)
 
-  let can_be_float t = match follow (real_type t) with
-    | TInst({ cl_path = (["haxe"], "Int32")}, [] )
-    | TInst({ cl_path = ([], "Int") }, [])
-    | TInst({ cl_path = ([], "Float") }, []) -> true
-    | _ -> false
-  in
+  let can_be_float t = like_float (real_type t) in
 
   let rcf_on_getset_field main_expr field_expr field may_hash may_set is_unsafe =
     let is_float = can_be_float (if is_none may_set then main_expr.etype else (get may_set).etype) in
@@ -1633,16 +1692,19 @@ let configure gen =
       (match follow t with
         | TInst({ cl_path = ([], "String") }, [])
         | TInst({ cl_path = ([], "Float") }, [])
+        | TAbstract ({ a_path = ([], "Float") },[]) 
         | TInst({ cl_path = (["haxe"], "Int32")}, [] )
         | TInst({ cl_path = (["haxe"], "Int64")}, [] )
         | TInst({ cl_path = ([], "Int") }, [])
-        | TEnum({ e_path = ([], "Bool") }, []) -> Some t
+        | TAbstract ({ a_path = ([], "Int") },[]) 
+        | TEnum({ e_path = ([], "Bool") }, [])
+        | TAbstract ({ a_path = ([], "Bool") },[]) -> Some t
         | _ -> None )
     | _ -> None
   in
-
-  let is_double t = match follow t with | TInst({ cl_path = ([], "Float") }, []) -> true | _ -> false in
-  let is_int t = match follow t with | TInst({ cl_path = ([], "Int") }, []) -> true | _ -> false in
+  
+  let is_double t = like_float t && not (like_int t) in
+  let is_int t = like_int t in
 
   DynamicOperators.configure gen
     (DynamicOperators.abstract_implementation gen (fun e -> match e.eexpr with
@@ -1670,15 +1732,21 @@ let configure gen =
           | TDynamic _, _
           | _, TDynamic _
           | TInst({ cl_path = ([], "Float") },[]), _
+          | TAbstract ({ a_path = ([], "Float") },[]) , _
           | TInst( { cl_path = (["haxe"], "Int32") }, [] ), _
           | TInst( { cl_path = (["haxe"], "Int64") }, [] ), _
           | TInst({ cl_path = ([], "Int") },[]), _
+          | TAbstract ({ a_path = ([], "Int") },[]) , _
           | TEnum({ e_path = ([], "Bool") },[]), _
+          | TAbstract ({ a_path = ([], "Bool") },[]) , _
           | _, TInst({ cl_path = ([], "Float") },[])
+          | _, TAbstract ({ a_path = ([], "Float") },[]) 
           | _, TInst({ cl_path = ([], "Int") },[])
+          | _, TAbstract ({ a_path = ([], "Int") },[]) 
           | _, TInst( { cl_path = (["haxe"], "Int32") }, [] )
           | _, TInst( { cl_path = (["haxe"], "Int64") }, [] )
           | _, TEnum({ e_path = ([], "Bool") },[])
+          | _, TAbstract ({ a_path = ([], "Bool") },[]) 
           | TInst( { cl_kind = KTypeParameter _ }, [] ), _
           | _, TInst( { cl_kind = KTypeParameter _ }, [] ) -> false
           | _, _ -> true
@@ -1770,6 +1838,7 @@ let configure gen =
         (match gen.gfollow#run_f cond.etype with
           | TInst( { cl_path = (["haxe"], "Int32") }, [] )
           | TInst({ cl_path = ([], "Int") },[])
+          | TAbstract ({ a_path = ([], "Int") },[]) 
           | TInst({ cl_path = ([], "String") },[]) ->
             (List.exists (fun (c,_) ->
               List.exists (fun expr -> match expr.eexpr with | TConst _ -> false | _ -> true ) c
@@ -1833,6 +1902,8 @@ let configure gen =
 
   TypeParams.RenameTypeParameters.run gen;
 
+  Codegen.dump_types gen.gcon;
+
   let t = Common.timer "code generation" in
 
 	generate_modules_t gen "java" "src" change_path module_gen;
@@ -1952,7 +2023,7 @@ let convert_java_enum p pe =
   let data = ref [] in
   List.iter (fun f ->
     if List.mem JEnum f.jf_flags then
-      data := (f.jf_name, None, [], [], p) :: !data
+      data := { ec_name = f.jf_name; ec_doc = None; ec_meta = []; ec_args = []; ec_pos = p; ec_params = []; ec_type = None; } :: !data;
   ) pe.cfields;
 
   EEnum {
@@ -2149,4 +2220,4 @@ let add_java_lib com file =
 
   (* TODO: add_dependency m mdep *)
   com.load_extern_type <- com.load_extern_type @ [build];
-  com.java_libs <- (file, close) :: com.java_libs
+  com.java_libs <- (file, close) :: com.java_libs

+ 9 - 10
main.ml

@@ -783,12 +783,12 @@ try
 		("-cpp",Arg.String (fun dir ->
 			set_platform Cpp dir;
 		),"<directory> : generate C++ code into target directory");
-(* 		("-cs",Arg.String (fun dir ->
+ 		("-cs",Arg.String (fun dir ->
 			set_platform Cs dir;
 		),"<directory> : generate C# code into target directory");
 		("-java",Arg.String (fun dir ->
 			set_platform Java dir;
-		),"<directory> : generate Java code into target directory"); *)
+		),"<directory> : generate Java code into target directory");
 		("-xml",Arg.String (fun file ->
 			Parser.use_doc := true;
 			xml_out := Some file
@@ -837,8 +837,7 @@ try
 			Genswf.add_swf_lib com file
 		),"<file> : add the SWF library to the compiled SWF");
 		("-java-lib",Arg.String (fun file ->
-			()
-			(* Genjava.add_java_lib com file *)
+			Genjava.add_java_lib com file 
 		),"<file> : add an external JAR or class directory library");
 		("-x", Arg.String (fun file ->
 			let neko_file = file ^ ".n" in
@@ -1051,10 +1050,10 @@ try
 			add_std "cpp";
 			"cpp"
 		| Cs ->
-			(* Gencs.before_generate com; *)
+			Gencs.before_generate com;
 			add_std "cs"; "cs"
 		| Java ->
-			(* Genjava.before_generate com; *)
+			Genjava.before_generate com;
 			add_std "java"; "java"
 	) in
 	(* if we are at the last compilation step, allow all packages accesses - in case of macros or opening another project file *)
@@ -1154,11 +1153,11 @@ try
 			Common.log com ("Generating Cpp in : " ^ com.file);
 			Gencpp.generate com;
 		| Cs ->
-			if com.verbose then print_endline ("Generating C# in : " ^ com.file);
-			(* Gencs.generate com; *)
+      Common.log com ("Generating Cs in : " ^ com.file);
+			Gencs.generate com;
 		| Java ->
-			if com.verbose then print_endline ("Generating Java in : " ^ com.file);
-			(* Genjava.generate com; *)
+      Common.log com ("Generating Cs in : " ^ com.file);
+			Genjava.generate com; 
 		);
 	end;
 	Sys.catch_break false;

+ 2 - 2
std/haxe/io/Bytes.hx

@@ -57,9 +57,9 @@ class Bytes {
 		#elseif cpp
 		untyped b[pos] = v;
 		#elseif java
-		b[pos] = v;
+		b[pos] = cast v;
 		#elseif cs
-		b[pos] = v;
+		b[pos] = cast v;
 		#else
 		b[pos] = v & 0xFF;
 		#end

+ 18 - 18
std/haxe/io/Input.hx

@@ -56,7 +56,7 @@ class Input {
 			#elseif cpp
 				b[pos] = untyped readByte();
 			#else
-				b[pos] = readByte();
+				b[pos] = cast readByte();
 			#end
 			pos++;
 			k--;
@@ -172,18 +172,18 @@ class Input {
 			var helper = helper;
 			helper.order(bigEndian ? java.nio.ByteOrder.BIG_ENDIAN : java.nio.ByteOrder.LITTLE_ENDIAN);
 
-			helper.put(0, readByte());
-			helper.put(1, readByte());
-			helper.put(2, readByte());
-			helper.put(3, readByte());
+			helper.put(0, cast readByte());
+			helper.put(1, cast readByte());
+			helper.put(2, cast readByte());
+			helper.put(3, cast readByte());
 
 			return helper.getFloat(0);
 		#else
 			var bytes = [];
-			bytes.push(readByte());
-			bytes.push(readByte());
-			bytes.push(readByte());
-			bytes.push(readByte());
+			bytes.push(cast readByte());
+			bytes.push(cast readByte());
+			bytes.push(cast readByte());
+			bytes.push(cast readByte());
 			if (bigEndian)
 				bytes.reverse();
 			var sign = 1 - ((bytes[0] >> 7) << 1);
@@ -253,14 +253,14 @@ class Input {
 		var helper = helper;
 		helper.order(bigEndian ? java.nio.ByteOrder.BIG_ENDIAN : java.nio.ByteOrder.LITTLE_ENDIAN);
 
-		helper.put(0, readByte());
-		helper.put(1, readByte());
-		helper.put(2, readByte());
-		helper.put(3, readByte());
-		helper.put(4, readByte());
-		helper.put(5, readByte());
-		helper.put(6, readByte());
-		helper.put(7, readByte());
+		helper.put(0, cast readByte());
+		helper.put(1, cast readByte());
+		helper.put(2, cast readByte());
+		helper.put(3, cast readByte());
+		helper.put(4, cast readByte());
+		helper.put(5, cast readByte());
+		helper.put(6, cast readByte());
+		helper.put(7, cast readByte());
 
 		return helper.getDouble(0);
 		#else
@@ -392,4 +392,4 @@ class Input {
     }
 #end
 
-}
+}

+ 3 - 3
std/java/StdTypes.hx

@@ -26,6 +26,6 @@ package java;
  * @author waneck
  */
 
-typedef Int8 = Int;
-typedef Int16 = Int;
-typedef Char16 = Int;
+@:notNull @:runtimeValue abstract Int8 <= Int {}
+@:notNull @:runtimeValue abstract Int16 <= Int {}
+@:notNull @:runtimeValue abstract Char16 <= Int {}

+ 3 - 0
std/java/_std/Math.hx

@@ -44,6 +44,9 @@
 	static function floor(v:Float):Int;
 	static function ceil(v:Float):Int;
 	static function atan(v:Float):Float;
+	static function fround(v:Float):Float;
+	static function ffloor(v:Float):Float;
+	static function fceil(v:Float):Float;
 	static function asin(v:Float):Float;
 	static function acos(v:Float):Float;
 	static function pow(v:Float,exp:Float):Float;

+ 3 - 3
tests/unit/compile.hxml

@@ -71,9 +71,9 @@ unit.Test
 -D NO_PRECOMPILED_HEADERS
 
 #java
-#--next
-#-main unit.Test
-#-java java
+--next
+-main unit.Test
+-java java
 
 #cs
 #--next