Procházet zdrojové kódy

all type parameters are now TInst
remove cl_shadow, use cl_kind
haxe.rtti.Generic support

Nicolas Cannasse před 17 roky
rodič
revize
e1e17dba33
7 změnil soubory, kde provedl 356 přidání a 65 odebrání
  1. 2 0
      doc/CHANGES.txt
  2. 23 21
      genswf9.ml
  3. 134 0
      std/flash9/FastList.hx
  4. 3 0
      std/haxe/ImportAll.hx
  5. 33 0
      std/haxe/rtti/Generic.hx
  6. 38 2
      type.ml
  7. 123 42
      typer.ml

+ 2 - 0
doc/CHANGES.txt

@@ -1,6 +1,8 @@
 2008-??-??: 1.19
 	fixed flash9 Array.toString
 	fixed inline return bug
+	added haxe.rtti.Generic behavior
+	added flash9.FastList
 	TODO haxe/f9 : inline code can give bad file in debug infos
 	TODO haxe/f9 var x = if( true ) Math.POSITIVE_INFINITY : 0.; VerifyError
 

+ 23 - 21
genswf9.ml

@@ -177,16 +177,16 @@ let type_id ctx t =
 	match follow_basic t with
 	| TEnum ({ e_path = path; e_extern = false },_) ->
 		type_path ctx path
-	| TInst ({ cl_shadow = true } as c,_) ->
-		(match c.cl_implements with
-		| [] ->
-			(match c.cl_super with
-			| None -> type_path ctx ([],"Object")
-			| Some (csup,_) -> type_path ctx csup.cl_path)
-		| [csup,_] -> type_path ctx csup.cl_path
-		| _ -> type_path ctx ([],"Object"))
 	| TInst (c,_) ->
-		type_path ctx c.cl_path
+		(match c.cl_kind with
+		| KTypeParameter ->
+			(match c.cl_implements with
+			| [csup,_] -> type_path ctx csup.cl_path
+			| _ -> type_path ctx ([],"Object"))
+		| KExtension (c,_) ->
+			type_path ctx c.cl_path
+		| _ ->
+			type_path ctx c.cl_path)
 	| TFun _ ->
 		type_path ctx ([],"Function")
 	| TEnum ({ e_path = ([],"Class") as path },_)
@@ -889,7 +889,7 @@ let rec gen_expr_content ctx retval e =
 		let branch = begin_branch ctx in
 		let switch_index = DynArray.length ctx.code in
 		let switch_pos = ctx.infos.ipos in
-		write ctx (HSwitch (0,[]));		
+		write ctx (HSwitch (0,[]));
 		(match def with
 		| None ->
 			if retval then begin
@@ -936,7 +936,7 @@ let rec gen_expr_content ctx retval e =
 		) cases in
 		let cases = Array.create (!max + 1) 1 in
 		List.iter (fun (tag,pos) -> Array.set cases tag (pos - switch_pos)) !constructs;
-		List.iter (fun j -> j()) jends;		
+		List.iter (fun j -> j()) jends;
 		DynArray.set ctx.code switch_index (HSwitch (1,Array.to_list cases));
 		branch();
 		free_reg ctx rparams
@@ -1252,16 +1252,18 @@ and jump_expr ctx e jif =
 let generate_method ctx fdata stat =
 	generate_function ctx { fdata with tf_expr = Transform.block_vars fdata.tf_expr } stat
 
-let generate_construct ctx fdata cfields =
+let generate_construct ctx fdata c =
 	(* make all args optional to allow no-param constructor *)
 	let f = begin_fun ctx (List.map (fun (a,o,t) -> a,true,t) fdata.tf_args) fdata.tf_type [ethis;fdata.tf_expr] false fdata.tf_expr.epos in
 	(* if skip_constructor, then returns immediatly *)
