Browse Source

[cs] generic implementation-related fixes:
- Type.createInstance() with generic classes that weren't looked up by name now works correctly
- __cast field now is typed correctly on deeply nested generic types

Caue Waneck 12 years ago
parent
commit
c46f309577
4 changed files with 67 additions and 47 deletions
  1. 50 45
      gencommon.ml
  2. 4 2
      gencs.ml
  3. 12 0
      std/cs/_std/Type.hx
  4. 1 0
      std/cs/internal/Runtime.hx

+ 50 - 45
gencommon.ml

@@ -3975,37 +3975,40 @@ struct
           if (level <> 0 || cls.cl_interface) && tls <> [] && is_hxgeneric (TClassDecl cls) then begin
             let cparams = List.map (fun (s,t) -> (s, TInst (map_param (get_cl_t t), []))) cls.cl_types in
             let name = String.concat "_" ((fst cls.cl_path) @ [snd cls.cl_path; cast_field_name]) in
-            let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in
-            let field = { eexpr = TField(this, FInstance(cl,cast_cfield)); etype = apply_params cast_cfield.cf_params reverse_params cast_cfield.cf_type; epos = p } in
-            let call =
-            {
-              eexpr = TCall(field, []);
-              etype = t_dynamic;
-              epos = p;
-            } in
-            let call = gen.gparam_func_call call field reverse_params [] in
-            let delay () =
-              cfield.cf_expr <-
-              Some {
-                eexpr = TFunction(
-                {
-                  tf_args = [];
-                  tf_type = t_dynamic;
-                  tf_expr =
-                  {
-                    eexpr = TReturn( Some call );
-                    etype = t_dynamic;
-                    epos = p;
-                  }
-                });
-                etype = cfield.cf_type;
+            if not (PMap.mem name cl.cl_fields) then begin
+              let reverse_params = List.map (apply_params cls.cl_types (List.map snd cparams)) reverse_params in
+              let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in
+              let field = { eexpr = TField(this, FInstance(cl,cast_cfield)); etype = apply_params cast_cfield.cf_params reverse_params cast_cfield.cf_type; epos = p } in
+              let call =
+              {
+                eexpr = TCall(field, []);
+                etype = t_dynamic;
                 epos = p;
-              }
-            in
-            gen.gafter_filters_ended <- delay :: gen.gafter_filters_ended; (* do not let filters alter this expression content *)
-            cl.cl_ordered_fields <- cfield :: cl.cl_ordered_fields;
-            cl.cl_fields <- PMap.add cfield.cf_name cfield cl.cl_fields;
-            if level <> 0 then cl.cl_overrides <- cfield :: cl.cl_overrides
+              } in
+              let call = gen.gparam_func_call call field reverse_params [] in
+              let delay () =
+                cfield.cf_expr <-
+                Some {
+                  eexpr = TFunction(
+                  {
+                    tf_args = [];
+                    tf_type = t_dynamic;
+                    tf_expr =
+                    {
+                      eexpr = TReturn( Some call );
+                      etype = t_dynamic;
+                      epos = p;
+                    }
+                  });
+                  etype = cfield.cf_type;
+                  epos = p;
+                }
+              in
+              gen.gafter_filters_ended <- delay :: gen.gafter_filters_ended; (* do not let filters alter this expression content *)
+              cl.cl_ordered_fields <- cfield :: cl.cl_ordered_fields;
+              cl.cl_fields <- PMap.add cfield.cf_name cfield cl.cl_fields;
+              if level <> 0 then cl.cl_overrides <- cfield :: cl.cl_overrides
+            end
           end;
           let get_reverse super supertl =
             let kv = List.map2 (fun (_,tparam) applied -> (follow applied, follow tparam)) super.cl_types supertl in
@@ -4228,22 +4231,24 @@ struct
 
         let implement_stub_cast cthis iface tl =
           let name = get_cast_name iface in
