Kaynağa Gözat

added TLazy for macros

Nicolas Cannasse 14 yıl önce
ebeveyn
işleme
0294ecc17e
5 değiştirilmiş dosya ile 27 ekleme ve 4 silme
  1. 1 0
      doc/CHANGES.txt
  2. 19 2
      interp.ml
  3. 1 0
      std/haxe/macro/Type.hx
  4. 3 0
      typeload.ml
  5. 3 2
      typer.ml

+ 1 - 0
doc/CHANGES.txt

@@ -7,6 +7,7 @@
 	js : upgraded jquery version
 	sys : added "in" operator for spod macros
 	macro : added ECheckType
+	macro : added TLazy for not-yet-typed class fields
 
 2011-09-25: 2.08
 	js : added js.JQuery

+ 19 - 2
interp.ml

@@ -57,6 +57,7 @@ and vabstract =
 	| ATExpr of texpr
 	| ATDecl of module_type
 	| AUnsafe of Obj.t
+	| ALazyType of (unit -> Type.t) ref
 
 and vfunction =
 	| Fun0 of (unit -> value)
@@ -2637,6 +2638,8 @@ and call ctx vthis vfun pl p =
 			| [a;b;c;d;e], Fun5 f -> f a b c d e
 			| _, FunVar f -> f pl
 			| _ -> exc (VString (Printf.sprintf "Invalid call (%d args instead of %d)" (List.length pl) (nargs f))))
+		| VAbstract (ALazyType f) ->
+			encode_type ((!f)())
 		| _ ->
 			exc (VString "Invalid call"))
 	with Return v -> v
@@ -3492,7 +3495,7 @@ and encode_efield f =
 and encode_cfield f =
 	enc_obj [
 		"name", enc_string f.cf_name;
-		"type", encode_type f.cf_type;
+		"type", (match f.cf_kind with Method _ -> encode_lazy_type f.cf_type | _ -> encode_type f.cf_type);
 		"isPublic", VBool f.cf_public;
 		"params", enc_array (List.map (fun (n,t) -> enc_obj ["name",enc_string n;"t",encode_type t]) f.cf_params);
 		"meta", encode_meta f.cf_meta (fun m -> f.cf_meta <- m);
@@ -3595,11 +3598,24 @@ and encode_type t =
 			else
 				6, [encode_type tsub]
 		| TLazy f ->
-			loop ((!f)())
+			loop (!f())
 	in
 	let tag, pl = loop t in
 	enc_enum IType tag pl
 
+and encode_lazy_type t =
+	let rec loop = function
+		| TMono r ->
+			(match !r with
+			| Some t -> loop t
+			| _ -> encode_type t)
+		| TLazy f ->
+			enc_enum IType 7 [VAbstract (ALazyType f)]
+		| _ ->
+			encode_type t
+	in
+	loop t
+
 and decode_type t =
 	match decode_enum t with
 	| 0, [r] -> TMono (decode_ref r)
@@ -3610,6 +3626,7 @@ and decode_type t =
 	| 5, [a] -> TAnon (decode_ref a)
 	| 6, [VNull] -> t_dynamic
 	| 6, [t] -> TDynamic (decode_type t)
+	| 7, [VAbstract (ALazyType f)] -> TLazy f
 	| _ -> raise Invalid_expr
 
 and encode_texpr e =

+ 1 - 0
std/haxe/macro/Type.hx

@@ -37,6 +37,7 @@ enum Type {
 	TFun( args : Array<{ name : String, opt : Bool, t : Type }>, ret : Type );
 	TAnonymous( a : Ref<AnonType> );
 	TDynamic( t : Null<Type> );
+	TLazy( f : Void -> Type );
 }
 
 typedef AnonType = {

+ 3 - 0
typeload.ml

@@ -929,6 +929,7 @@ let init_class ctx c p herits fields =
 						if ctx.com.verbose then print_endline ("Typing " ^ s_type_path c.cl_path ^ "." ^ name);
 						cf.cf_meta <- if has_meta ":?keep" cf.cf_meta then f.cff_meta else (":?keep", [], p) :: f.cff_meta;
 						cf.cf_expr <- Some (type_static_var ctx t e p);
+						cf.cf_type <- t;
 						t
 					) in
 					cf.cf_type <- TLazy r;
@@ -946,6 +947,7 @@ let init_class ctx c p herits fields =
 						r := (fun() -> t);
 						if ctx.com.verbose then print_endline ("Typing " ^ s_type_path c.cl_path ^ "." ^ name);
 						cf.cf_expr <- Some (type_static_var ctx t e p);
+						cf.cf_type <- t;
 						t
 					) in
 					bind_type cf r (snd e) false
@@ -1038,6 +1040,7 @@ let init_class ctx c p herits fields =
 					| TBlock [] | TBlock [{ eexpr = TConst _ }] | TConst _ | TObjectDecl [] -> ()
 					| _ -> c.cl_init <- Some e);
 				cf.cf_expr <- Some (mk (TFunction f) t p);
+				cf.cf_type <- t;
 				t
 			) in
 			let delay = if (ctx.com.dead_code_elimination && not ctx.com.display) then begin

+ 3 - 2
typer.ml

@@ -1741,8 +1741,9 @@ and type_expr ctx ?(need_val=true) (e,p) =
 			error "Not a class" p)
 	| ECheckType (e,t) ->
 		let e = type_expr ctx ~need_val e in
-		unify ctx e.etype (Typeload.load_complex_type ctx p t) e.epos;
-		e
+		let t = Typeload.load_complex_type ctx p t in
+		unify ctx e.etype t e.epos;
+		if e.etype == t then e else mk (TCast (e,None)) t p
 
 and type_call ctx e el p =
 	match e, el with