Browse Source

Merge branch 'tmeta' into development

Simon Krajewski 12 năm trước cách đây
mục cha
commit
1b2b31db36
21 tập tin đã thay đổi với 84 bổ sung44 xóa
  1. 11 0
      ast.ml
  2. 1 1
      codegen.ml
  3. 2 0
      common.ml
  4. 3 0
      genas3.ml
  5. 8 6
      gencommon.ml
  6. 8 7
      gencpp.ml
  7. 3 1
      gencs.ml
  8. 3 1
      genjava.ml
  9. 3 0
      genjs.ml
  10. 2 0
      genneko.ml
  11. 8 0
      genphp.ml
  12. 1 1
      genswf8.ml
  13. 6 6
      genswf9.ml
  14. 2 10
      genxml.ml
  15. 3 2
      interp.ml
  16. 1 1
      main.ml
  17. 1 1
      matcher.ml
  18. 3 3
      optimizer.ml
  19. 12 1
      type.ml
  20. 1 1
      typeload.ml
  21. 2 2
      typer.ml

+ 11 - 0
ast.ml

@@ -136,6 +136,9 @@ module Meta = struct
 
 	let has m ml = List.exists (fun (m2,_,_) -> m = m2) ml
 	let get m ml = List.find (fun (m2,_,_) -> m = m2) ml
+
+	let to_string_ref = ref (fun _ -> assert false)
+	let to_string (m : strict_meta) : string = !to_string_ref m 
 end
 
 type keyword =
@@ -676,3 +679,11 @@ let map_expr loop (e,p) =
 	| EMeta (m,e) -> EMeta(m, loop e)
 	) in
 	(e,p)
+
+let rec s_expr (e,_) =
+	match e with
+	| EConst c -> s_constant c
+	| EParenthesis e -> "(" ^ (s_expr e) ^ ")"
+	| EArrayDecl el -> "[" ^ (String.concat "," (List.map s_expr el)) ^ "]"
+	| EObjectDecl fl -> "{" ^ (String.concat "," (List.map (fun (n,e) -> n ^ ":" ^ (s_expr e)) fl)) ^ "}"
+	| _ -> "'???'"

+ 1 - 1
codegen.ml

@@ -1858,7 +1858,7 @@ let rec constructor_side_effects e =
 		true
 	| TBinop _ | TTry _ | TIf _ | TBlock _ | TVars _
 	| TFunction _ | TArrayDecl _ | TObjectDecl _
-	| TParenthesis _ | TTypeExpr _ | TLocal _
+	| TParenthesis _ | TTypeExpr _ | TLocal _ | TMeta _
 	| TConst _ | TContinue | TBreak | TCast _ ->
 		try
 			Type.iter (fun e -> if constructor_side_effects e then raise Exit) e;

+ 2 - 0
common.ml

@@ -824,3 +824,5 @@ let rec close_times() =
 	| [] -> ()
 	| t :: _ -> close t; close_times()
 
+;;
+Ast.Meta.to_string_ref := fun m -> fst (MetaInfo.to_string m)

+ 3 - 0
genas3.ml

@@ -589,6 +589,8 @@ and gen_expr ctx e =
 		spr ctx "(";
 		gen_value ctx e;
 		spr ctx ")";
