Explorar el Código

macro AST changes (added full class field definition)

Nicolas Cannasse hace 14 años
padre
commit
cb88382c0e
Se han modificado 11 ficheros con 241 adiciones y 160 borrados
  1. 12 16
      ast.ml
  2. 5 4
      codegen.ml
  3. 4 3
      genswf.ml
  4. 110 65
      interp.ml
  5. 20 22
      parser.ml
  6. 1 1
      std/Reflect.hx
  7. 21 8
      std/haxe/macro/Expr.hx
  8. 5 5
      std/haxe/macro/Type.hx
  9. 1 1
      typecore.ml
  10. 61 34
      typeload.ml
  11. 1 1
      typer.ml

+ 12 - 16
ast.ml

@@ -145,22 +145,18 @@ and type_param_or_const =
 	| TPType of complex_type
 	| TPConst of constant
 
-and anonymous_field =
-	| AFVar of complex_type
-	| AFProp of complex_type * string * string
-	| AFFun of (string * bool * complex_type) list * complex_type
-
 and complex_type =
 	| CTPath of type_path
 	| CTFunction of complex_type list * complex_type
-	| CTAnonymous of (string * bool option * anonymous_field * pos) list
+	| CTAnonymous of class_field list
 	| CTParent of complex_type
-	| CTExtend of type_path * (string * bool option * anonymous_field * pos) list
+	| CTExtend of type_path * class_field list
 
