Переглянути джерело

[java/cs] Types that have their haxe type changed by how type parameters are handled now are properly cast;
- namespaces are also escaped now
- more robust type parameter detection for anonymous functions
- toString calls redirect to C#'s ToString()

Caue Waneck 12 роки тому
батько
коміт
63ecd79c4a
4 змінених файлів з 90 додано та 53 видалено
  1. 74 39
      gencommon.ml
  2. 6 6
      gencs.ml
  3. 4 8
      genjava.ml
  4. 6 0
      std/cs/internal/Runtime.hx

+ 74 - 39
gencommon.ml

@@ -2817,7 +2817,7 @@ struct
       | _ -> run e)
 
   let rec get_type_params acc t =
-    match follow t with
+    match t with
       | TInst(( { cl_kind = KTypeParameter _ } as cl), []) ->
         if List.memq cl acc then acc else cl :: acc
       | TFun (params,tret) ->
@@ -2826,16 +2826,22 @@ struct
         (match t with | TDynamic _ -> acc | _ -> get_type_params acc t)
       | TAbstract ({ a_impl = Some _ } as a, pl) ->
           get_type_params acc ( Codegen.Abstract.get_underlying_type a pl)
-      | TAnon _
-      | TMono _
+      | TAnon a ->
+        PMap.fold (fun cf acc -> get_type_params acc cf.cf_type) a.a_fields acc
+      | TType(_, [])
       | TAbstract (_, [])
       | TInst(_, [])
-      | TEnum(_, []) -> acc
+      | TEnum(_, []) ->
+        acc
+      | TType(_, params)
       | TAbstract(_, params)
       | TEnum(_, params)
       | TInst(_, params) ->
         List.fold_left get_type_params acc params
-      | _ -> assert false
+      | TMono r -> (match !r with
+        | Some t -> get_type_params acc t
+        | None -> acc)
+      | _ -> get_type_params acc (follow_once t)
 
   let get_captured expr =
     let ret = Hashtbl.create 1 in
@@ -9944,6 +9950,7 @@ end;;
 
   dependencies:
     FixOverrides expects that the target platform is able to deal with overloaded functions
+    It must run after DefaultArguments, otherwise code added by the default arguments may be invalid
 
 *)
 
@@ -9952,7 +9959,7 @@ struct
 
   let name = "fix_overrides"
 