+	| TMeta (_,e) ->
+		gen_value ctx e
 	| TReturn eo ->
 		if ctx.in_value <> None then unsupported e.epos;
 		(match eo with
@@ -859,6 +861,7 @@ and gen_value ctx e =
 	| TField _
 	| TTypeExpr _
 	| TParenthesis _
+	| TMeta _
 	| TObjectDecl _
 	| TArrayDecl _
 	| TCall _

+ 8 - 6
gencommon.ml

@@ -110,7 +110,7 @@ struct
   let mk_heexpr = function
     | TConst _ -> 0 | TLocal _ -> 1 | TArray _ -> 3 | TBinop _ -> 4 | TField _ -> 5 | TTypeExpr _ -> 7 | TParenthesis _ -> 8 | TObjectDecl _ -> 9
     | TArrayDecl _ -> 10 | TCall _ -> 11 | TNew _ -> 12 | TUnop _ -> 13 | TFunction _ -> 14 | TVars _ -> 15 | TBlock _ -> 16 | TFor _ -> 17 | TIf _ -> 18 | TWhile _ -> 19
-    | TSwitch _ -> 20 | TMatch _ -> 21 | TTry _ -> 22 | TReturn _ -> 23 | TBreak -> 24 | TContinue -> 25 | TThrow _ -> 26 | TCast _ -> 27
+    | TSwitch _ -> 20 | TMatch _ -> 21 | TTry _ -> 22 | TReturn _ -> 23 | TBreak -> 24 | TContinue -> 25 | TThrow _ -> 26 | TCast _ -> 27 | TMeta _ -> 28
 
   let mk_heetype = function
     | TMono _ -> 0 | TEnum _ -> 1 | TInst _ -> 2 | TType _ -> 3 | TFun _ -> 4
@@ -4661,7 +4661,7 @@ struct
       | TFunction _
       | TCast _
       | TUnop _ -> Expression (expr)
-      | TParenthesis p -> shallow_expr_type p
+      | TParenthesis p | TMeta(_,p) -> shallow_expr_type p
       | TBlock ([e]) -> shallow_expr_type e
       | TCall _
       | TVars _
@@ -4711,6 +4711,7 @@ struct
           | TArray (e1,e2) ->
             aggregate true [e1;e2]
           | TParenthesis e
+          | TMeta(_,e)
           | TField (e,_) ->
             aggregate true [e]
           | TArrayDecl (el) ->
@@ -4805,7 +4806,7 @@ struct
       | TReturn _
       | TBreak
       | TContinue -> right
-      | TParenthesis p ->
+      | TParenthesis p | TMeta(_,p) ->
         apply_assign assign_fun p
       | _ ->
         match follow right.etype with
@@ -5179,6 +5180,7 @@ struct
     let default_implementation gen =
       let rec extract_expr e = match e.eexpr with
         | TParenthesis e
+        | TMeta (_,e)
         | TCast(e,_) -> extract_expr e
         | _ -> e
       in
@@ -6021,7 +6023,7 @@ struct
           let rec get_null e =
             match e.eexpr with
             | TConst TNull -> Some e
-            | TParenthesis e -> get_null e
+            | TParenthesis e | TMeta(_,e) -> get_null e
             | _ -> None
           in
           (match get_null expr with
@@ -6658,7 +6660,7 @@ struct
         | TIf(cond,e1,Some e2) ->
           is_side_effects_free cond && is_side_effects_free e1 && is_side_effects_free e2
         | TField(e,_)
-        | TParenthesis e -> is_side_effects_free e
+        | TParenthesis e | TMeta(_,e) -> is_side_effects_free e
         | TArrayDecl el -> List.for_all is_side_effects_free el
         | TCast(e,_) -> is_side_effects_free e
         | _ -> false
@@ -9423,7 +9425,7 @@ struct
     match e.eexpr with
       | TConst (v) -> Some v
       | TBinop(op, v1, v2) -> aggregate_constant op (get_constant_expr v1) (get_constant_expr v2)
-      | TParenthesis(e) -> get_constant_expr e
+      | TParenthesis(e) | TMeta(_,e) -> get_constant_expr e
       | _ -> None
 
   let traverse gen should_warn handle_switch_break handle_not_final_returns java_mode =

+ 8 - 7
gencpp.ml

@@ -341,7 +341,7 @@ List.filter (function (t,pl) ->
 
 let rec is_function_expr expr =
    match expr.eexpr with
-   | TParenthesis expr -> is_function_expr expr
+   | TParenthesis expr | TMeta(_,expr) -> is_function_expr expr
    | TCast (e,None) -> is_function_expr e
    | TFunction _ -> true
    | _ -> false;;
@@ -760,7 +760,7 @@ let rec iter_retval f retval e =
 	| TField (e,_)
 	| TUnop (_,_,e) ->
 		f true e
-	| TParenthesis e ->
+	| TParenthesis e | TMeta(_,e) ->
 		f retval e
 	| TBlock expr_list when retval ->
 		let rec return_last = function
@@ -856,7 +856,7 @@ let tmatch_params_to_args params =
 let rec is_null expr =
    match expr.eexpr with
    | TConst TNull -> true
-   | TParenthesis expr -> is_null expr
+   | TParenthesis expr | TMeta (_,expr) -> is_null expr
    | TCast (e,None) -> is_null e
    | _ -> false
 ;;
@@ -971,7 +971,7 @@ let rec is_dynamic_in_cpp ctx expr =
                    is_dynamic_in_cpp ctx func
                | _ -> ctx.ctx_dbgout "/* not TFun */";  true
            );
-		| TParenthesis(expr) -> is_dynamic_in_cpp ctx expr
+		| TParenthesis(expr) | TMeta(_,expr) -> is_dynamic_in_cpp ctx expr
       | TCast (e,None) -> is_dynamic_in_cpp ctx e
 		| TLocal { v_name = "__global__" } -> false
 		| TConst TNull -> true
@@ -1579,7 +1579,7 @@ and gen_expression ctx retval expression =
 		let rec is_variable e = match e.eexpr with
 		| TField _ -> false
 		| TLocal { v_name = "__global__" } -> false
-		| TParenthesis p -> is_variable p
+		| TParenthesis p | TMeta(_,p) -> is_variable p
 		| TCast (e,None) -> is_variable e
 		| _ -> true
       in
@@ -1596,7 +1596,7 @@ and gen_expression ctx retval expression =
             end;
             fixed
           )
-		| TParenthesis p -> is_fixed_override p
+		| TParenthesis p | TMeta(_,p) -> is_fixed_override p
 		| _ -> false
       in
       let is_super = (match func.eexpr with | TConst TSuper -> true | _ -> false ) in
@@ -1626,7 +1626,7 @@ and gen_expression ctx retval expression =
                   | "map" -> check_array_cast expression.etype
                   | _ -> ()
                )
