Selaa lähdekoodia

[cs] Full C# support for Null<>. Fixes Issue #808

Caue Waneck 13 vuotta sitten
vanhempi
commit
5041333824
2 muutettua tiedostoa jossa 23 lisäystä ja 13 poistoa
  1. 6 6
      gencommon.ml
  2. 17 7
      gencs.ml

+ 6 - 6
gencommon.ml

@@ -4364,7 +4364,7 @@ struct
       | TMono _, _
       | TMono _, _
       | TDynamic _, _
       | TDynamic _, _
       | TAnon _, _ when gen.gneeds_box real_from_t -> 
       | TAnon _, _ when gen.gneeds_box real_from_t -> 
-        mk_cast to_t e
+        mk_cast to_t (mk_paren e)
       | TMono _, _
       | TMono _, _
       | TDynamic _, _ -> e
       | TDynamic _, _ -> e
       | _, TMono _
       | _, TMono _
@@ -8184,12 +8184,12 @@ struct
           mk_cast to_t (unwrap_null e)
           mk_cast to_t (unwrap_null e)
     in
     in
     
     
-    let handle_wrap e =
+    let handle_wrap e t =
       match e.eexpr with
       match e.eexpr with
         | TConst(TNull) ->
         | TConst(TNull) ->
-          wrap_val e false
+          wrap_val e t false
         | _ ->
         | _ ->
-          wrap_val e true
+          wrap_val e t true
     in
     in
     
     
     let is_null_t = is_null_t gen in
     let is_null_t = is_null_t gen in
@@ -8201,7 +8201,7 @@ struct
           if is_some null_vt && is_none null_et then
           if is_some null_vt && is_none null_et then
             handle_unwrap e.etype (run v)
             handle_unwrap e.etype (run v)
           else if is_none null_vt && is_some null_et then
           else if is_none null_vt && is_some null_et then
-            handle_wrap ({ (run v) with etype = get (is_null_t e.etype) })
+            handle_wrap (run v) (get (is_null_t e.etype))
           else
           else
             Type.map_expr run e
             Type.map_expr run e
         | TField(ef, field) when is_some (is_null_t ef.etype) ->
         | TField(ef, field) when is_some (is_null_t ef.etype) ->
@@ -8236,7 +8236,7 @@ struct
               (* if it is Null<T>, we need to convert the result again to null *)
               (* if it is Null<T>, we need to convert the result again to null *)
               let e_t = (is_null_t e.etype) in
               let e_t = (is_null_t e.etype) in
               if is_some e_t then
               if is_some e_t then
-                wrap_val { eexpr = TBinop(op, e1, e2); etype = get e_t; epos = e.epos } true
+                wrap_val { eexpr = TBinop(op, e1, e2); etype = get e_t; epos = e.epos } (get e_t) true
               else
               else
                 { e with eexpr = TBinop(op, e1, e2) }
                 { e with eexpr = TBinop(op, e1, e2) }
           )
           )

+ 17 - 7
gencs.ml

@@ -1219,6 +1219,12 @@ let configure gen =
   
   
   StubClosureImpl.configure gen (StubClosureImpl.default_implementation gen float_cl 10 (fun e _ _ -> e));*)
   StubClosureImpl.configure gen (StubClosureImpl.default_implementation gen float_cl 10 (fun e _ _ -> e));*)
   
   
+  let tp_v = alloc_var "$type_param" t_dynamic in
+  let mk_tp t pos = { eexpr = TLocal(tp_v); etype = t; epos = pos } in
+  TypeParams.configure gen (fun ecall efield params elist ->
+    { ecall with eexpr = TCall(efield, (List.map (fun t -> mk_tp t ecall.epos ) params) @ elist) }
+  );
+  
   HardNullableSynf.configure gen (HardNullableSynf.traverse gen 
   HardNullableSynf.configure gen (HardNullableSynf.traverse gen 
     (fun e ->
     (fun e ->
       match real_type e.etype with
       match real_type e.etype with
@@ -1227,10 +1233,19 @@ let configure gen =
         | _ -> 
         | _ -> 
           trace (debug_type e.etype); gen.gcon.error "This expression is not a Nullable expression" e.epos; assert false
           trace (debug_type e.etype); gen.gcon.error "This expression is not a Nullable expression" e.epos; assert false
     ) 
     ) 
-    (fun v has_value ->
-      { eexpr = TNew(null_t, [v.etype], [mk_cast v.etype v; { eexpr = TConst(TBool has_value); etype = gen.gcon.basic.tbool; epos = v.epos } ]); etype = TInst(null_t, [v.etype]); epos = v.epos }
+    (fun v t has_value ->
+      match has_value, real_type v.etype with
+        | true, TDynamic _ | true, TAnon _ | true, TMono _ ->
+          {
+            eexpr = TCall(mk_static_field_access_infer null_t "ofDynamic" v.epos [t], [mk_tp t v.epos; v]);
+            etype = TInst(null_t, [t]);
+            epos = v.epos
+          }
+        | _ -> 
+          { eexpr = TNew(null_t, [t], [mk_cast t v; { eexpr = TConst(TBool has_value); etype = gen.gcon.basic.tbool; epos = v.epos } ]); etype = TInst(null_t, [t]); epos = v.epos }
     ) 
     ) 
     (fun e ->
     (fun e ->
+      trace (debug_expr e);
       {
       {
         eexpr = TCall({
         eexpr = TCall({
             eexpr = TField(e, "toDynamic");
             eexpr = TField(e, "toDynamic");
@@ -1512,11 +1527,6 @@ let configure gen =
     end
     end
   ));
   ));
   
   
-  let v = alloc_var "$type_param" t_dynamic in
-  TypeParams.configure gen (fun ecall efield params elist ->
-    { ecall with eexpr = TCall(efield, (List.map (fun t -> { eexpr = TLocal(v); etype = t; epos = ecall.epos }) params) @ elist) }
-  );
-  
   CastDetect.configure gen (CastDetect.default_implementation gen (Some (TEnum(empty_e, []))));
   CastDetect.configure gen (CastDetect.default_implementation gen (Some (TEnum(empty_e, []))));
   
   
   (*FollowAll.configure gen;*)
   (*FollowAll.configure gen;*)