-  let priority = solve_deps name []
+  let priority = solve_deps name [DAfter DefaultArguments.priority]
 
   (*
     if the platform allows explicit interface implementation (C#),
@@ -10078,47 +10085,75 @@ struct
           List.iter loop_f iface.cl_ordered_fields
         in
         List.iter (fun (iface,itl) -> loop_iface iface itl) c.cl_implements;
-        (* now go through all overrides, and find those that are overloads and have actual_t <> t *)
+        (* now go through all overrides, *)
         let rec check_f f =
           (* find the first declared field *)
-          match find_first_declared_field gen c ~exact_field:f f.cf_name with
+          let is_overload = Meta.has Meta.Overload f.cf_meta in
+          let decl = if is_overload then
+            find_first_declared_field gen c ~exact_field:f f.cf_name
+          else
+            find_first_declared_field gen c f.cf_name
+          in
+          match decl with
           | Some(f2,actual_t,_,t,declared_cl,_,_)
             when not (Typeload.same_overload_args actual_t (get_real_fun gen f.cf_type) f2 f) ->
-              (* create another field with the requested type *)
-              let f3 = mk_class_field f.cf_name t f.cf_public f.cf_pos f.cf_kind f.cf_params in
-              let p = f.cf_pos in
-              let old_args, old_ret = get_fun f.cf_type in
-              let args, ret = get_fun t in
-              let tf_args = List.map (fun (n,o,t) -> alloc_var n t, None) args in
-              f3.cf_expr <- Some {
-                eexpr = TFunction({
-                  tf_args = tf_args;
-                  tf_type = ret;
-                  tf_expr = mk_block (mk_return (mk_cast ret {
-                    eexpr = TCall(
-                      {
-                        eexpr = TField(
-                          { eexpr = TConst TThis; etype = TInst(c, List.map snd c.cl_types); epos = p },
-                          FInstance(c,f));
-                        etype = f.cf_type;
-                        epos = p
-                      },
-                      List.map2 (fun (v,_) (_,_,t) -> mk_cast t (mk_local v p)) tf_args old_args);
-                    etype = old_ret;
-                    epos = p
-                  }))
+              if Meta.has Meta.Overload f.cf_meta then begin
+                (* if it is overload, create another field with the requested type *)
+                let f3 = mk_class_field f.cf_name t f.cf_public f.cf_pos f.cf_kind f.cf_params in
+                let p = f.cf_pos in
+                let old_args, old_ret = get_fun f.cf_type in
+                let args, ret = get_fun t in
+                let tf_args = List.map (fun (n,o,t) -> alloc_var n t, None) args in
+                f3.cf_expr <- Some {
+                  eexpr = TFunction({
+                    tf_args = tf_args;
+                    tf_type = ret;
+                    tf_expr = mk_block (mk_return (mk_cast ret {
+                      eexpr = TCall(
+                        {
+                          eexpr = TField(
+                            { eexpr = TConst TThis; etype = TInst(c, List.map snd c.cl_types); epos = p },
+                            FInstance(c,f));
+                          etype = f.cf_type;
+                          epos = p
+                        },
+                        List.map2 (fun (v,_) (_,_,t) -> mk_cast t (mk_local v p)) tf_args old_args);
+                      etype = old_ret;
+                      epos = p
+                    }))
+                  });
+                  etype = t;
+                  epos = p;
+                };
+                gen.gafter_filters_ended <- ((fun () ->
+                  f.cf_overloads <- f3 :: f.cf_overloads;
+                ) :: gen.gafter_filters_ended);
+                f3
+              end else begin match f.cf_expr with
+              | Some({ eexpr = TFunction(tf) } as e) ->
+                (* if it's not overload, just cast the vars *)
+                let actual_args, _ = get_fun (get_real_fun gen actual_t) in
+                let new_args, vardecl = List.fold_left2 (fun (args,vdecl) (v,_) (_,_,t) ->
+                  if not (type_iseq (gen.greal_type v.v_type) (gen.greal_type t)) then begin
+                    let new_var = mk_temp gen v.v_name t in
+                    (new_var,None) :: args, (v, Some(mk_cast v.v_type (mk_local new_var f.cf_pos))) :: vdecl
+                  end else
+                    (v,None) :: args, vdecl
+                ) ([],[]) tf.tf_args actual_args in
+                if vardecl <> [] then
+                f.cf_expr <- Some({ e with
+                  eexpr = TFunction({ tf with
+                    tf_args = List.rev new_args;
+                    tf_expr = Codegen.concat { eexpr = TVars(vardecl); etype = gen.gcon.basic.tvoid; epos = e.epos } tf.tf_expr
+                  });
                 });
-                etype = t;
-                epos = p;
-              };
-              gen.gafter_filters_ended <- ((fun () ->
-                f.cf_overloads <- f3 :: f.cf_overloads;
-              ) :: gen.gafter_filters_ended);
-              f3
+                f
+              | _ -> f
+              end
           | _ -> f
         in
         if not c.cl_extern then
-          c.cl_overrides <- List.map (fun f -> if Meta.has Meta.Overload f.cf_meta then check_f f else f) c.cl_overrides;
+          c.cl_overrides <- List.map (fun f -> check_f f) c.cl_overrides;
         md
       | _ -> md
     in

+ 6 - 6
gencs.ml

@@ -572,16 +572,16 @@ let configure gen =
 
   let no_root = Common.defined gen.gcon Define.NoRoot in
 
-  let change_ns md = if no_root then
-    function
-      | [] when is_hxgen md -> ["haxe";"root"]
-      | ns -> ns
-  else fun ns -> ns in
-
   let change_clname n = n in
 
   let change_id name = try Hashtbl.find reserved name with | Not_found -> name in
 
+  let change_ns md = if no_root then
+    function
+      | [] when is_hxgen md -> ["haxe";"root"]
+      | ns -> List.map change_id ns
+  else List.map change_id in
+
   let change_field = change_id in
 
   let write_id w name = write w (change_id name) in

+ 4 - 8
genjava.ml

@@ -736,18 +736,14 @@ let configure gen =
               ) params
   in
 
-  let rec change_ns ns = match ns with
-    | [] -> ["haxe"; "root"]
-    | _ -> ns
-  in
-
   let change_clname name =
     String.map (function | '$' -> '.' | c -> c) name
   in
-
-
   let change_id name = try Hashtbl.find reserved name with | Not_found -> name in
-
+  let rec change_ns ns = match ns with
+    | [] -> ["haxe"; "root"]
+    | _ -> List.map change_id ns
+  in
   let change_field = change_id in
 
   let write_id w name = write w (change_id name) in

+ 6 - 0
std/cs/internal/Runtime.hx

@@ -555,6 +555,12 @@ import cs.system.Type;
 	}
 
 	@:functionCode('
+		if (field == "toString")
+		{
+			if (args == null)
+				return obj.ToString();
+			field = "ToString";
+		}
 		if (args == null) args = new Array<object>();
 
 		System.Reflection.BindingFlags bf;