-            | TParenthesis p -> cast_array_output p
+            | TParenthesis p | TMeta(_,p) -> cast_array_output p
             | _ -> ()
       in
       cast_array_output func;
@@ -1740,6 +1740,7 @@ and gen_expression ctx retval expression =
 	| TParenthesis expr when not retval ->
 			gen_expression ctx retval expr;
 	| TParenthesis expr -> output "("; gen_expression ctx retval expr; output ")"
+	| TMeta (_,expr) -> gen_expression ctx retval expr;
 	| TObjectDecl (
       ("fileName" , { eexpr = (TConst (TString file)) }) ::
          ("lineNumber" , { eexpr = (TConst (TInt line)) }) ::

+ 3 - 1
gencs.ml

@@ -882,7 +882,7 @@ let configure gen =
     match e.eexpr with
       | TLocal _ -> e
       | TCast(e,_)
-      | TParenthesis e -> ensure_local e explain
+      | TParenthesis e | TMeta(_,e) -> ensure_local e explain
       | _ -> gen.gcon.error ("This function argument " ^ explain ^ " must be a local variable.") e.epos; e
   in
 
@@ -992,6 +992,8 @@ let configure gen =
           )
         | TParenthesis e ->
           write w "("; expr_s w e; write w ")"
+        | TMeta (_,e) ->
+            expr_s w e 
         | TArrayDecl el ->
           print w "new %s" (t_s e.etype);
           write w "{";

+ 3 - 1
genjava.ml

@@ -284,7 +284,7 @@ struct
       (* this is hack to not use 'break' on switch cases *)
       | TLocal { v_name = "__fallback__" } when is_switch -> true
       | TCall( { eexpr = TLocal { v_name = "__goto__" } }, _ ) -> true
-      | TParenthesis p -> is_final_return_expr p
+      | TParenthesis p | TMeta (_,p) -> is_final_return_expr p
       | TBlock bl -> is_final_return_block is_switch bl
       | TSwitch (_, el_e_l, edef) ->
         List.for_all (fun (_,e) -> is_final_return_expr e) el_e_l && Option.map_default is_final_return_expr false edef
@@ -1123,6 +1123,8 @@ let configure gen =
         | TTypeExpr mt -> write w (md_s e.epos mt)
         | TParenthesis e ->
           write w "("; expr_s w e; write w ")"
+        | TMeta (_,e) ->
+          expr_s w e
         | TArrayDecl el when t_has_type_param_shallow false e.etype ->
           print w "( (%s) (new java.lang.Object[] " (t_s e.epos e.etype);
           write w "{";

+ 3 - 0
genjs.ml

@@ -459,6 +459,8 @@ and gen_expr ctx e =
 		spr ctx "(";
 		gen_value ctx e;
 		spr ctx ")";