-          let cparams = List.map (fun (s,t) -> ("To_" ^ s, TInst(map_param (get_cl_t t), []))) iface.cl_types in
-          let field = mk_class_field name (TFun([],t_dynamic)) false iface.cl_pos (Method MethNormal) cparams in
-          let this = { eexpr = TConst TThis; etype = TInst(cthis, List.map snd cthis.cl_types); epos = cthis.cl_pos } in
-          field.cf_expr <- Some {
-            etype = TFun([],t_dynamic);
-            epos = this.epos;
-            eexpr = TFunction {
-              tf_type = t_dynamic;
-              tf_args = [];
-              tf_expr = mk_block { this with
-                eexpr = TReturn (Some this)
+          if not (PMap.mem name cthis.cl_fields) then begin
+            let cparams = List.map (fun (s,t) -> ("To_" ^ s, TInst(map_param (get_cl_t t), []))) iface.cl_types in
+            let field = mk_class_field name (TFun([],t_dynamic)) false iface.cl_pos (Method MethNormal) cparams in
+            let this = { eexpr = TConst TThis; etype = TInst(cthis, List.map snd cthis.cl_types); epos = cthis.cl_pos } in
+            field.cf_expr <- Some {
+              etype = TFun([],t_dynamic);
+              epos = this.epos;
+              eexpr = TFunction {
+                tf_type = t_dynamic;
+                tf_args = [];
+                tf_expr = mk_block { this with
+                  eexpr = TReturn (Some this)
+                }
               }
-            }
-          };
-          cthis.cl_ordered_fields <- field :: cthis.cl_ordered_fields;
-          cthis.cl_fields <- PMap.add name field cthis.cl_fields
+            };
+            cthis.cl_ordered_fields <- field :: cthis.cl_ordered_fields;
+            cthis.cl_fields <- PMap.add name field cthis.cl_fields
+          end
         in
 
         let rec run md =

+ 4 - 2
gencs.ml

@@ -1473,7 +1473,8 @@ let configure gen =
                       let t = Common.timer "expression to string" in
                       expr_s w { expr with eexpr = TBlock(rest) };
                       t();
-                      end_block w
+                      write w "#line default";
+                      end_block w;
                     | _ -> assert false
                 end else begin
                   begin_block w;
@@ -1481,7 +1482,8 @@ let configure gen =
                   let t = Common.timer "expression to string" in
                   expr_s w expr;
                   t();
-                  end_block w
+                  write w "#line default";
+                  end_block w;
                 end)
               | (Meta.FunctionCode, [Ast.EConst (Ast.String contents),_],_) :: tl ->
                 begin_block w;

+ 12 - 0
std/cs/_std/Type.hx

@@ -177,12 +177,24 @@ import cs.internal.Runtime;
 		if (untyped cl == String)
 			return args[0];
 		var t:cs.system.Type = Lib.toNativeType(cl);
+		if (t.IsInterface)
+		{
+			//may be generic
+			t = Lib.toNativeType(resolveClass(getClassName(cl)));
+		}
 		var ctors = t.GetConstructors();
 		return Runtime.callMethod(null, cast ctors, ctors.Length, args);
 	}
 
 	public static function createEmptyInstance<T>( cl : Class<T> ) : T
 	{
+		var t:cs.system.Type = Lib.toNativeType(cl);
+		if (t.IsInterface)
+		{
+			//may be generic
+			t = Lib.toNativeType(resolveClass(getClassName(cl)));
+		}
+
 		if (Reflect.hasField(cl, "__hx_createEmpty"))
 			return untyped cl.__hx_createEmpty();
 		return createInstance(cl, []);

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

@@ -416,6 +416,7 @@ import cs.system.Type;
 
 	public static function callMethod(obj:Dynamic, methods:NativeArray<MethodBase>, methodLength:Int, args:Array<Dynamic>):Dynamic
 	{
+		if (methodLength == 0) throw "No available methods";
 		var length = args.length;
 		var oargs:NativeArray<Dynamic> = new NativeArray(length);
 		var ts:NativeArray<cs.system.Type> = new NativeArray(length);