瀏覽代碼

added TSign , signatures can be bound to any type.

Nicolas Cannasse 19 年之前
父節點
當前提交
0d96dfc06e
共有 7 個文件被更改,包括 173 次插入103 次删除
  1. 7 2
      ast.ml
  2. 1 0
      genjs.ml
  3. 1 0
      genswf8.ml
  4. 4 3
      genxml.ml
  5. 41 25
      parser.ml
  6. 37 27
      type.ml
  7. 82 46
      typer.ml

+ 7 - 2
ast.ml

@@ -133,10 +133,15 @@ type type_path_normal = {
 	tparams : type_path list;
 }
 
+and anonymous_field = 
+	| AFVar of type_path
+	| AFProp of type_path * string * string
+	| AFFun of (string * type_path) list * type_path
+
 and type_path = 
 	| TPNormal of type_path_normal
 	| TPFunction of type_path list * type_path
-	| TPAnonymous of (string * type_path) list
+	| TPAnonymous of (string * anonymous_field * pos) list
 	| TPParent of type_path
 
 type func = {
@@ -201,7 +206,7 @@ type type_param_flag =
 type type_def =
 	| EClass of string * documentation * type_param list * type_param_flag list * (class_field * pos) list
 	| EEnum of string * documentation * type_param list * enum_param list * (string * documentation * (string * type_path) list * pos) list
-	| ESignature of string * documentation * type_param list * enum_param list * (class_field * pos) list
+	| ESignature of string * documentation * type_param list * enum_param list * type_path
 	| EImport of (string list * string)
 
 type type_decl = type_def * pos

+ 1 - 0
genjs.ml

@@ -320,6 +320,7 @@ and gen_expr ctx e =
 			| TInst (c,_) -> Some (TClassDecl c)
 			| TFun _
 			| TLazy _
+			| TSign _
 			| TAnon _ ->
 				assert false
 			| TMono _

+ 1 - 0
genswf8.ml

@@ -538,6 +538,7 @@ and gen_try_catch ctx retval e catchs =
 			| TInst (c,_) -> Some (TClassDecl c)
 			| TFun _
 			| TLazy _
+			| TSign _
 			| TAnon _ ->
 				assert false
 			| TMono _

+ 4 - 3
genxml.ml

@@ -46,8 +46,9 @@ let rec gen_type t =
 	| TMono m -> (match !m with None -> tag "unknown" | Some t -> gen_type t)
 	| TEnum (e,params) -> node "e" [gen_path e.e_path] (List.map gen_type params)
 	| TInst (c,params) -> node "c" [gen_path c.cl_path] (List.map gen_type params)
+	| TSign (s,params) -> node "s" [gen_path s.s_path] (List.map gen_type params)
 	| TFun (args,r) -> node "f" ["a",String.concat ":" (List.map fst args)] (List.map gen_type (List.map snd args @ [r]))
-	| TAnon (fields,_,_) -> node "a" [] (pmap (fun f -> node f.cf_name [] [gen_type f.cf_type]) fields)
+	| TAnon fields -> node "a" [] (pmap (fun f -> node f.cf_name [] [gen_type f.cf_type]) fields)
 	| TDynamic t2 -> node "d" [] (if t == t2 then [] else [gen_type t2])
 	| TLazy f -> gen_type (!f())
 
@@ -83,8 +84,8 @@ let gen_type t =
 		node "enum" (gen_type_params e.e_private e.e_path e.e_types e.e_pos) (pmap gen_constr e.e_constrs @ doc)
 	| TSignatureDecl s ->
 		let doc = gen_doc_opt s.s_doc in
-		let fields = pmap (gen_field []) s.s_fields in
-		node "signature" (gen_type_params false s.s_path [] s.s_pos) (fields @ doc)
+		let t = [] in
+		node "signature" (gen_type_params false s.s_path [] s.s_pos) (t @ doc)
 
 let att_str att = 
 	String.concat "" (List.map (fun (a,v) -> Printf.sprintf " %s=\"%s\"" a v) att)

+ 41 - 25
parser.ml

@@ -149,7 +149,13 @@ and parse_type_decl s =
 		match s with parser 
 		| [< n , p1 = parse_enum_params; doc = get_doc; '(Const (Type name),_); tl = parse_type_params; '(BrOpen,_); l = plist parse_enum; '(BrClose,p2) >] -> (EEnum (name,doc,tl,List.map snd c @ n,l), punion p1 p2)
 		| [< n , p1 = parse_class_params; doc = get_doc; '(Const (Type name),_); tl = parse_type_params; hl = psep Comma parse_class_herit; '(BrOpen,_); fl = plist parse_class_field; '(BrClose,p2) >] -> (EClass (name,doc,tl,List.map fst c @ n @ hl,fl), punion p1 p2)
-		| [< '(Const (Ident "signature"),p1); doc = get_doc; '(Const (Type name),_); tl = parse_type_params; '(BrOpen,_); fl = plist parse_signature_field; '(BrClose,p2) >] -> (ESignature (name,doc,tl,List.map snd c,fl), punion p1 p2)
+		| [< '(Const (Ident "signature"),p1); doc = get_doc; '(Const (Type name),p2); tl = parse_type_params; s >] ->
+			let t = (match s with parser
+				| [< '(Binop OpAssign,_); t = parse_type_path >] -> t
+				| [< t = parse_type_path >] -> t
+				| [< >] -> serror()
+			) in
+			(ESignature (name,doc,tl,List.map snd c,t), punion p1 p2)
 
 and parse_package s = psep Dot ident s
 
@@ -173,7 +179,13 @@ and parse_type_opt = parser
 
 and parse_type_path = parser
 	| [< '(POpen,_); t = parse_type_path; '(PClose,_); s >] -> parse_type_path_next (TPParent t) s
-	| [< '(BrOpen,_); l = psep Comma parse_type_anonymous; '(BrClose,_); s >] -> parse_type_path_next (TPAnonymous l) s
+	| [< '(BrOpen,_); s >] ->
+		let l = (match s with parser
+			| [< name = any_ident >] -> parse_type_anonymous_resume name s
+			| [< l = plist parse_signature_field; '(BrClose,_) >] -> l
+			| [< >] -> serror()
+		) in
+		parse_type_path_next (TPAnonymous l) s
 	| [< t = parse_type_path_normal; s >] -> parse_type_path_next (TPNormal t) s
 
 and parse_type_path_normal s = parse_type_path1 [] s
@@ -200,8 +212,16 @@ and parse_type_path_next t = parser
 			TPFunction ([t] , t2))
 	| [< >] -> t 
 
+and parse_type_anonymous_resume name = parser
+	| [< '(DblDot,p); t = parse_type_path; s >] ->
+		(name, AFVar t, p) ::
+		match s with parser
+		| [< '(BrClose,_) >] -> []
+		| [< '(Comma,_); l = psep Comma parse_type_anonymous; '(BrClose,_) >] -> l
+		| [< >] -> serror()
+
 and parse_type_anonymous = parser
-	| [< '(Const (Ident name),_); '(DblDot,_); t = parse_type_path >] -> (name,t)
+	| [< name = any_ident; '(DblDot,p); t = parse_type_path >] -> (name, AFVar t, p)
 
 and parse_enum s = 
 	doc := None;
@@ -213,7 +233,7 @@ and parse_enum s =
 		| [< >] -> serror()
 
 and parse_enum_param = parser
-	| [< '(Const (Ident name),_); '(DblDot,_); t = parse_type_path >] -> (name,t)
+	| [< name = any_ident; '(DblDot,_); t = parse_type_path >] -> (name,t)
 
 and parse_class_field s =
 	doc := None;
@@ -243,22 +263,13 @@ and parse_class_field s =
 			(FFun (name,doc,l,pl,f),punion p1 (pos e))
 		| [< >] -> if l = [] then raise Stream.Failure else serror()
 
-and parse_signature_field s =
-	doc := None;
-	match s with parser
-	| [< l = parse_cf_rights false []; doc = get_doc; s >] ->
-		match s with parser
-		| [< '(Kwd Var,p1); name = any_ident; t = parse_type_opt; p2 = semicolon >] -> (FVar (name,doc,l,t,None),punion p1 p2)
-		| [< '(Const (Ident "property"),p1); name = any_ident; '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_); '(DblDot,_); t = parse_type_path; p2 = semicolon >] ->
-			(FProp (name,doc,l,i1,i2,t),punion p1 p2)
-		| [< '(Kwd Function,p1); name = parse_fun_name; pl = parse_type_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; p2 = semicolon >] ->
-			let f = {
-				f_args = al;
-				f_type = t;
-				f_expr = (EBlock [],p2);
-			} in
-			(FFun (name,doc,l,pl,f),punion p1 p2)
-		| [< >] -> if l = [] then raise Stream.Failure else serror()
+and parse_signature_field = parser
+	| [< '(Kwd Var,p1); name = any_ident; '(DblDot,_); t = parse_type_path; p2 = semicolon >] ->
+		(name,AFVar t,punion p1 p2)
+	| [< '(Const (Ident "property"),p1); name = any_ident; '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_); '(DblDot,_); t = parse_type_path; p2 = semicolon >] ->
+		(name,AFProp (t,i1,i2),punion p1 p2)
+	| [< '(Kwd Function,p1); name = any_ident; '(POpen,_); al = psep Comma parse_fun_param_type; '(PClose,_); '(DblDot,_); t = parse_type_path; p2 = semicolon >] ->
+		(name,AFFun (al,t),punion p1 p2)
 
 and parse_cf_rights allow_static l = parser
 	| [< '(Kwd Static,_) when allow_static; l = parse_cf_rights false (AStatic :: l) >] -> l
@@ -272,7 +283,10 @@ and parse_fun_name = parser
 	| [< '(Kwd New,_) >] -> "new"
 
 and parse_fun_param = parser
-	| [< '(Const (Ident name),_); t = parse_type_opt >] -> (name,t)
+	| [< name = any_ident; t = parse_type_opt >] -> (name,t)
+
+and parse_fun_param_type = parser
+	| [< name = any_ident; '(DblDot,_); t = parse_type_path >] -> (name,t)
 
 and parse_type_params = parser
 	| [< '(Binop OpLt,_); l = psep Comma parse_type_param; '(Binop OpGt,_) >] -> l
@@ -293,12 +307,14 @@ and parse_class_herit = parser
 	| [< '(Kwd Implements,_); t = parse_type_path_normal >] -> HImplements t
 
 and block1 = parser
-	| [< '(Const (Ident name),p); s >] ->
-		(match s with parser
-		| [< '(DblDot,_); e = expr; l = plist parse_obj_decl; _ = popt comma >] -> EObjectDecl ((name,e) :: l)
-		| [< e = expr_next (EConst (Ident name),p); _ = semicolon; b = block >] -> EBlock (e :: b))
+	| [< '(Const (Ident name),p); s >] -> block2 name true p s
+	| [< '(Const (Type name),p); s >] -> block2 name false p s
 	| [< b = block >] -> EBlock b
 
+and block2 name ident p = parser
+	| [< '(DblDot,_); e = expr; l = plist parse_obj_decl; _ = popt comma >] -> EObjectDecl ((name,e) :: l)
+	| [< e = expr_next (EConst (if ident then Ident name else Type name),p); _ = semicolon; b = block >] -> EBlock (e :: b)
+
 and block s = plist parse_block_elt s
 
 and parse_block_elt = parser

+ 37 - 27
type.ml

@@ -28,8 +28,9 @@ type t =
 	| TMono of t option ref
 	| TEnum of tenum * t list
 	| TInst of tclass * t list
+	| TSign of tsignature * t list
 	| TFun of (string * t) list * t
-	| TAnon of (string, tclass_field) PMap.t * t list * string option
+	| TAnon of (string, tclass_field) PMap.t
 	| TDynamic of t
 	| TLazy of (unit -> t) ref
 
@@ -133,7 +134,7 @@ and tsignature = {
 	s_doc : Ast.documentation;
 	s_private : bool;
 	mutable s_types : (string * t) list;
-	mutable s_fields : (string, tclass_field) PMap.t;
+	mutable s_type : t;
 }
 
 and module_type = 
@@ -195,18 +196,17 @@ let rec s_type ctx t =
 		Ast.s_type_path e.e_path ^ s_type_params ctx tl
 	| TInst (c,tl) ->
 		Ast.s_type_path c.cl_path ^ s_type_params ctx tl
+	| TSign (s,tl) ->
+		Ast.s_type_path s.s_path ^ s_type_params ctx tl
 	| TFun ([],t) ->
 		"Void -> " ^ s_fun ctx t false
 	| TFun (l,t) ->
 		String.concat " -> " (List.map (fun (s,t) -> 
 			(if s = "" then "" else s ^ " : ") ^ s_fun ctx t true
 		) l) ^ " -> " ^ s_fun ctx t false
-	| TAnon (fl,tl,name) ->
-		(match name with
-		| Some s -> s ^ s_type_params ctx tl
-		| None ->
-			let fl = PMap.fold (fun f acc -> (" " ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) fl [] in
-			"{" ^ String.concat "," fl ^ " }");
+	| TAnon fl ->
+		let fl = PMap.fold (fun f acc -> (" " ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) fl [] in
+		"{" ^ String.concat "," fl ^ " }"
 	| TDynamic t2 ->
 		"Dynamic" ^ s_type_params ctx (if t == t2 then [] else [t2])
 	| TLazy f ->		
@@ -222,16 +222,6 @@ and s_type_params ctx = function
 	| [] -> ""
 	| l -> "<" ^ String.concat ", " (List.map (s_type ctx) l) ^ ">"
 
-let rec follow t =
-	match t with
-	| TMono r ->
-		(match !r with
-		| Some t -> follow t
-		| _ -> t)
-	| TLazy f ->		
-		follow (!f())
-	| _ -> t
-
 let rec is_parent csup c =
 	if c == csup then
 		true
@@ -245,8 +235,7 @@ let rec link e a b =
 			true
 		else match t with
 		| TMono t -> (match !t with None -> false | Some t -> loop t)
-		| TEnum (_,tl) -> List.exists loop tl
-		| TInst (_,tl) -> List.exists loop tl
+		| TEnum (_,tl) | TInst (_,tl) | TSign (_,tl) -> List.exists loop tl
 		| TFun (tl,t) -> List.exists (fun (_,t) -> loop t) tl || loop t
 		| TDynamic t2 ->
 			if t == t2 then
@@ -255,8 +244,7 @@ let rec link e a b =
 				loop t2
 		| TLazy f ->
 			loop (!f())
-		| TAnon (fl,tl,_) ->
-			List.exists loop tl ||
+		| TAnon fl ->
 			try
 				PMap.iter (fun _ f -> if loop f.cf_type then raise Exit) fl;
 				false
@@ -295,6 +283,10 @@ let apply_params cparams params t =
 			(match tl with
 			| [] -> t
 			| _ -> TEnum (e,List.map loop tl))
+		| TSign (s,tl) ->
+			(match tl with
+			| [] -> t
+			| _ -> TSign (s,List.map loop tl))
 		| TInst (c,tl) ->
 			(match tl with
 			| [] ->
@@ -312,8 +304,8 @@ let apply_params cparams params t =
 				TInst (c,List.map loop tl))
 		| TFun (tl,r) ->
 			TFun (List.map (fun (s,t) -> s, loop t) tl,loop r)
-		| TAnon (fl,tl,name) ->
-			TAnon (PMap.map (fun f -> { f with cf_type = loop f.cf_type }) fl,List.map loop tl,name)
+		| TAnon fl ->
+			TAnon (PMap.map (fun f -> { f with cf_type = loop f.cf_type }) fl)
 		| TLazy f ->
 			loop (!f())
 		| TDynamic t2 ->
@@ -324,6 +316,18 @@ let apply_params cparams params t =
 	in
 	loop t
 
+let rec follow t =
+	match t with
+	| TMono r ->
+		(match !r with
+		| Some t -> follow t
+		| _ -> t)
+	| TLazy f ->
+		follow (!f())
+	| TSign (s,tl) ->
+		follow (apply_params s.s_types tl s.s_type)
+	| _ -> t
+
 let monomorphs eparams t =
 	apply_params eparams (List.map (fun _ -> mk_mono()) eparams) t
 
@@ -335,6 +339,8 @@ let rec type_eq param a b =
 	| _ , TLazy f -> type_eq param a (!f())
 	| TMono t , _ -> (match !t with None -> link t a b | Some t -> type_eq param t b)
 	| _ , TMono t -> (match !t with None -> link t b a | Some t -> type_eq param a t)
+	| TSign (s,tl) , _ -> type_eq param (apply_params s.s_types tl s.s_type) b
+	| _ , TSign (s,tl) -> type_eq param a (apply_params s.s_types tl s.s_type)
 	| TEnum (a,tl1) , TEnum (b,tl2) -> a == b && List.for_all2 (type_eq param) tl1 tl2
 	| TInst (c1,tl1) , TInst (c2,tl2) -> 
 		c1 == c2 && List.for_all2 (type_eq param) tl1 tl2
@@ -342,7 +348,7 @@ let rec type_eq param a b =
 		type_eq param r1 r2 && List.for_all2 (fun (_,t1) (_,t2) -> type_eq param t1 t2) l1 l2
 	| TDynamic a , TDynamic b ->
 		type_eq param a b
-	| TAnon (fl1,_,_), TAnon (fl2,_,_) ->
+	| TAnon fl1, TAnon fl2 ->
 		let keys1 = PMap.fold (fun f acc -> f :: acc) fl1 [] in
 		let keys2 = PMap.fold (fun f acc -> f :: acc) fl2 [] in
 		(try
@@ -399,6 +405,10 @@ let rec unify a b =
 		(match !t with
 		| None -> if not (link t b a) then error [cannot_unify a b]
 		| Some t -> unify a t)
+	| TSign (s,tl) , _ ->
+		unify (apply_params s.s_types tl s.s_type) b
+	| _ , TSign (s,tl) ->
+		unify a (apply_params s.s_types tl s.s_type)
 	| TEnum (ea,tl1) , TEnum (eb,tl2) -> 
 		if ea != eb then error [cannot_unify a b];
 		unify_types a b tl1 tl2
@@ -422,7 +432,7 @@ let rec unify a b =
 			List.iter2 (fun (_,t1) (_,t2) -> unify t1 t2) l2 l1 (* contravariance *)
 		with
 			Unify_error l -> error (cannot_unify a b :: l))
-	| TInst (c,tl) , TAnon (fl,_,_) ->
+	| TInst (c,tl) , TAnon fl ->
 		(try
 			PMap.iter (fun n f2 ->
 				let f1 = (try PMap.find n c.cl_fields with Not_found -> error [has_no_field a n]) in
@@ -436,7 +446,7 @@ let rec unify a b =
 			) fl
 		with
 			Unify_error l -> error (cannot_unify a b :: l))
-	| TAnon (fl1,_,_) , TAnon (fl2,_,_) ->
+	| TAnon fl1, TAnon fl2 ->
 		(try
 			PMap.iter (fun n f2 ->
 				let f1 = (try PMap.find n fl1 with Not_found -> error [has_no_field a n]) in

+ 82 - 46
typer.ml

@@ -139,7 +139,7 @@ let context warn =
 let field_type f =
 	match f.cf_params with
 	| [] -> f.cf_type 
-	| l -> apply_params l (List.map (fun _ -> mk_mono()) l) f.cf_type
+	| l -> monomorphs l f.cf_type
 
 let unify ctx t1 t2 p =
 	try
@@ -261,12 +261,7 @@ let rec load_normal_type ctx t p allow_no_params =
 		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))
 			| TEnumDecl e -> e.e_types , e.e_path , (fun t -> TEnum (e,t))
-			| TSignatureDecl s -> s.s_types , s.s_path , (fun t -> 
-				let fields = PMap.map (fun f -> 
-					{ f with cf_type = apply_params s.s_types t f.cf_type }
-				) s.s_fields in
-				TAnon (fields,t,Some (s_type_path s.s_path))
-			)
+			| TSignatureDecl s -> s.s_types , s.s_path , (fun t -> TSign(s,t))
 		in
 		if allow_no_params && t.tparams = [] then
 			f (List.map (fun (name,t) ->
@@ -300,21 +295,37 @@ and load_type ctx p t =
 	| TPParent t -> load_type ctx p t
 	| TPNormal t -> load_normal_type ctx t p false
 	| TPAnonymous l ->
-		let rec loop acc (n,t) =
-			let t = load_type ctx p t in
+		let rec loop acc (n,f,p) =
 			if PMap.mem n acc then error ("Duplicate field declaration : " ^ n) p;
+			let t , get, set = (match f with
+				| AFVar t ->
+					load_type ctx p t, NormalAccess, NormalAccess
+				| AFFun (tl,t) ->
+					let t = load_type ctx p t in
+					let args = List.map (fun (name,t) -> name , load_type ctx p t) tl in
+					TFun (args,t), NormalAccess, NormalAccess
+				| AFProp (t,i1,i2) ->					
+					let access m get = 
+						match m with
+						| "null" -> NoAccess
+						| "default" -> NormalAccess
+						| "dynamic" -> MethodAccess ((if get then "get_"  else "set_") ^ n)
+						| _ -> MethodAccess m
+					in
+					load_type ctx p t, access i1 true, access i2 false
+			) in
 			PMap.add n {
 				cf_name = n;
 				cf_type = t;
 				cf_public = true;
-				cf_get = NormalAccess;
-				cf_set = NormalAccess;
+				cf_get = get;
+				cf_set = set;
 				cf_params = [];
 				cf_expr = None;
 				cf_doc = None;
 			} acc
 		in
-		TAnon (List.fold_left loop PMap.empty l,[],None)
+		TAnon (List.fold_left loop PMap.empty l)		
 	| TPFunction (args,r) ->
 		match args with
 		| [TPNormal { tpackage = []; tparams = []; tname = "Void" }] ->
@@ -333,13 +344,14 @@ let rec reverse_type t =
 		TPNormal { tpackage = fst e.e_path; tname = snd e.e_path; tparams = List.map reverse_type params }
 	| TInst (c,params) ->
 		TPNormal { tpackage = fst c.cl_path; tname = snd c.cl_path; tparams = List.map reverse_type params }
+	| TSign (s,params) ->
+		TPNormal { tpackage = fst s.s_path; tname = snd s.s_path; tparams = List.map reverse_type params }
 	| TFun (params,ret) ->
 		TPFunction (List.map (fun (_,t) -> reverse_type t) params,reverse_type ret)
-	| TAnon (fields,[],None) ->
-		TPAnonymous (PMap.fold (fun f acc -> (f.cf_name , reverse_type f.cf_type) :: acc) fields [])
-	| TAnon (_,params,Some name) when name.[0] != '#' ->
-		let path = List.rev (ExtString.String.nsplit "." name) in
-		TPNormal { tpackage = List.rev (List.tl path); tname = List.hd path; tparams = List.map reverse_type params }
+	| TAnon fields ->
+		TPAnonymous (PMap.fold (fun f acc -> 			
+			(f.cf_name , AFVar (reverse_type f.cf_type), null_pos) :: acc
+		) fields [])
 	| TDynamic t2 ->
 		TPNormal { tpackage = []; tname = "Dynamic"; tparams = if t == t2 then [] else [reverse_type t2] }
 	| _ ->
@@ -517,10 +529,7 @@ let t_iterator ctx =
 		show();
 		if List.length s.s_types <> 1 then assert false;
 		let pt = mk_mono() in
-		let fields = PMap.map (fun f -> 
-			{ f with cf_type = apply_params s.s_types [pt] f.cf_type }
-		) s.s_fields in
-		TAnon (fields,[pt],Some "Iterator") , pt
+		apply_params s.s_types [pt] s.s_type, pt
 	| _ ->
 		assert false
 
@@ -569,8 +578,18 @@ let unify_call_params ctx t el args p =
 		| [] , [] ->
 			el
 		| [] , [(_,t)] ->
-			(match follow t with
-			| TAnon (_,[],Some "haxe.PosInfos") ->
+			let rec loop t =
+				match t with
+				| TMono r ->
+					(match !r with
+					| Some t -> loop t
+					| _ -> t)
+				| TLazy f ->
+					loop (!f())
+				| _ -> t
+			in
+			(match loop t with
+			| TSign ({ s_path = ["haxe"] , "PosInfos" },[]) ->
 				let infos = mk_infos ctx p [] in
 				let e = (!type_expr_ref) ctx ~need_val:true infos in
 				el @ [e]
@@ -700,26 +719,22 @@ let type_type ctx tpath p =
 			| TEnum _ -> mk_mono()
 			| _ -> t
 		) c.cl_types in
-		let fl = PMap.fold (fun f acc ->
-			PMap.add f.cf_name {
-				cf_name = f.cf_name;
-				cf_public = f.cf_public || pub;
-				cf_type = apply_params c.cl_types types f.cf_type;
-				cf_get = f.cf_get;
-				cf_set = f.cf_set;
-				cf_params = f.cf_params;
-				cf_doc = None;
-				cf_expr = None;
-			} acc
-		) c.cl_statics PMap.empty in
-		mk (TType (TClassDecl c)) (TAnon (fl,types,Some ("#" ^ s_type_path c.cl_path))) p
+		let s_tmp = {
+			s_path = fst c.cl_path, "#" ^ snd c.cl_path;
+			s_doc = None;
+			s_pos = c.cl_pos;
+			s_type = TAnon (if pub then PMap.map (fun f -> { f with cf_public = true }) c.cl_statics else c.cl_statics);
+			s_private = true;
+			s_types = c.cl_types;
+		} in
+		mk (TType (TClassDecl c)) (TSign (s_tmp,types)) p
 	| TEnumDecl e ->
 		let types = List.map (fun _ -> mk_mono()) e.e_types in
 		let fl = PMap.fold (fun f acc ->
 			PMap.add f.ef_name {
 				cf_name = f.ef_name;
 				cf_public = true;
-				cf_type = apply_params e.e_types types f.ef_type;
+				cf_type = f.ef_type;
 				cf_get = NormalAccess;
 				cf_set = NoAccess;
 				cf_doc = None;
@@ -727,7 +742,15 @@ let type_type ctx tpath p =
 				cf_params = [];
 			} acc
 		) e.e_constrs PMap.empty in
-		mk (TType (TEnumDecl e)) (TAnon (fl,types,Some ("#" ^ s_type_path e.e_path))) p
+		let s_tmp = {
+			s_path = fst e.e_path, "#" ^ snd e.e_path;
+			s_doc = None;
+			s_pos = e.e_pos;
+			s_type = TAnon fl;
+			s_private = true;
+			s_types = e.e_types;
+		} in
+		mk (TType (TEnumDecl e)) (TSign (s_tmp,types)) p
 	| TSignatureDecl _ ->
 		error (s_type_path tpath ^ " is not a value") p
 
@@ -852,7 +875,7 @@ let type_field ctx e i p get =
 			no_field())
 	| TDynamic t ->
 		AccExpr (mk (TField (e,i)) t p)
-	| TAnon (fl,_,_) ->
+	| TAnon fl ->
 		(try
 			let f = PMap.find i fl in
 			if not f.cf_public && not ctx.untyped then error ("Cannot access to private field " ^ i) p;
@@ -1257,7 +1280,7 @@ and type_expr ctx ?(need_val=true) (e,p) =
 			((f,e) :: l, PMap.add f cf acc)
 		in
 		let fields , types = List.fold_left loop ([],PMap.empty) fl in
-		mk (TObjectDecl fields) (TAnon (types,[],None)) p
+		mk (TObjectDecl fields) (TAnon types) p
 	| EArrayDecl el ->
 		let t , pt = t_array ctx in
 		let dyn = ref ctx.untyped in
@@ -1838,7 +1861,7 @@ let type_module ctx m tdecls loadp =
 				s_doc = doc;
 				s_private = priv;
 				s_types = [];
-				s_fields = PMap.empty;
+				s_type = mk_mono();
 			} in
 			decls := TSignatureDecl s :: !decls
 	) tdecls;
@@ -1917,12 +1940,25 @@ let type_module ctx m tdecls loadp =
 				) in
 				e.e_constrs <- PMap.add c { ef_name = c; ef_type = t; ef_pos = p; ef_doc = doc } e.e_constrs
 			) constrs
-		| ESignature (name,_,_,_,fields) ->
+		| ESignature (name,_,_,_,t) ->
 			let s = get_sign name in
-			let ctmp = mk_class s.s_path s.s_pos None false in
-			ctmp.cl_types <- s.s_types;
-			delays := !delays @ init_class ctx ctmp p [HInterface] fields;
-			s.s_fields <- ctmp.cl_fields
+			ctx.type_params <- s.s_types;
+			let rec loop t =
+				match t with
+				| TSign (s2,_) ->
+					if s == s2 then
+						error "Do you know you're not supposed to do that ?" p
+					else
+						loop s2.s_type
+				| TMono r ->
+					(match !r with
+					| None -> ()
+					| Some t -> loop t)
+				| _ -> ()
+			in
+			let t = load_type ctx p t in
+			loop t;
+			unify ctx s.s_type t p;
 	) tdecls;
 	(* PASS 3 : type checking, delayed until all modules and types are built *)
 	ctx.delays := !delays :: !(ctx.delays);