+	| TMeta (_,e) ->
+		gen_value ctx e
 	| TReturn eo ->
 		if ctx.in_value <> None then unsupported e.epos;
 		(match eo with
@@ -786,6 +788,7 @@ and gen_value ctx e =
 	| TField _
 	| TTypeExpr _
 	| TParenthesis _
+	| TMeta _
 	| TObjectDecl _
 	| TArrayDecl _
 	| TNew _

+ 2 - 0
genneko.ml

@@ -248,6 +248,8 @@ and gen_expr ctx e =
 		gen_type_path p (t_path t)
 	| TParenthesis e ->
 		(EParenthesis (gen_expr ctx e),p)
+	| TMeta (_,e) ->
+		gen_expr ctx e
 	| TObjectDecl fl ->
 		let hasToString = ref false in
 		let fl = List.map (fun (f,e) -> if f = "toString" then hasToString := (match follow e.etype with TFun ([],_) -> true | _ -> false); f , gen_expr ctx e) fl in

+ 8 - 0
genphp.ml

@@ -609,6 +609,7 @@ and gen_call ctx e el =
 	| TFunction _, []
 	| TCall _, []
 	| TParenthesis _, []
+	| TMeta _, []
 	| TBlock _, [] ->
 		ctx.is_call <- true;
 		spr ctx "call_user_func(";
@@ -619,6 +620,7 @@ and gen_call ctx e el =
 	| TFunction _, el
 	| TCall _, el
 	| TParenthesis _, el
+	| TMeta _, el
 	| TBlock _, el ->
 		ctx.is_call <- true;
 		spr ctx "call_user_func_array(";
@@ -801,6 +803,7 @@ and gen_field_access ctx isvar e s =
 		gen_member_access ctx isvar e s
 	| TBlock _
 	| TParenthesis _
+	| TMeta _
 	| TObjectDecl _
 	| TArrayDecl _
 	| TNew _ ->
@@ -1001,6 +1004,7 @@ and gen_expr ctx e =
 		| TCall _
 		| TBlock _
 		| TParenthesis _
+		| TMeta _
 		| TArrayDecl _ ->
 			spr ctx "_hx_array_get(";
 			gen_value ctx e1;
@@ -1236,6 +1240,8 @@ and gen_expr ctx e =
 			gen_value ctx e;
 			spr ctx ")"
 		);