-	let id = ident "skip_constructor" in
-	getvar ctx (VGlobal (type_path ctx ([],ctx.boot)));
-	getvar ctx (VId id);
-	let j = jump ctx J3False in
-	write ctx HRetVoid;
-	j();
+	if c.cl_kind <> KGenericInstance then begin
+		let id = ident "skip_constructor" in
+		getvar ctx (VGlobal (type_path ctx ([],ctx.boot)));
+		getvar ctx (VId id);
+		let j = jump ctx J3False in
+		write ctx HRetVoid;
+		j();
+	end;
 	(* --- *)
 	PMap.iter (fun _ f ->
 		match f.cf_expr with
@@ -1271,7 +1273,7 @@ let generate_construct ctx fdata cfields =
 			write ctx (HFunction (generate_method ctx fdata false));
 			write ctx (HInitProp id);
 		| _ -> ()
-	) cfields;
+	) c.cl_fields;
 	gen_expr ctx false (Transform.block_vars fdata.tf_expr);
 	write ctx HRetVoid;
 	f() , List.length fdata.tf_args
@@ -1402,10 +1404,10 @@ let generate_class ctx c =
 						etype = t_void;
 						epos = null_pos;
 					}
-				} c.cl_fields
+				} c
 		| Some f ->
 			match f.cf_expr with