-type func = {
+and func = {
+	f_params : type_param list;
 	f_args : (string * bool * complex_type option * expr option) list;
 	f_type : complex_type option;
-	f_expr : expr;
+	f_expr : expr option;
 }
 
 and expr_def =
@@ -195,13 +191,13 @@ and expr_def =
 
 and expr = expr_def * pos
 
-type type_param = string * type_path list
+and type_param = string * complex_type list
 
-type documentation = string option
+and documentation = string option
 
-type metadata = (string * expr list * pos) list
+and metadata = (string * expr list * pos) list
 
-type access =
+and access =
 	| APublic
 	| APrivate
 	| AStatic
@@ -209,12 +205,12 @@ type access =
 	| ADynamic
 	| AInline
 
-type class_field_kind =
+and class_field_kind =
 	| FVar of complex_type option * expr option
-	| FFun of type_param list * func
+	| FFun of func
 	| FProp of string * string * complex_type
 
-type class_field = {
+and class_field = {
 	cff_name : string;
 	cff_doc : documentation;
 	cff_pos : pos;

+ 5 - 4
codegen.ml

@@ -109,14 +109,14 @@ let extend_remoting ctx c t p async prot =
 	ctx.com.package_rules <- rules;
 	let base_fields = [
 		{ cff_name = "__cnx"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = []; cff_kind = FVar (Some (CTPath { tpackage = ["haxe";"remoting"]; tname = if async then "AsyncConnection" else "Connection"; tparams = []; tsub = None }),None) };
-		{ cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun ([],{ f_args = ["c",false,None,None]; f_type = None; f_expr = (EBinop (OpAssign,(EConst (Ident "__cnx"),p),(EConst (Ident "c"),p)),p) }) };
+		{ cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun { f_args = ["c",false,None,None]; f_type = None; f_expr = Some (EBinop (OpAssign,(EConst (Ident "__cnx"),p),(EConst (Ident "c"),p)),p); f_params = [] } };
 	] in
 	let tvoid = CTPath { tpackage = []; tname = "Void"; tparams = []; tsub = None } in
 	let build_field is_public acc f =
 		if f.cff_name = "new" then
 			acc
 		else match f.cff_kind with
-		| FFun (pl,fd) when (is_public || List.mem APublic f.cff_access) && not (List.mem AStatic f.cff_access) ->
+		| FFun fd when (is_public || List.mem APublic f.cff_access) && not (List.mem AStatic f.cff_access) ->
 			if List.exists (fun (_,_,t,_) -> t = None) fd.f_args then error ("Field " ^ f.cff_name ^ " type is not complete and cannot be used by RemotingProxy") p;
 			let eargs = [EArrayDecl (List.map (fun (a,_,_,_) -> (EConst (Ident a),p)) fd.f_args),p] in
 			let ftype = (match fd.f_type with Some (CTPath { tpackage = []; tname = "Void" }) -> None | _ -> fd.f_type) in
@@ -136,11 +136,12 @@ let extend_remoting ctx c t p async prot =
 			in
 			let expr = if async || ftype = None then expr else (EReturn (Some expr),p) in
 			let fd = {
+				f_params = fd.f_params;
 				f_args = fargs;
 				f_type = if async then None else ftype;
-				f_expr = (EBlock [expr],p);
+				f_expr = Some (EBlock [expr],p);
 			} in
-			{ cff_name = f.cff_name; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun (pl,fd) } :: acc
+			{ cff_name = f.cff_name; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = [APublic]; cff_kind = FFun fd } :: acc
 		| _ -> acc
 	in
 	let decls = List.map (fun d ->

+ 4 - 3
genswf.ml

@@ -319,12 +319,13 @@ let build_class com c file =
 					args @ List.map (fun _ -> incr pn; ("p" ^ string_of_int !pn,true,Some (make_type None),None)) [1;2;3;4;5]
 				else args in
 				let f = {
+					f_params = [];
 					f_args = args;
 					f_type = Some (make_type t.hlmt_ret);
-					f_expr = (EBlock [],pos)
+					f_expr = None;
 				} in
 				cf.cff_meta <- mk_meta();
-				cf.cff_kind <- FFun ([],f);
+				cf.cff_kind <- FFun f;
 				cf :: acc
 			| MK3Getter ->
 				Hashtbl.add getters (name,stat) m.hlm_type.hlmt_ret;
@@ -387,7 +388,7 @@ let build_class com c file =
 				| FVar (Some (CTPath { tpackage = []; tname = ("String" | "Int" | "UInt") as tname }),None) when List.mem AStatic f.cff_access ->
 					if !real_type = "" then real_type := tname else if !real_type <> tname then raise Exit;
 					(f.cff_name,None,[],[],pos) :: loop l
-				| FFun (_,{ f_args = [] }) when f.cff_name = "new" -> loop l
+				| FFun { f_args = [] } when f.cff_name = "new" -> loop l
 				| _ -> raise Exit
 		in
 		(match path.tpackage, path.tname with

+ 110 - 65
interp.ml

@@ -2391,6 +2391,7 @@ type enum_index =
 	| IFieldKind
 	| IMethodKind
 	| IVarAccess
+	| IAccess
 
 let enum_name = function
 	| IExpr -> "ExprDef"
@@ -2404,6 +2405,7 @@ let enum_name = function
 	| IFieldKind -> "FieldKind"
 	| IMethodKind -> "MethodKind"
 	| IVarAccess -> "VarAccess"
+	| IAccess -> "Access"
 
 let init ctx =
 	let enums = [IExpr;IBinop;IUnop;IConst;ITParam;ICType;IField;IType;IFieldKind;IMethodKind;IVarAccess] in
@@ -2542,23 +2544,39 @@ and encode_tparam = function
 	| TPType t -> enc_enum ITParam 0 [encode_type t]
 	| TPConst c -> enc_enum ITParam 1 [encode_const c]
 
-and encode_field (f,pub,field,pos) =
-	let tag, pl = match field with
-		| AFVar t -> 0, [encode_type t]
-		| AFProp (t,get,set) -> 1, [encode_type t; enc_string get; enc_string set]
-		| AFFun (pl,t) -> 2, [enc_array (List.map (fun (n,opt,t) ->
-			enc_obj [
-				"name", enc_string n;
-				"opt", VBool opt;
-				"type", encode_type t
-			]
-		) pl); encode_type t]
+and encode_access a =
+	let tag = match a with
+		| APublic -> 0
+		| APrivate -> 1
+		| AStatic -> 2
+		| AOverride -> 3
+		| ADynamic -> 4
+		| AInline -> 5
+	in
+	enc_enum IAccess tag []
+
+and encode_meta_content m =
+	enc_array (List.map (fun (m,ml,p) ->
+		enc_obj [
+			"name", enc_string m;
+			"params", enc_array (List.map encode_expr ml);
+			"pos", encode_pos p;
+		]
+	) m)
+
+and encode_field (f:class_field) =
+	let tag, pl = match f.cff_kind with
+		| FVar (t,e) -> 0, [null encode_type t; null encode_expr e]
+		| FFun f -> 1, [encode_fun f]
+		| FProp (get,set, t) -> 2, [enc_string get; enc_string set; encode_type t]
 	in
 	enc_obj [
-		"name",enc_string f;
-		"isPublic",null (fun b -> VBool b) pub;
-		"type", enc_enum IField tag pl;
-		"pos", encode_pos pos;
+		"name",enc_string f.cff_name;
+		"doc", null enc_string f.cff_doc;
+		"pos", encode_pos f.cff_pos;
+		"kind", enc_enum IField tag pl;
+		"meta", encode_meta_content f.cff_meta;
+		"access", enc_array (List.map encode_access f.cff_access);
 	]
 
 and encode_type t =
@@ -2576,7 +2594,27 @@ and encode_type t =
 	in
 	enc_enum ICType tag pl
 
-let encode_expr e =
+and encode_fun f =
+	enc_obj [
+		"params", enc_array (List.map (fun (n,cl) ->
+			enc_obj [
+				"name", enc_string n;
+				"constraints", enc_array (List.map encode_type cl);
+			]
+		) f.f_params);
+		"args", enc_array (List.map (fun (n,opt,t,e) ->
+			enc_obj [
+				"name", enc_string n;
+				"opt", VBool opt;
+				"type", null encode_type t;
+				"value", null encode_expr e;
+			]
+		) f.f_args);
+		"ret", null encode_type f.f_type;
+		"expr", null encode_expr f.f_expr
+	]
+
+and encode_expr e =
 	let rec loop (e,p) =
 		let tag, pl = match e with
 			| EConst c ->
@@ -2613,19 +2651,7 @@ let encode_expr e =
 					]
 				) vl)]
 			| EFunction (name,f) ->
-				12, [enc_obj [
-					"name", null enc_string name;
-					"args", enc_array (List.map (fun (n,opt,t,e) ->
-						enc_obj [
-							"name", enc_string n;
-							"opt", VBool opt;
-							"type", null encode_type t;
-							"value", null loop e;
-						]
-					) f.f_args);
-					"ret", null encode_type f.f_type;
-					"expr", loop f.f_expr
-				]]
+				12, [null enc_string name; encode_fun f]
 			| EBlock el ->
 				13, [enc_array (List.map loop el)]
 			| EFor (v,e,eloop) ->
@@ -2773,26 +2799,52 @@ and decode_tparam v =
 	| 1,[c] -> TPConst (decode_const c)
 	| _ -> raise Invalid_expr
 
+and decode_fun v =
+	{
+		f_params = List.map (fun v ->
+			(dec_string (field v "name"), List.map decode_ctype (dec_array (field v "constraints")))
+		) (dec_array (field v "params"));
+		f_args = List.map (fun o ->
+			(dec_string (field o "name"),dec_bool (field o "opt"),opt decode_ctype (field o "type"),opt decode_expr (field o "value"))
+		) (dec_array (field v "args"));
+		f_type = opt decode_ctype (field v "ret");
+		f_expr = opt decode_expr (field v "expr");
+	}
+
+and decode_access v =
+	match decode_enum v with
+	| 0, [] -> APublic
+	| 1, [] -> APrivate
+	| 2, [] -> AStatic
+	| 3, [] -> AOverride
+	| 4, [] -> ADynamic
+	| 5, [] -> AInline
+	| _ -> raise Invalid_expr
+
+and decode_meta_content v =
+	List.map (fun v ->
+		(dec_string (field v "name"), List.map decode_expr (dec_array (field v "params")), decode_pos (field v "pos"))
+	) (dec_array v)
+
 and decode_field v =
-	let ftype = match decode_enum (field v "type") with
-		| 0, [t] ->
-			AFVar (decode_ctype t)
-		| 1, [t;get;set] ->
-			AFProp (decode_ctype t, dec_string get, dec_string set)
-		| 2, [pl;t] ->
-			let pl = List.map (fun p ->
-				(dec_string (field p "name"),dec_bool (field p "opt"),decode_ctype (field p "type"))
-			) (dec_array pl) in
-			AFFun (pl, decode_ctype t)
+	let fkind = match decode_enum (field v "kind") with
+		| 0, [t;e] ->
+			FVar (opt decode_ctype t, opt decode_expr e)
+		| 1, [f] ->
+			FFun (decode_fun f)
+		| 2, [get;set; t] ->
+			FProp (dec_string get, dec_string set, decode_ctype t)
 		| _ ->
 			raise Invalid_expr
 	in
-	(
-		dec_string (field v "name"),
-		opt dec_bool (field v "isPublic"),
-		ftype,
-		decode_pos (field v "pos")
-	)
+	{
+		cff_name = dec_string (field v "name");
+		cff_doc = opt dec_string (field v "doc");
+		cff_pos = decode_pos (field v "pos");
+		cff_kind = fkind;
+		cff_access = List.map decode_access (dec_array (field v "access"));
+		cff_meta = decode_meta_content (field v "meta");
+	}
 
 and decode_ctype t =
 	match decode_enum t with
@@ -2842,15 +2894,8 @@ let decode_expr v =
 			EVars (List.map (fun v ->
 				(dec_string (field v "name"),opt decode_ctype (field v "type"),opt loop (field v "expr"))
 			) (dec_array vl))
-		| 12, [f] ->
-			let ft = {
-				f_args = List.map (fun o ->
-					(dec_string (field o "name"),dec_bool (field o "opt"),opt decode_ctype (field o "type"),opt loop (field o "value"))
-				) (dec_array (field f "args"));
-				f_type = opt decode_ctype (field f "ret");
-				f_expr = loop (field f "expr");
-			} in
-			EFunction (opt dec_string (field f "name"),ft)
+		| 12, [fname;f] ->
+			EFunction (opt dec_string fname,decode_fun f)
 		| 13, [el] ->
 			EBlock (List.map loop (dec_array el))
 		| 14, [v;e1;e2] ->
@@ -2925,13 +2970,7 @@ let encode_meta m set =
 	let meta = ref m in
 	enc_obj [
 		"get", VFunction (Fun0 (fun() ->
-			enc_array (List.map (fun (m,ml,p) ->
-				enc_obj [
-					"name", enc_string m;
-					"params", enc_array (List.map encode_expr ml);
-					"pos", encode_pos p;
-				]
-			) (!meta))
+			encode_meta_content (!meta)
 		));
 		"add", VFunction (Fun3 (fun k vl p ->
 			(try
@@ -3197,14 +3236,20 @@ let rec make_ast e =
 			CTFunction (List.map (fun (_,_,t) -> mk_type t) args, mk_type ret)			
 		| TAnon a ->
 			CTAnonymous (PMap.foldi (fun _ f acc -> 
-				(f.cf_name,None,AFVar (mk_type f.cf_type), e.epos) :: acc
+				{
+					cff_name = f.cf_name;
+					cff_kind = FVar (mk_ot f.cf_type,None);
+					cff_pos = e.epos;
+					cff_doc = f.cf_doc;
+					cff_meta = f.cf_meta;
+					cff_access = [];
+				} :: acc
 			) a.a_fields [])
 		| (TDynamic t2) as t ->
 			tpath ([],"Dynamic") (if t == t_dynamic then [] else [mk_type t2])
 		| TLazy f ->
 			mk_type ((!f)())
-	in
-	let mk_ot t =
+	and mk_ot t =
 		match follow t with
 		| TMono _ -> None
 		| _ -> Some (mk_type t)
@@ -3227,7 +3272,7 @@ let rec make_ast e =
 	| TUnop (op,p,e) -> EUnop (op,p,make_ast e)
 	| TFunction f -> 
 		let arg (n,c,t) = n, false, mk_ot t, (match c with None -> None | Some c -> Some (EConst (mk_const c),e.epos)) in
-		EFunction (None,{ f_args = List.map arg f.tf_args; f_type = mk_ot f.tf_type; f_expr = make_ast f.tf_expr })
+		EFunction (None,{ f_params = []; f_args = List.map arg f.tf_args; f_type = mk_ot f.tf_type; f_expr = Some (make_ast f.tf_expr) })
 	| TVars vl ->
 		EVars (List.map (fun (n,t,e) -> n, mk_ot t, eopt e) vl)
 	| TBlock el -> EBlock (List.map make_ast el)

+ 20 - 22
parser.ml

@@ -290,9 +290,9 @@ and parse_complex_type = parser
 			| [< '(Binop OpGt,_); t = parse_type_path; '(Comma,_); s >] ->
 				(match s with parser
 				| [< name = any_ident; l = parse_type_anonymous_resume name >] -> CTExtend (t,l)
-				| [< l = plist (parse_signature_field None); '(BrClose,_) >] -> CTExtend (t,l)
+				| [< l = parse_class_field_resume; '(BrClose,_) >] -> CTExtend (t,l)
 				| [< >] -> serror())
-			| [< l = plist (parse_signature_field None); '(BrClose,_) >] -> CTAnonymous l
+			| [< l = parse_class_field_resume; '(BrClose,_) >] -> CTAnonymous l
 			| [< >] -> serror()
 		) in
 		parse_complex_type_next t s
@@ -354,7 +354,14 @@ and parse_complex_type_next t = parser
 
 and parse_type_anonymous_resume name = parser
 	| [< '(DblDot,p); t = parse_complex_type; s >] ->
-		(name, None, AFVar t, p) ::
+		{
+			cff_name = name;
+			cff_meta = [];
+			cff_access = [];
+			cff_doc = None;
+			cff_kind = FVar (Some t,None);
+			cff_pos = p;
+		} ::
 		match s with parser
 		| [< '(BrClose,_) >] -> []
 		| [< '(Comma,_) >] ->
@@ -395,17 +402,18 @@ and parse_class_field s =
 				) in
 				name, punion p1 p2, FVar (t,e))
 		| [< '(Kwd Function,p1); name = parse_fun_name; pl = parse_constraint_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
-			let e = (match s with parser
-				| [< e = toplevel_expr >] -> e
-				| [< '(Semicolon,p) >] -> (EBlock [],p)
+			let e, p2 = (match s with parser
+				| [< e = toplevel_expr >] -> Some e, pos e
+				| [< '(Semicolon,p) >] -> None, p
 				| [< >] -> serror()
 			) in
 			let f = {
+				f_params = pl;
 				f_args = al;
 				f_type = t;
 				f_expr = e;
 			} in
-			name, punion p1 (pos e), FFun (pl,f)
+			name, punion p1 p2, FFun f
 		| [< >] ->
 			if al = [] then raise Stream.Failure else serror()
 		) in
@@ -418,17 +426,6 @@ and parse_class_field s =
 			cff_kind = k;
 		}
 
-and parse_signature_field flag = parser
-	| [< '(Kwd Var,p1); name = any_ident; s >] ->
-		(match s with parser
-		| [< '(DblDot,_); t = parse_complex_type; p2 = semicolon >] -> (name,flag,AFVar t,punion p1 p2)
-		| [< '(POpen,_); i1 = property_ident; '(Comma,_); i2 = property_ident; '(PClose,_); '(DblDot,_); t = parse_complex_type; p2 = semicolon >] -> (name,flag,AFProp (t,i1,i2),punion p1 p2)
-		| [< >] -> serror())
-	| [< '(Kwd Function,p1); name = any_ident; '(POpen,_); al = psep Comma parse_fun_param_type; '(PClose,_); '(DblDot,_); t = parse_complex_type; p2 = semicolon >] ->
-		(name,flag,AFFun (al,t),punion p1 p2)
-	| [< '(Kwd Private,_) when flag = None; s >] -> parse_signature_field (Some false) s
-	| [< '(Kwd Public,_) when flag = None; s >] -> parse_signature_field (Some true) s
-
 and parse_cf_rights allow_static l = parser
 	| [< '(Kwd Static,_) when allow_static; l = parse_cf_rights false (AStatic :: l) >] -> l
 	| [< '(Kwd Public,_) when not(List.mem APublic l || List.mem APrivate l); l = parse_cf_rights allow_static (APublic :: l) >] -> l
@@ -464,8 +461,8 @@ and parse_constraint_param = parser
 		match s with parser
 		| [< '(DblDot,_); s >] ->
 			(match s with parser
-			| [< '(POpen,_); l = psep Comma parse_type_path; '(PClose,_) >] -> (name,l)
-			| [< t = parse_type_path >] -> (name,[t])
+			| [< '(POpen,_); l = psep Comma parse_complex_type; '(PClose,_) >] -> (name,l)
+			| [< t = parse_complex_type >] -> (name,[t])
 			| [< >] -> serror())
 		| [< >] -> (name,[])
 
@@ -557,12 +554,13 @@ and expr = parser
 		| [< >] -> serror())
 	| [< '(POpen,p1); e = expr; '(PClose,p2); s >] -> expr_next (EParenthesis e, punion p1 p2) s
 	| [< '(BkOpen,p1); l = parse_array_decl; '(BkClose,p2); s >] -> expr_next (EArrayDecl l, punion p1 p2) s
-	| [< '(Kwd Function,p1); name = popt any_ident; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
+	| [< '(Kwd Function,p1); name = popt any_ident; pl = parse_constraint_params; '(POpen,_); al = psep Comma parse_fun_param; '(PClose,_); t = parse_type_opt; s >] ->
 		let make e =
 			let f = {
+				f_params = pl;
 				f_type = t;
 				f_args = al;
-				f_expr = e;
+				f_expr = Some e;
 			} in
 			EFunction (name,f), punion p1 (pos e)
 		in

+ 1 - 1
std/Reflect.hx

@@ -43,7 +43,7 @@ extern class Reflect {
 	/**
 		Set an object field value.
 	**/
-	public inline static function setField( o : Dynamic, field : String, value : Dynamic ) : Void;
+	public static function setField( o : Dynamic, field : String, value : Dynamic ) : Void;
 
 	/**
 		Call a method with the given object and arguments.

+ 21 - 8
std/haxe/macro/Expr.hx

@@ -98,7 +98,7 @@ enum ExprDef {
 	ENew( t : TypePath, params : Array<Expr> );
 	EUnop( op : Unop, postFix : Bool, e : Expr );
 	EVars( vars : Array<{ name : String, type : Null<ComplexType>, expr : Null<Expr> }> );
-	EFunction( f : Function );
+	EFunction( name : Null<String>, f : Function );
 	EBlock( exprs : Array<Expr> );
 	EFor( v : String, it : Expr, expr : Expr );
 	EIf( econd : Expr, eif : Expr, eelse : Null<Expr> );
@@ -137,10 +137,10 @@ enum TypeParam {
 }
 
 typedef Function = {
-	var name : Null<String>;
 	var args : Array<FunctionArg>;
 	var ret : Null<ComplexType>;
-	var expr : Expr;
+	var expr : Null<Expr>;
+	var params : Array<{ name : String, constraints : Array<ComplexType> }>;
 }
 
 typedef FunctionArg = {
@@ -150,16 +150,29 @@ typedef FunctionArg = {
 	var value : Null<Expr>;
 }
 
+typedef Metadata = Array<{ name : String, params : Array<Expr>, pos : Position }>;
+
 typedef Field = {
 	var name : String;
-	var isPublic : Null<Bool>;
-	var type : FieldType;
+	var doc : Null<String>;
+	var access : Array<Access>;
+	var kind : FieldType;
 	var pos : Position;
+	var meta : Metadata;
+}
+
+enum Access {
+	APublic;
+	APrivate;
+	AStatic;
+	AOverride;
+	ADynamic;
+	AInline;
 }
 
 enum FieldType {
-	FVar( t : ComplexType );
-	FProp( t : ComplexType, get : String, set : String );
-	FFun( args : Array<{ name : String, opt : Bool, type : ComplexType }>, ret : ComplexType );
+	FVar( t : Null<ComplexType>, e : Null<Expr> );
+	FFun( f : Function );
+	FProp( get : String, set : String, t : ComplexType );
 }
 

+ 5 - 5
std/haxe/macro/Type.hx

@@ -51,7 +51,7 @@ typedef BaseType = {
 	var isPrivate : Bool;
 	var isExtern : Bool;
 	var params : Array<{ name : String, t : Type }>;
-	var meta : Metadata;
+	var meta : MetaAccess;
 	function exclude() : Void;
 }
 
@@ -60,7 +60,7 @@ typedef ClassField = {
 	var type : Type;
 	var isPublic : Bool;
 	var params : Array<{ name : String, t : Type }>;
-	var meta : Metadata;
+	var meta : MetaAccess;
 	var kind : FieldKind;
 	var expr : Null<TypedExpr>;
 	var pos : Expr.Position;
@@ -83,7 +83,7 @@ typedef EnumField = {
 	var name : String;
 	var type : Type;
 	var pos : Expr.Position;
-	var meta : Metadata;
+	var meta : MetaAccess;
 	var index : Int;
 }
 
@@ -96,8 +96,8 @@ typedef DefType = {> BaseType,
 	var type : Type;
 }
 
-typedef Metadata = {
-	function get() : Array<{ name : String, params : Array<Expr>, pos : Expr.Position }>;
+typedef MetaAccess = {
+	function get() : Expr.Metadata;
 	function add( name : String, params : Array<Expr>, pos : Expr.Position ) : Void;
 	function remove( name : String ) : Void;
 	function has( name : String ) : Bool;

+ 1 - 1
typecore.ml

@@ -29,7 +29,7 @@ type typer_globals = {
 	types_module : (path, path) Hashtbl.t;
 	modules : (path , module_def) Hashtbl.t;
 	mutable delayed : (unit -> unit) list;
-	constructs : (path , Ast.access list * Ast.type_param list * Ast.func) Hashtbl.t;
+	constructs : (path , Ast.access list * Ast.func) Hashtbl.t;
 	doinline : bool;
 	mutable core_api : typer option;
 	mutable macros : ((unit -> unit) * typer) option;

+ 61 - 34
typeload.ml

@@ -199,16 +199,37 @@ and load_complex_type ctx p t =
 			loop (load_instance ctx t p false)
 		| _ -> assert false)
 	| CTAnonymous l ->
-		let rec loop acc (n,pub,f,p) =
+		let rec loop acc f =
+			let n = f.cff_name in
+			let p = f.cff_pos in
 			if PMap.mem n acc then error ("Duplicate field declaration : " ^ n) p;
-			let t , access = (match f with
-				| AFVar t ->
-					load_complex_type ctx p t, Var { v_read = AccNormal; v_write = AccNormal }
-				| AFFun (tl,t) ->
-					let t = load_complex_type ctx p t in
-					let args = List.map (fun (name,o,t) -> name , o, load_complex_type ctx p t) tl in
-					TFun (args,t), Method MethNormal
-				| AFProp (t,i1,i2) ->
+			let topt = function
+				| None -> error ("Explicit type required for field " ^ n) p
+				| Some t -> load_complex_type ctx p t
+			in
+			let no_expr = function
+				| None -> ()
+				| Some (_,p) -> error "Expression not allowed here" p
+			in
+			let pub = ref true in
+			let dyn = ref false in
+			List.iter (fun a ->
+				match a with
+				| APublic -> ()
+				| APrivate -> pub := false;
+				| ADynamic when (match f.cff_kind with FFun _ -> true | _ -> false) -> dyn := true
+				| AStatic | AOverride | AInline | ADynamic -> error ("Invalid access " ^ Ast.s_access a) p
+			) f.cff_access;
+			let t , access = (match f.cff_kind with
+				| FVar (t, e) ->
+					no_expr e;
+					topt t, Var { v_read = AccNormal; v_write = AccNormal }
+				| FFun f ->
+					if f.f_params <> [] then error "Type parameters are not allowed in structures" p;
+					no_expr f.f_expr;
+					let args = List.map (fun (name,o,t,e) -> no_expr e; name, o, topt t) f.f_args in
+					TFun (args,topt f.f_type), Method (if !dyn then MethDynamic else MethNormal)
+				| FProp (i1,i2,t) ->
 					let access m get =
 						match m with
 						| "null" -> AccNo
@@ -223,12 +244,12 @@ and load_complex_type ctx p t =
 				cf_name = n;
 				cf_type = t;
 				cf_pos = p;
-				cf_public = (match pub with None -> true | Some p -> p);
+				cf_public = !pub;
 				cf_kind = access;
 				cf_params = [];
 				cf_expr = None;
-				cf_doc = None;
-				cf_meta = no_meta;
+				cf_doc = f.cff_doc;
+				cf_meta = f.cff_meta;
 			} acc
 		in
 		mk_anon (List.fold_left loop PMap.empty l)
@@ -491,7 +512,7 @@ let type_type_params ctx path get_params p (n,flags) =
 		let r = exc_protect (fun r ->
 			r := (fun _ -> t);
 			let ctx = { ctx with type_params = ctx.type_params @ get_params() } in
-			set_heritance ctx c (List.map (fun t -> HImplements t) flags) p;
+			set_heritance ctx c (List.map (fun t -> match t with CTPath t -> HImplements t | _ -> error "Unsupported type constraint" p) flags) p;
 			t
 		) in
 		delay ctx (fun () -> ignore(!r()));
@@ -521,7 +542,7 @@ let type_function ctx args ret static constr f p =
 	ctx.in_constructor <- constr;
 	ctx.ret <- ret;
 	ctx.opened <- [];
-	let e = type_expr ctx f.f_expr false in
+	let e = type_expr ctx (match f.f_expr with None -> error "Function body required" p | Some e -> e) false in
 	let rec loop e =
 		match e.eexpr with
 		| TReturn (Some _) -> raise Exit
@@ -619,7 +640,7 @@ let patch_class ctx c fields =
 			| f :: l ->
 				(* patch arguments types *)
 				(match f.cff_kind with
-				| FFun (pl,ff) ->
+				| FFun ff ->
 					let param ((n,opt,t,e) as p) =
 						try
 							let t2 = (try Hashtbl.find h (("$" ^ f.cff_name ^ "__" ^ n),false) with Not_found -> Hashtbl.find h (("$" ^ n),false)) in
@@ -627,7 +648,7 @@ let patch_class ctx c fields =
 						with Not_found ->
 							p
 					in
-					f.cff_kind <- FFun (pl,{ ff with f_args = List.map param ff.f_args })
+					f.cff_kind <- FFun { ff with f_args = List.map param ff.f_args }
 				| _ -> ());
 				(* other patches *)
 				match (try Some (Hashtbl.find h (f.cff_name,List.mem AStatic f.cff_access)) with Not_found -> None) with
@@ -641,7 +662,7 @@ let patch_class ctx c fields =
 						f.cff_kind <- match f.cff_kind with
 						| FVar (_,e) -> FVar (Some t,e)
 						| FProp (get,set,_) -> FProp (get,set,t)
-						| FFun (pl,f) -> FFun (pl,{ f with f_type = Some t }));
+						| FFun f -> FFun { f with f_type = Some t });
 					loop (f :: acc) l
 		in
 		List.rev (loop [] fields)
@@ -685,7 +706,7 @@ let init_class ctx c p herits fields =
 			List.map (fun (e,p) ->
 				let n, k = (match e with
 				| EVars [v,t,e] -> v, FVar (t,e)
-				| EFunction (Some n,f) -> (if n = "__new__" then "new" else n), FFun ([],f)
+				| EFunction (Some n,f) -> (if n = "__new__" then "new" else n), FFun f
 				| _ -> error "Class build expression should be a single variable or a named function" p
 				) in
 				let accesses = [APublic; APrivate; AStatic; AOverride; ADynamic; AInline] in
@@ -908,14 +929,14 @@ let init_class ctx c p herits fields =
 					bind_type cf r (snd e) false
 			) in
 			f, false, cf, delay
-		| FFun (fparams,fd) ->
+		| FFun fd ->
 			let params = ref [] in
 			params := List.map (fun (n,flags) ->
 				match flags with
 				| [] ->
 					type_type_params ctx ([],name) (fun() -> !params) p (n,[])
 				| _ -> error "This notation is not allowed because it can't be checked" p
-			) fparams;
+			) fd.f_params;
 			let params = !params in
 			if inline && c.cl_interface then error "You can't declare inline methods in interfaces" p;
 			let is_macro = (is_macro && stat) || has_meta ":macro" f.cff_meta in
@@ -933,6 +954,7 @@ let init_class ctx c p herits fields =
 			else if ctx.in_macro then
 				let texpr = CTPath { tpackage = ["haxe";"macro"]; tname = "Expr"; tparams = []; tsub = None } in
 				{
+					f_params = fd.f_params;
 					f_type = (match fd.f_type with None -> Some texpr | t -> t);
 					f_args = List.map (fun (a,o,t,e) -> a,o,(match t with None -> Some texpr | _ -> t),e) fd.f_args;
 					f_expr = fd.f_expr;
@@ -945,9 +967,10 @@ let init_class ctx c p herits fields =
 					| _ -> tdyn
 				in
 				{
+					f_params = fd.f_params;
 					f_type = (match fd.f_type with Some (CTPath t) -> to_dyn t | _ -> tdyn);
 					f_args = List.map (fun (a,o,t,_) -> a,o,(match t with Some (CTPath t) -> to_dyn t | _ -> tdyn),None) fd.f_args;
-					f_expr = (EBlock [],p)
+					f_expr = None;
 				}
 			in
 			let parent = (if not stat then get_parent c name else None) in
@@ -967,7 +990,7 @@ let init_class ctx c p herits fields =
 			let t = TFun (fun_args args,ret) in
 			let constr = (name = "new") in
 			if constr && c.cl_interface then error "An interface cannot have a constructor" p;
-			if c.cl_interface && not stat && (match fd.f_expr with EBlock [] , _ -> false | _ -> true) then error "An interface method cannot have a body" p;
+			if c.cl_interface && not stat && fd.f_expr <> None then error "An interface method cannot have a body" p;
 			if constr then (match fd.f_type with
 				| None | Some (CTPath { tpackage = []; tname = "Void" }) -> ()
 				| _ -> error "A class constructor can't have a return value" p
@@ -1014,7 +1037,7 @@ let init_class ctx c p herits fields =
 			end else if ((c.cl_extern && not inline) || c.cl_interface) && cf.cf_name <> "__init__" then
 				(fun() -> ())
 			else
-				bind_type cf r (snd fd.f_expr) is_macro
+				bind_type cf r (match fd.f_expr with Some e -> snd e | None -> f.cff_pos) is_macro
 			in
 			f, constr, cf, delay
 		| FProp (get,set,t) ->
@@ -1127,11 +1150,11 @@ let init_class ctx c p herits fields =
 			| Some (csuper,_) ->
 				match define_constructor ctx csuper with
 				| None -> None
-				| Some (acc,pl,f) as infos ->
+				| Some (acc,f) as infos ->
 					let p = c.cl_pos in
 					let esuper = (ECall ((EConst (Ident "super"),p),List.map (fun (n,_,_,_) -> (EConst (Ident n),p)) f.f_args),p) in
 					let acc = (if csuper.cl_extern && acc = [] then [APublic] else acc) in
-					let fnew = { f with f_expr = esuper; f_args = List.map (fun (a,opt,t,def) ->
+					let fnew = { f with f_expr = Some esuper; f_args = List.map (fun (a,opt,t,def) ->
 						(*
 							we are removing the type and letting the type inference
 							work because the current package is not the same as the superclass one
@@ -1145,12 +1168,16 @@ let init_class ctx c p herits fields =
 							| CTPath t -> is_qual_name t
 							| CTParent t -> is_qualified t
 							| CTFunction (tl,t) -> List.for_all is_qualified tl && is_qualified t
-							| CTAnonymous fl -> List.for_all (fun (_,_,f,_) -> is_qual_field f) fl
-							| CTExtend (t,fl) -> is_qual_name t && List.for_all (fun (_,_,f,_) -> is_qual_field f) fl
-						and is_qual_field = function
-							| AFVar t -> is_qualified t
-							| AFProp (t,_,_) -> is_qualified t
-							| AFFun (pl,t) -> List.for_all (fun (_,_,t) -> is_qualified t) pl && is_qualified t
+							| CTAnonymous fl -> List.for_all is_qual_field fl
+							| CTExtend (t,fl) -> is_qual_name t && List.for_all is_qual_field fl
+						and is_qual_field f =
+							match f.cff_kind with
+							| FVar (t,_) -> is_qual_opt t
+							| FProp (_,_,t) -> is_qualified t
+							| FFun f -> List.for_all (fun (_,_,t,_) -> is_qual_opt t) f.f_args && is_qual_opt f.f_type
+						and is_qual_opt = function
+							| None -> true
+							| Some t -> is_qualified t
 						and is_qual_name t =
 							match t.tpackage with
 							| [] -> t.tname = "Dynamic" && List.for_all is_qual_param t.tparams
@@ -1165,9 +1192,9 @@ let init_class ctx c p herits fields =
 						) in
 						a,opt,t,def
 					) f.f_args } in
-					let _, _, cf, delayed = loop_cf { cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = acc; cff_kind = FFun (pl,fnew) } in
+					let _, _, cf, delayed = loop_cf { cff_name = "new"; cff_pos = p; cff_doc = None; cff_meta = []; cff_access = acc; cff_kind = FFun fnew } in
 					c.cl_constructor <- Some cf;
-					Hashtbl.add ctx.g.constructs c.cl_path (acc,pl,f);
+					Hashtbl.add ctx.g.constructs c.cl_path (acc,f);
 					delay ctx delayed;
 					infos
 	in
@@ -1214,7 +1241,7 @@ let type_module ctx m tdecls loadp =
 			(* store the constructor for later usage *)
 			List.iter (fun cf ->
 				match cf with
-				| { cff_name = "new"; cff_kind = FFun (pl,f) } -> Hashtbl.add ctx.g.constructs path (cf.cff_access,pl,f)
+				| { cff_name = "new"; cff_kind = FFun f } -> Hashtbl.add ctx.g.constructs path (cf.cff_access,f)
 				| _ -> ()
 			) d.d_data;
 			decls := TClassDecl c :: !decls

+ 1 - 1
typer.ml

@@ -1966,7 +1966,7 @@ let make_macro_api ctx p =
 			let head = "class X{static function main() " in
 			let head = (if p.pmin > String.length head then head ^ String.make (p.pmin - String.length head) ' ' else head) in
 			match parse_string ctx (head ^ s ^ "}") p with
-			| EClass { d_data = [{ cff_name = "main"; cff_kind = FFun (_,{ f_expr = e }) }]} -> e
+			| EClass { d_data = [{ cff_name = "main"; cff_kind = FFun { f_expr = Some e } }]} -> e
 			| _ -> assert false
 		);
 		Interp.typeof = (fun e ->