+	| TMeta (_,e) ->
+		gen_value ctx e
 	| TReturn eo ->
 		(match eo with
 		| None ->
@@ -1733,6 +1739,7 @@ and canbe_ternary_param e =
 	| TLocal _
 	| TField (_,FEnum _)
 	| TParenthesis _
+	| TMeta _
 	| TObjectDecl _
 	| TArrayDecl _
 	| TCall _
@@ -1762,6 +1769,7 @@ and gen_value ctx e =
 	| TBinop _
 	| TField _
 	| TParenthesis _
+	| TMeta _
 	| TObjectDecl _
 	| TArrayDecl _
 	| TCall _

+ 1 - 1
genswf8.ml

@@ -977,7 +977,7 @@ and gen_expr_2 ctx retval e =
 		getvar ctx (gen_access ctx false e)
 	| TConst c ->
 		gen_constant ctx c e.epos
-	| TParenthesis e ->
+	| TParenthesis e | TMeta (_,e) ->
 		gen_expr ctx retval e
 	| TBlock el ->
 		let rec loop = function

+ 6 - 6
genswf9.ml

@@ -989,7 +989,7 @@ let rec gen_expr_content ctx retval e =
 		gen_expr ctx true e;
 		write ctx HThrow;
 		no_value ctx retval;
-	| TParenthesis e ->
+	| TParenthesis e | TMeta (_,e) ->
 		gen_expr ctx retval e
 	| TObjectDecl fl ->
 		List.iter (fun (name,e) ->
@@ -1203,7 +1203,7 @@ let rec gen_expr_content ctx retval e =
 			let rec get_int e =
 				match e.eexpr with
 				| TConst (TInt n) -> if n < 0l || n > 512l then raise Exit; Int32.to_int n
-				| TParenthesis e | TBlock [e] -> get_int e
+				| TParenthesis e | TBlock [e] | TMeta (_,e) -> get_int e
 				| _ -> raise Not_found
 			in
 			List.iter (fun (vl,_) -> List.iter (fun v ->
@@ -1701,13 +1701,13 @@ and generate_function ctx fdata stat =
 					match e.eexpr with
 					| TSwitch _ | TMatch _ | TFor _ | TWhile _ | TTry _ -> false
 					| TIf _ -> loop e
-					| TParenthesis e -> inner_loop e
+					| TParenthesis e | TMeta(_,e) -> inner_loop e
 					| _ -> true
 				in
 				inner_loop e
 			| TIf (_,e1,Some e2) -> loop e1 && loop e2
 			| TSwitch (_,_,Some e) -> loop e
-			| TParenthesis e -> loop e
+			| TParenthesis e | TMeta(_,e) -> loop e
 			| _ -> false
 		in
 		if not (loop fdata.tf_expr) then write ctx HRetVoid;
@@ -1716,7 +1716,7 @@ and generate_function ctx fdata stat =
 
 and jump_expr_gen ctx e jif jfun =
 	match e.eexpr with
-	| TParenthesis e -> jump_expr_gen ctx e jif jfun
+	| TParenthesis e | TMeta(_,e) -> jump_expr_gen ctx e jif jfun
 	| TBinop (op,e1,e2) ->
 		let j t f =
 			check_binop ctx e1 e2;
@@ -1800,7 +1800,7 @@ let rec is_const e =
 	| TConst _ -> true
 	| TArrayDecl el | TBlock el -> List.for_all is_const el
 	| TObjectDecl fl -> List.for_all (fun (_,e) -> is_const e) fl
-	| TParenthesis e -> is_const e
+	| TParenthesis e | TMeta(_,e) -> is_const e
 	| TFunction _ -> true
 	| _ -> false
 

+ 2 - 10
genxml.ml

@@ -81,21 +81,13 @@ let rec follow_param t =
 	| _ ->
 		t
 
-let rec sexpr (e,_) =
-	match e with
-	| EConst c -> s_constant c
-	| EParenthesis e -> "(" ^ (sexpr e) ^ ")"
-	| EArrayDecl el -> "[" ^ (String.concat "," (List.map sexpr el)) ^ "]"
-	| EObjectDecl fl -> "{" ^ (String.concat "," (List.map (fun (n,e) -> n ^ ":" ^ (sexpr e)) fl)) ^ "}"
-	| _ -> "'???'"
-
 let gen_meta meta =
 	let meta = List.filter (fun (m,_,_) -> match m with Meta.Used | Meta.MaybeUsed | Meta.RealPath -> false | _ -> true) meta in
 	match meta with
 	| [] -> []
 	| _ ->
 		let nodes = List.map (fun (m,el,_) ->
-			node "m" ["n",fst (MetaInfo.to_string m)] (List.map (fun e -> node "e" [] [gen_string (sexpr e)]) el)
+			node "m" ["n",fst (MetaInfo.to_string m)] (List.map (fun e -> node "e" [] [gen_string (Ast.s_expr e)]) el)
 		) meta in
 		[node "meta" [] nodes]
 
@@ -342,7 +334,7 @@ let generate_type com t =
 			| _ ->
 			match pl with
 			| [] -> p "@%s " (fst (MetaInfo.to_string m))
-			| l -> p "@%s(%s) " (fst (MetaInfo.to_string m)) (String.concat "," (List.map sexpr pl))
+			| l -> p "@%s(%s) " (fst (MetaInfo.to_string m)) (String.concat "," (List.map Ast.s_expr pl))
 		) ml
 	in
 	let access a =

+ 3 - 2
interp.ml

@@ -4356,7 +4356,7 @@ let rec make_const e =
 		| TBool b -> VBool b
 		| TNull -> VNull
 		| TThis | TSuper -> raise Exit)
-	| TParenthesis e ->
+	| TParenthesis e | TMeta(_,e) ->
 		make_const e
 	| TObjectDecl el ->
 		VObject (obj (hash_field (get_ctx())) (List.map (fun (f,e) -> f, make_const e) el))
@@ -4530,7 +4530,8 @@ let rec make_ast e =
 				let t = (match t with TClassDecl c -> TInst (c,[]) | TEnumDecl e -> TEnum (e,[]) | TTypeDecl t -> TType (t,[]) | TAbstractDecl a -> TAbstract (a,[])) in
 				Some (try make_type t with Exit -> assert false)
 		) in
-		ECast (make_ast e,t))
+		ECast (make_ast e,t)
+	| TMeta (m,e) -> EMeta(m,make_ast e))
 	,e.epos)
 
 ;;