-			| Some { eexpr = TFunction fdata } -> generate_construct ctx fdata c.cl_fields
+			| Some { eexpr = TFunction fdata } -> generate_construct ctx fdata c
 			| _ -> assert false
 	) in
 	let fields = Array.of_list (PMap.fold (fun f acc ->

+ 134 - 0
std/flash9/FastList.hx

@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2005-2008, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package flash;
+
+private class Cell<T> implements haxe.rtti.Generic {
+	public var elt : T;
+	public var next : Cell<T>;
+	public function new(elt,next) { this.elt = elt; this.next = next; }
+}
+
+/**
+	A linked-list of elements. A different class is created for each container used.
+**/
+class FastList<T> implements haxe.rtti.Generic {
+
+	public var head : Cell<T>;
+
+	/**
+		Creates a new empty list.
+	**/
+	public function new() {
+	}
+
+	/**
+		Add an element at the head of the list.
+	**/
+	public inline function add( item : T ) {
+		head = new Cell<T>(item,head);
+	}
+
+	/**
+		Returns the first element of the list, or null
+		if the list is empty.
+	**/
+	public inline function first() : T {
+		return if( head == null ) null else head.elt;
+	}
+
+	/**
+		Removes the first element of the list and
+		returns it or simply returns null if the
+		list is empty.
+	**/
+	public inline function pop() : T {
+		var k = head;
+		if( k== null )
+			return null;
+		else {
+			head = k.next;
+			return k.elt;
+		}
+	}
+
+	/**
+		Tells if a list is empty.
+	**/
+	public inline function isEmpty() : Bool {
+		return (head == null);
+	}
+
+	/**
+		Remove the first element that is [== v] from the list.
+		Returns [true] if an element was removed, [false] otherwise.
+	**/
+	public inline function remove( v : T ) : Bool {
+		var prev = null;
+		var l = head;
+		while( l != null ) {
+			if( l.elt == v ) {
+				if( prev == null )
+					head = l.next;
+				else
+					prev.next = l.next;
+				break;
+			}
+			prev = l;
+			l = l.next;
+		}
+		return (l != null);
+	}
+
+	/**
+		Returns an iterator on the elements of the list.
+	**/
+	public function iterator() : Iterator<T> {
+		var l = head;
+		return {
+			hasNext : function() {
+				return l != null;
+			},
+			next : function() {
+				var k = l;
+				l = k.next;
+				return k.elt;
+			}
+		};
+	}
+
+	/**
+		Returns a displayable representation of the String.
+	**/
+	public function toString() {
+		var a = new Array();
+		var l = head;
+		while( l != null ) {
+			a.push(l.elt);
+			l = l.next;
+		}
+		return "{"+a.join(",")+"}";
+	}
+
+}

+ 3 - 0
std/haxe/ImportAll.hx

@@ -84,6 +84,7 @@ import haxe.remoting.SocketWrapper;
 import haxe.rtti.Infos;
 import haxe.rtti.Type;
 import haxe.rtti.XmlParser;
+import haxe.rtti.Generic;
 
 import haxe.xml.Check;
 import haxe.xml.Fast;
@@ -99,6 +100,7 @@ import haxe.unit.TestStatus;
 // generated by haxe
 import flash.Boot;
 import flash.Lib;
+import flash.FastList;
 import flash.FlashXml__;
 import flash.accessibility.Accessibility;
 import flash.accessibility.AccessibilityImplementation;
@@ -311,6 +313,7 @@ import flash.system.Security;
 // generated by haxe
 import flash9.Boot;
 import flash9.Lib;
+import flash9.FastList;
 import flash9.FlashXml__;
 import flash9.accessibility.Accessibility;
 import flash9.accessibility.AccessibilityImplementation;

+ 33 - 0
std/haxe/rtti/Generic.hx

@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2006-2008, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package haxe.rtti;
+
+/**
+	You can implement this interface with a parametrized type. For each type
+	parameter used, a duplicate class with be created. This is useful on
+	platforms that supports runtime typing (such as flash9).
+**/
+interface Generic {
+}

+ 38 - 2
type.ml

@@ -113,13 +113,21 @@ and tclass_field = {
 	mutable cf_expr : texpr option;
 }
 
+and tclass_kind =
+	| KNormal
+	| KTypeParameter
+	| KExtension of tclass * tparams
+	| KConstant of tconstant
+	| KGeneric
+	| KGenericInstance
+
 and tclass = {
 	cl_path : module_path;
 	cl_pos : Ast.pos;
 	cl_doc : Ast.documentation;
 	cl_private : bool;
+	mutable cl_kind : tclass_kind;
 	mutable cl_extern : bool;
-	mutable cl_shadow : bool;
 	mutable cl_interface : bool;
 	mutable cl_types : (string * t) list;
 	mutable cl_super : (tclass * tparams) option;
@@ -200,8 +208,8 @@ let mk_class path pos doc priv =
 		cl_pos = pos;
 		cl_doc = doc;
 		cl_private = priv;
+		cl_kind = KNormal;
 		cl_extern = false;
-		cl_shadow = false;
 		cl_interface = false;
 		cl_types = [];
 		cl_super = None;
@@ -314,6 +322,34 @@ let rec link e a b =
 		| TDynamic _ -> true
 		| _ -> e := Some b; true
 
+let map loop t =
+	match t with
+	| TMono r ->
+		(match !r with
+		| None -> t
+		| Some t -> loop t) (* erase*)
+	| TEnum (_,[]) | TInst (_,[]) | TType (_,[]) ->
+		t
+	| TEnum (e,tl) ->
+		TEnum (e, List.map loop tl)
+	| TInst (c,tl) ->
+		TInst (c, List.map loop tl)
+	| TType (t2,tl) ->
+		TType (t2,List.map loop tl)
+	| TFun (tl,r) ->
+		TFun (List.map (fun (s,o,t) -> s, o, loop t) tl,loop r)
+	| TAnon a ->
+		TAnon {
+			a_fields = PMap.map (fun f -> { f with cf_type = loop f.cf_type }) a.a_fields;
+			a_status = a.a_status;
+		}
+	| TLazy f ->
+		let ft = !f() in
+		let ft2 = loop ft in
+		if ft == ft2 then t else ft2
+	| TDynamic t2 ->
+		if t == t2 then	t else TDynamic (loop t2)
+
 (* substitute parameters with other types *)
 let apply_params cparams params t =
 	match cparams with

+ 123 - 42
typer.ml

@@ -324,15 +324,16 @@ let rec load_normal_type ctx t p allow_no_params =
 		pt
 	with Not_found ->
 		let types , path , f = match load_type_def ctx p (t.tpackage,t.tname) with
-			| TClassDecl c -> c.cl_types , c.cl_path , (fun t -> TInst (c,t))
+			| TClassDecl c ->
+				c.cl_types , c.cl_path , (match c.cl_kind with KGeneric -> build_generic ctx c allow_no_params p | _ -> (fun t -> TInst (c,t)))
 			| TEnumDecl e -> e.e_types , e.e_path , (fun t -> TEnum (e,t))
 			| TTypeDecl t -> t.t_types , t.t_path , (fun tl -> TType(t,tl))
 		in
 		if allow_no_params && t.tparams = [] then
 			f (List.map (fun (name,t) ->
 				match follow t with
-				| TEnum _ -> mk_mono()
-				| _ -> error ("Type parameter " ^ name ^ " need constraint") p
+				| TInst (c,_) -> if c.cl_implements = [] then mk_mono() else error ("Type parameter " ^ name ^ " need constraint") p
+				| _ -> assert false
 			) types)
 		else if path = ([],"Dynamic") then
 			match t.tparams with
@@ -344,24 +345,25 @@ let rec load_normal_type ctx t p allow_no_params =
 			let tparams = List.map (fun t ->
 				match t with
 				| TPConst c ->
-					let name = (match c with
-						| String s -> "S" ^ s
-						| Int i -> "I" ^ i
-						| Float f -> "F" ^ f
+					let name, const = (match c with
+						| String s -> "S" ^ s, TString s
+						| Int i -> "I" ^ i, TInt (Int32.of_string i)
+						| Float f -> "F" ^ f, TFloat f
 						| _ -> assert false
 					) in
-					TEnum ({ e_path = ([],name); e_pos = p; e_doc = None; e_private = false; e_extern = true; e_types = []; e_constrs = PMap.empty; e_names = [] },[]), true
-				| TPType t -> load_type ctx p t, false
+					let c = mk_class ([],name) p None false in
+					c.cl_kind <- KConstant const;
+					TInst (c,[])
+				| TPType t -> load_type ctx p t
 			) t.tparams in
-			let bparams = List.map fst tparams in
-			let params = List.map2 (fun (t,isconst) (name,t2) ->
+			let params = List.map2 (fun t (name,t2) ->
+				let isconst = (match t with TInst ({ cl_kind = KConstant _ },_) -> true | _ -> false) in
 				if isconst <> (name = "Const") && t != t_dynamic then error (if isconst then "Constant value unexpected here" else "Constant value excepted as type parameter") p;
 				(match follow t2 with
 				| TInst (c,[]) ->
 					List.iter (fun (i,params) ->
-						unify ctx t (apply_params types bparams (TInst (i,params))) p
+						unify ctx t (apply_params types tparams (TInst (i,params))) p
 					) c.cl_implements
-				| TEnum (c,[]) -> ()
 				| _ -> assert false);
 				t
 			) tparams types in
@@ -387,7 +389,7 @@ and load_type ctx p t =
 							Not_found -> ()
 					) a.a_fields;
 					(* do NOT tag as extern - for protect *)
-					c2.cl_shadow <- true;
+					c2.cl_kind <- KExtension (c,tl);
 					c2.cl_super <- Some (c,tl);
 					c2.cl_fields <- a.a_fields;
 					TInst (c2,[])
@@ -441,7 +443,100 @@ and load_type ctx p t =
 		| _ ->
 			TFun (List.map (fun t -> "",false,load_type ctx p t) args,load_type ctx p r)
 
-let rec reverse_type t =
+and build_generic ctx c allow p tl =
+	let pack = fst c.cl_path in
+	let recurse = ref false in
+	let name = String.concat "_" (snd c.cl_path :: (List.map (fun t ->
+		let t = follow t in
+		let path = (match t with
+			| TInst (c,_) -> if c.cl_kind = KTypeParameter then recurse := true; c.cl_path
+			| TEnum (e,_) -> e.e_path
+			| _ -> error "Type parameter must be a class or enum instance" p
+		) in
+		match path with
+		| [] , name -> name
+		| l , name -> String.concat "_" l ^ "_" ^ name
+	) tl)) in
+	if !recurse then begin
+		TInst (c,tl)
+	end else try
+		load_normal_type ctx { tpackage = pack; tname = name; tparams = [] } p allow
+	with Error(Module_not_found path,_) when path = (pack,name) ->
+		(* try to find the module in which the generic class was originally defined *)
+		let mpath = (if c.cl_private then match List.rev (fst c.cl_path) with [] -> assert false | x :: l -> List.rev l, String.sub x 1 (String.length x - 1) else c.cl_path) in
+		let m = try Hashtbl.find ctx.modules mpath with Not_found -> assert false in
+		let ctx = { ctx with local_types = m.mtypes @ ctx.local_types } in
+		let cg = mk_class (pack,name) c.cl_pos None false in
+		let mg = {
+			mpath = cg.cl_path;
+			mtypes = [TClassDecl cg];
+			mimports = [];
+		} in
+		Hashtbl.add ctx.modules mg.mpath mg;
+		let rec loop l1 l2 =
+			match l1, l2 with
+			| [] , [] -> []
+			| (x,TLazy f) :: l1, _ -> loop ((x,(!f)()) :: l1) l2
+			| (_,t1) :: l1 , t2 :: l2 -> (t1,t2) :: loop l1 l2
+			| _ -> assert false
+		in
+		let subst = loop c.cl_types tl in
+		let rec build_type t =
+			match t with
+			| TInst ({ cl_kind = KGeneric } as c,tl) ->
+				(* maybe loop, or generate cascading generics *)
+				load_type ctx p (reverse_type (TInst (c,List.map build_type tl)))
+			| _ ->
+				try List.assq t subst with Not_found -> Type.map build_type t
+		in
+		let rec build_expr e =
+			let t = build_type e.etype in
+			match e.eexpr with
+			| TFunction f ->
+				{
+					eexpr = TFunction {
+						tf_args = List.map (fun (n,o,t) -> n, o, build_type t) f.tf_args;
+						tf_type = build_type f.tf_type;
+						tf_expr = build_expr f.tf_expr;
+					};
+					etype = t;
+					epos = e.epos;
+				}
+			| TNew (c,tl,el) ->
+				let c, tl = (match follow t with TInst (c,tl) -> c, tl | _ -> assert false) in
+				{
+					eexpr = TNew (c,tl,List.map build_expr el);
+					etype = t;
+					epos = e.epos;
+				};
+			| TVars vl ->
+				{
+					eexpr = TVars (List.map (fun (v,t,eo) ->
+						v, build_type t, (match eo with None -> None | Some e -> Some (build_expr e))
+					) vl);
+					etype = t;
+					epos = e.epos;
+				}
+			(* there's still some 't' lefts in TFor, TMatch and TTry *)
+			| _ ->
+				Transform.map build_expr { e with etype = t }
+		in
+		let build_field f =
+			let t = build_type f.cf_type in
+			{ f with cf_type = t; cf_expr = (match f.cf_expr with None -> None | Some e -> Some (build_expr e)) }
+		in
+		if c.cl_super <> None || c.cl_init <> None || c.cl_dynamic <> None then error "This class can't be generic" p;
+		if c.cl_ordered_statics <> [] then error "A generic class can't have static fields" p;
+		cg.cl_constructor <- (match c.cl_constructor with None -> None | Some c -> Some (build_field c));
+		cg.cl_implements <- List.map (fun (i,tl) -> i, List.map build_type tl) c.cl_implements;
+		cg.cl_ordered_fields <- List.map (fun f ->
+			let f = build_field f in
+			cg.cl_fields <- PMap.add f.cf_name f cg.cl_fields;
+			f
+		) c.cl_ordered_fields;
+		TInst (cg,[])
+
+and reverse_type t =
 	match t with
 	| TEnum (e,params) ->
 		TPNormal { tpackage = fst e.e_path; tname = snd e.e_path; tparams = List.map reverse_param params }
@@ -573,6 +668,8 @@ let set_heritance ctx c herits p =
 			extend_remoting ctx c t p false true
 		| HExtends { tpackage = ["haxe";"remoting"]; tname = "AsyncProxy"; tparams = [TPType(TPNormal t)] } ->
 			extend_remoting ctx c t p true true
+		| HImplements { tpackage = ["haxe";"rtti"]; tname = "Generic"; tparams = [] } ->
+			c.cl_kind <- KGeneric
 		| HExtends { tpackage = ["mt"]; tname = "AsyncProxy"; tparams = [TPType(TPNormal t)] } ->
 			extend_remoting ctx c t p true false
 		| HExtends t ->
@@ -603,35 +700,19 @@ let set_heritance ctx c herits p =
 	List.iter loop herits
 
 let type_type_params ctx path p (n,flags) =
-	let t = (match flags with
-	| [] ->
-		(* build a phantom enum *)
-		let e = {
-			e_path = (fst path @ [snd path],n);
-			e_pos = p;
-			e_private = true;
-			e_extern = true;
-			e_types = [];
-			e_constrs = PMap.empty;
-			e_doc = None;
-			e_names = [];
-		} in
-		TEnum (e,[])
-	| l ->
-		(* build a phantom class *)
-		let c = mk_class (fst path @ [snd path],n) p None true in
-		let t = TInst (c,[]) in
+	let c = mk_class (fst path @ [snd path],n) p None false in
+	c.cl_kind <- KTypeParameter;
+	let t = TInst (c,[]) in
+	match flags with
+	| [] -> n, t
+	| _ ->
 		let r = exc_protect (fun r ->
 			r := (fun _ -> t);
-			set_heritance ctx c (List.map (fun t -> HImplements t) l) p;
+			set_heritance ctx c (List.map (fun t -> HImplements t) flags) p;
 			t
 		) in
-		c.cl_extern <- true;
-		c.cl_shadow <- true;
 		ctx.delays := [(fun () -> ignore(!r()))] :: !(ctx.delays);
-		TLazy r
-	) in
-	n , t
+		n, TLazy r
 
 let hide_types ctx =
 	let old_locals = ctx.local_types in
@@ -2181,7 +2262,7 @@ and type_inline ctx f ethis params tret p =
 		| _ -> Transform.map inline_params e
 	in
 	let e = (if PMap.is_empty subst then e else inline_params e) in
-	let init = (match vars with [] -> None | l -> Some (mk (TVars (List.rev l)) (t_void ctx) p)) in	
+	let init = (match vars with [] -> None | l -> Some (mk (TVars (List.rev l)) (t_void ctx) p)) in
 	if 	Plugin.defined "js" && (init <> None || !has_vars) then
 		None
 	else match e.eexpr, init with
@@ -2544,7 +2625,7 @@ let init_class ctx c p herits fields =
 				cf_doc = doc;
 				cf_type = t;
 				cf_get = if inline then InlineAccess else NormalAccess;
-				cf_set = (if inline then NeverAccess else if ctx.flash9 && not (List.mem AF9Dynamic access) then F9MethodAccess else NormalAccess);
+				cf_set = (if ctx.flash9 && not (List.mem AF9Dynamic access) then F9MethodAccess else if inline then NeverAccess else NormalAccess);
 				cf_expr = None;
 				cf_public = is_public access;
 				cf_params = params;
@@ -3110,7 +3191,7 @@ let types ctx main excludes =
 				let t = field_type f in
 				(match follow t with
 				| TFun ([],r) -> t, r
-				| _ -> error ("Invalid -main : " ^ s_type_path cl ^ " has invalid main function") null_pos);				
+				| _ -> error ("Invalid -main : " ^ s_type_path cl ^ " has invalid main function") null_pos);
 			with
 				Not_found -> error ("Invalid -main : " ^ s_type_path cl ^ " does not have static function main") null_pos
 		) in