+ 1 - 1
main.ml

@@ -1348,7 +1348,7 @@ with
 			Buffer.add_string b ("<meta name=\"" ^ (fst (MetaInfo.to_string m)) ^ "\"");
 			if el = [] then Buffer.add_string b "/>" else begin
 				Buffer.add_string b ">\n";
-				List.iter (fun e -> Buffer.add_string b ((htmlescape (Genxml.sexpr e)) ^ "\n")) el;
+				List.iter (fun e -> Buffer.add_string b ((htmlescape (Ast.s_expr e)) ^ "\n")) el;
 				Buffer.add_string b "</meta>\n";
 			end
 		) m;

+ 1 - 1
matcher.ml

@@ -1175,7 +1175,7 @@ let match_expr ctx e cases def with_type p =
 		let rec loop e = match e.eexpr with
 			| TField (ef,s) when (match s with FEnum _ -> false | _ -> true) ->
 				mk_st (SField(loop ef,field_name s)) e.etype e.epos
-			| TParenthesis e ->
+			| TParenthesis e | TMeta(_,e) ->
 				loop e
 			| TLocal v ->
 				mk_st (SVar v) e.etype e.epos

+ 3 - 3
optimizer.ml

@@ -34,7 +34,7 @@ let has_side_effect e =
 		| TConst _ | TLocal _ | TField (_,FEnum _) | TTypeExpr _ | TFunction _ -> ()
 		| TMatch _ | TNew _ | TCall _ | TField _ | TArray _ | TBinop ((OpAssignOp _ | OpAssign),_,_) | TUnop ((Increment|Decrement),_,_) -> raise Exit
 		| TReturn _ | TBreak | TContinue | TThrow _ | TCast (_,Some _) -> raise Exit
-		| TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TWhile _ | TFor _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TVars _ | TBlock _ | TObjectDecl _ -> Type.iter loop e
+		| TCast (_,None) | TBinop _ | TUnop _ | TParenthesis _ | TMeta _ | TWhile _ | TFor _ | TIf _ | TTry _ | TSwitch _ | TArrayDecl _ | TVars _ | TBlock _ | TObjectDecl _ -> Type.iter loop e
 	in
 	try
 		loop e; false
@@ -600,7 +600,7 @@ let standard_precedence op =
 
 let rec need_parent e =
 	match e.eexpr with
-	| TConst _ | TLocal _ | TArray _ | TField _ | TParenthesis _ | TCall _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false
+	| TConst _ | TLocal _ | TArray _ | TField _ | TParenthesis _ | TMeta _ | TCall _ | TNew _ | TTypeExpr _ | TObjectDecl _ | TArrayDecl _ -> false
 	| TCast (e,None) -> need_parent e
 	| TCast _ | TThrow _ | TReturn _ | TTry _ | TMatch _ | TSwitch _ | TFor _ | TIf _ | TWhile _ | TBinop _ | TContinue | TBreak
 	| TBlock _ | TVars _ | TFunction _ | TUnop _ -> true
@@ -954,7 +954,7 @@ let rec make_constant_expression ctx ?(concat_strings=false) e =
 			Some (mk (TConst (TString (s1 ^ s2))) ctx.com.basic.tstring (punion e1.epos e2.epos))
 		| Some e1, Some e2 -> Some (mk (TBinop(op, e1, e2)) e.etype e.epos)
 		| _ -> None)
-	| TParenthesis e -> Some e
+	| TParenthesis e | TMeta(_,e) -> Some e
 	| TTypeExpr _ -> Some e
 	(* try to inline static function calls *)
 	| TCall ({ etype = TFun(_,ret); eexpr = TField (_,FStatic (c,cf)) },el) ->

+ 12 - 1
type.ml

@@ -126,6 +126,7 @@ and texpr_expr =
 	| TContinue
 	| TThrow of texpr
 	| TCast of texpr * module_type option
+	| TMeta of metadata_entry * texpr
 
 and tfield_access =
 	| FInstance of tclass * tclass_field
@@ -1286,7 +1287,8 @@ let iter f e =
 	| TField (e,_)
 	| TParenthesis e
 	| TCast (e,_)
-	| TUnop (_,_,e) ->
+	| TUnop (_,_,e)
+	| TMeta(_,e) ->
 		f e
 	| TArrayDecl el
 	| TNew (_,_,el)
@@ -1369,6 +1371,8 @@ let map_expr f e =
 		{ e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)) }
 	| TCast (e1,t) ->
 		{ e with eexpr = TCast (f e1,t) }
+	| TMeta (m,e1) ->
+		 {e with eexpr = TMeta(m,f e1)}
 
 let map_expr_type f ft fv e =
 	match e.eexpr with
@@ -1436,6 +1440,8 @@ let map_expr_type f ft fv e =
 		{ e with eexpr = TReturn (match eo with None -> None | Some e -> Some (f e)); etype = ft e.etype }
 	| TCast (e1,t) ->
 		{ e with eexpr = TCast (f e1,t); etype = ft e.etype }
+	| TMeta (m,e1) ->
+		{e with eexpr = TMeta(m, f e1); etype = ft e.etype }
 
 let s_expr_kind e =
 	match e.eexpr with
@@ -1465,6 +1471,7 @@ let s_expr_kind e =
 	| TContinue -> "Continue"
 	| TThrow _ -> "Throw"
 	| TCast _ -> "Cast"
+	| TMeta _ -> "Meta"
 
 let s_const = function
 	| TInt i -> Int32.to_string i
@@ -1550,6 +1557,8 @@ let rec s_expr s_type e =
 		"Throw " ^ (loop e)
 	| TCast (e,t) ->
 		sprintf "Cast %s%s" (match t with None -> "" | Some t -> s_type_path (t_path t) ^ ": ") (loop e)
+	| TMeta ((n,el,_),e) ->
+		sprintf "@%s%s %s" (Meta.to_string n) (match el with [] -> "" | _ -> "(" ^ (String.concat ", " (List.map Ast.s_expr el)) ^ ")") (loop e)
 	) in
 	sprintf "(%s : %s)" str (s_type e.etype)
 
@@ -1625,3 +1634,5 @@ let rec s_expr_pretty tabs s_type e =
 		sprintf "cast %s" (loop e)
 	| TCast (e,Some mt) ->
 		sprintf "cast (%s,%s)" (loop e) (s_type_path (t_path mt))
+	| TMeta ((n,el,_),e) ->
+		sprintf "@%s%s %s" (Meta.to_string n) (match el with [] -> "" | _ -> "(" ^ (String.concat ", " (List.map Ast.s_expr el)) ^ ")") (loop e)		

+ 1 - 1
typeload.ml

@@ -865,7 +865,7 @@ let rec return_flow ctx e =
 	let return_flow = return_flow ctx in
 	match e.eexpr with
 	| TReturn _ | TThrow _ -> ()
-	| TParenthesis e ->
+	| TParenthesis e | TMeta(_,e) ->
 		return_flow e
 	| TBlock el ->
 		let rec loop = function

+ 2 - 2
typer.ml

@@ -364,7 +364,7 @@ let rec unify_min_raise ctx (el:texpr list) : t =
 				(match List.rev el with
 				| [] -> false
 				| e :: _ -> chk_null e)
-			| TParenthesis e -> chk_null e
+			| TParenthesis e | TMeta(_,e) -> chk_null e
 			| _ -> false
 		in
 
@@ -1346,7 +1346,7 @@ let unify_int ctx e k =
 		| TArray({ etype = t } as e,_) -> is_dynamic_array t || maybe_dynamic_rec e t
 		| TField({ etype = t } as e,f) -> is_dynamic_field t (field_name f) || maybe_dynamic_rec e t
 		| TCall({ etype = t } as e,_) -> is_dynamic_return t || maybe_dynamic_rec e t
-		| TParenthesis e -> maybe_dynamic_mono e
+		| TParenthesis e | TMeta(_,e) -> maybe_dynamic_mono e
 		| TIf (_,a,Some b) -> maybe_dynamic_mono a || maybe_dynamic_mono b
 		| _ -> false
 	and maybe_dynamic_rec e t =