Переглянути джерело

[parser] support `var @:meta name`

Simon Krajewski 5 роки тому
батько
коміт
c05e7b0025

+ 3 - 3
src/context/display/display.ml

@@ -66,7 +66,7 @@ module ExprPreprocessing = struct
 			match fst e with
 			| EVars vl when is_annotated (pos e) && is_completion ->
 				let rec loop2 acc mark vl = match vl with
-					| ((s,pn),final,tho,eo) as v :: vl ->
+					| (meta,(s,pn),final,tho,eo) as v :: vl ->
 						if mark then
 							loop2 (v :: acc) mark vl
 						else if is_annotated pn then
@@ -90,7 +90,7 @@ module ExprPreprocessing = struct
 								in
 								let p = {p0 with pmax = (pos e).pmin} in
 								let e = if is_annotated p then annotate_marked e else e in
-								loop2 (((s,pn),final,tho,(Some e)) :: acc) mark vl
+								loop2 ((meta,(s,pn),final,tho,(Some e)) :: acc) mark vl
 						end
 					| [] ->
 						List.rev acc,mark
@@ -190,7 +190,7 @@ module ExprPreprocessing = struct
 				raise Exit
 			| EVars vl when is_annotated (pos e) ->
 				(* We only want to mark EVars if we're on a var name. *)
-				if List.exists (fun ((_,pn),_,_,_) -> is_annotated pn) vl then
+				if List.exists (fun (_,(_,pn),_,_,_) -> is_annotated pn) vl then
 					annotate_marked e
 				else
 					raise Exit

+ 1 - 1
src/context/display/documentSymbols.ml

@@ -12,7 +12,7 @@ let collect_module_symbols with_locals (pack,decls) =
 		let add name kind location = add name kind location parent in
 		begin match e with
 		| EVars vl ->
-			List.iter (fun ((s,p),_,_,eo) ->
+			List.iter (fun (_,(s,p),_,_,eo) ->
 				add s Variable p false;
 				expr_opt parent eo
 			) vl

+ 1 - 1
src/context/display/syntaxExplorer.ml

@@ -60,7 +60,7 @@ let find_in_syntax symbols (pack,decls) =
 			expr e1;
 			check KAnyField s;
 		| EVars vl ->
-			List.iter (fun (_,_,tho,eo) ->
+			List.iter (fun (_,_,_,tho,eo) ->
 				Option.may type_hint tho;
 				expr_opt eo
 			) vl;

+ 6 - 6
src/core/ast.ml

@@ -205,7 +205,7 @@ and expr_def =
 	| ECall of expr * expr list
 	| ENew of placed_type_path * expr list
 	| EUnop of unop * unop_flag * expr
-	| EVars of (placed_name * bool * type_hint option * expr option) list
+	| EVars of (metadata * placed_name * bool * type_hint option * expr option) list
 	| EFunction of function_kind * func
 	| EBlock of expr list
 	| EFor of expr * expr
@@ -660,10 +660,10 @@ let map_expr loop (e,p) =
 		ENew (t,el)
 	| EUnop (op,f,e) -> EUnop (op,f,loop e)
 	| EVars vl ->
-		EVars (List.map (fun (n,b,t,eo) ->
+		EVars (List.map (fun (meta,n,b,t,eo) ->
 			let t = opt type_hint t in
 			let eo = opt loop eo in
-			n,b,t,eo
+			meta,n,b,t,eo
 		) vl)
 	| EFunction (kind,f) -> EFunction (kind,func f)
 	| EBlock el -> EBlock (List.map loop el)
@@ -744,7 +744,7 @@ let iter_expr loop (e,p) =
 	| EFunction(_,f) ->
 		List.iter (fun (_,_,_,_,eo) -> opt eo) f.f_args;
 		opt f.f_expr
-	| EVars vl -> List.iter (fun (_,_,_,eo) -> opt eo) vl
+	| EVars vl -> List.iter (fun (_,_,_,_,eo) -> opt eo) vl
 
 let s_object_key_name name =  function
 	| DoubleQuotes -> "\"" ^ StringHelper.s_escape name ^ "\""
@@ -859,7 +859,7 @@ module Printer = struct
 		if List.length tl > 0 then "<" ^ String.concat ", " (List.map (s_type_param tabs) tl) ^ ">" else ""
 	and s_func_arg tabs ((n,_),o,_,t,e) =
 		if o then "?" else "" ^ n ^ s_opt_type_hint tabs t ":" ^ s_opt_expr tabs e " = "
-	and s_var tabs ((n,_),_,t,e) =
+	and s_var tabs (_,(n,_),_,t,e) =
 		n ^ (s_opt_type_hint tabs t ":") ^ s_opt_expr tabs e " = "
 	and s_case tabs (el,e1,e2,_) =
 		"case " ^ s_expr_list tabs el ", " ^
@@ -1005,7 +1005,7 @@ module Expr = struct
 				loop e1
 			| EVars vl ->
 				add "EVars";
-				List.iter (fun ((n,p),_,cto,eo) ->
+				List.iter (fun (_,(n,p),_,cto,eo) ->
 					add (Printf.sprintf "%s  %s%s" tabs n (match cto with None -> "" | Some (ct,_) -> ":" ^ Printer.s_complex_type "" ct));
 					match eo with
 					| None -> ()

+ 1 - 1
src/core/tOther.ml

@@ -117,7 +117,7 @@ module TExprToExpr = struct
 			let arg (v,c) = (v.v_name,v.v_pos), false, v.v_meta, mk_type_hint v.v_type null_pos, (match c with None -> None | Some c -> Some (convert_expr c)) in
 			EFunction (FKAnonymous,{ f_params = []; f_args = List.map arg f.tf_args; f_type = mk_type_hint f.tf_type null_pos; f_expr = Some (convert_expr f.tf_expr) })
 		| TVar (v,eo) ->
-			EVars ([(v.v_name,v.v_pos), v.v_final, mk_type_hint v.v_type v.v_pos, eopt eo])
+			EVars ([v.v_meta,(v.v_name,v.v_pos), v.v_final, mk_type_hint v.v_type v.v_pos, eopt eo])
 		| TBlock el -> EBlock (List.map convert_expr el)
 		| TFor (v,it,e) ->
 			let ein = (EBinop (OpIn,(EConst (Ident v.v_name),it.epos),convert_expr it),it.epos) in

+ 1 - 1
src/macro/eval/evalDebugMisc.ml

@@ -329,7 +329,7 @@ let rec expr_to_value ctx env e =
 			let v1 = loop e1 in
 			throw v1 (pos e)
 		| EVars vl ->
-			List.iter (fun ((n,_),_,_,eo) ->
+			List.iter (fun (_,(n,_),_,_,eo) ->
 				match eo with
 				| Some e ->
 					env.env_extra_locals <- IntMap.add (hash n) (loop e) env.env_extra_locals

+ 4 - 2
src/macro/macroApi.ml

@@ -439,13 +439,14 @@ and encode_expr e =
 			| EUnop (op,flag,e) ->
 				9, [encode_unop op; vbool (match flag with Prefix -> false | Postfix -> true); loop e]
 			| EVars vl ->
-				10, [encode_array (List.map (fun (v,final,t,eo) ->
+				10, [encode_array (List.map (fun (meta,v,final,t,eo) ->
 					encode_obj [
 						"name",encode_placed_name v;
 						"name_pos",encode_pos (pos v);
 						"isFinal",vbool final;
 						"type",null encode_ctype t;
 						"expr",null loop eo;
+						"meta",encode_meta_content meta;
 					]
 				) vl)]
 			| EFunction (kind,f) ->
@@ -772,7 +773,8 @@ and decode_expr v =
 			EVars (List.map (fun v ->
 				let vfinal = field v "isFinal" in
 				let final = if vfinal == vnull then false else decode_bool vfinal in
-				((decode_placed_name (field v "name_pos") (field v "name")),final,opt decode_ctype (field v "type"),opt loop (field v "expr"))
+				let meta = opt_list decode_meta_content (field v "meta") in
+				(meta,(decode_placed_name (field v "name_pos") (field v "name")),final,opt decode_ctype (field v "type"),opt loop (field v "expr"))
 			) (decode_array vl))
 		| 11, [kind;f] ->
 			EFunction (decode_function_kind kind,decode_fun f)

+ 4 - 4
src/optimization/optimizer.ml

@@ -669,10 +669,10 @@ let optimize_completion_expr e args =
 				());
 			map e
 		| EVars vl ->
-			let vl = List.map (fun ((v,pv),final,t,e) ->
+			let vl = List.map (fun (meta,(v,pv),final,t,e) ->
 				let e = (match e with None -> None | Some e -> Some (loop e)) in
 				decl v (Option.map fst t) e;
-				((v,pv),final,t,e)
+				(meta,(v,pv),final,t,e)
 			) vl in
 			(EVars vl,p)
 		| EBlock el ->
@@ -719,7 +719,7 @@ let optimize_completion_expr e args =
 						(fun (name, pos) ->
 							let etmp = (EConst (Ident "`tmp"),pos) in
 							decl name None (Some (EBlock [
-								(EVars [("`tmp",null_pos),false,None,None],p);
+								(EVars [[],("`tmp",null_pos),false,None,None],p);
 								(EFor(header,(EBinop (OpAssign,etmp,(EConst (Ident name),p)),p)), p);
 								etmp
 							],p));
@@ -817,7 +817,7 @@ let optimize_completion_expr e args =
 							with Not_found ->
 								let e = subst_locals lc e in
 								let name = "`tmp_" ^ string_of_int id in
-								tmp_locals := ((name,null_pos),false,None,Some e) :: !tmp_locals;
+								tmp_locals := ([],(name,null_pos),false,None,Some e) :: !tmp_locals;
 								tmp_hlocals := PMap.add id name !tmp_hlocals;
 								name
 							) in

+ 13 - 11
src/syntax/grammar.mly

@@ -1091,33 +1091,35 @@ and parse_array_decl p1 s =
 	in
 	EArrayDecl (List.rev el),punion p1 p2
 
-and parse_var_decl_head final = parser
-	| [< name, p = dollar_ident; t = popt parse_type_hint >] -> (name,final,t,p)
+and parse_var_decl_head final s =
+	let meta = parse_meta s in
+	match s with parser
+	| [< name, p = dollar_ident; t = popt parse_type_hint >] -> (meta,name,final,t,p)
 
 and parse_var_assignment = parser
 	| [< '(Binop OpAssign,p1); s >] ->
 		Some (secure_expr s)
 	| [< >] -> None
 
-and parse_var_assignment_resume final vl name pn t s =
+and parse_var_assignment_resume final vl meta name pn t s =
 	let eo = parse_var_assignment s in
-	((name,pn),final,t,eo)
+	(meta,(name,pn),final,t,eo)
 
 and parse_var_decls_next final vl = parser
-	| [< '(Comma,p1); name,final,t,pn = parse_var_decl_head final; s >] ->
-		let v_decl = parse_var_assignment_resume final vl name pn t s in
+	| [< '(Comma,p1); meta,name,final,t,pn = parse_var_decl_head final; s >] ->
+		let v_decl = parse_var_assignment_resume final vl meta name pn t s in
 		parse_var_decls_next final (v_decl :: vl) s
 	| [< >] ->
 		vl
 
 and parse_var_decls final p1 = parser
-	| [< name,final,t,pn = parse_var_decl_head final; s >] ->
-		let v_decl = parse_var_assignment_resume final [] name pn t s in
+	| [< meta,name,final,t,pn = parse_var_decl_head final; s >] ->
+		let v_decl = parse_var_assignment_resume final [] meta name pn t s in
 		List.rev (parse_var_decls_next final [v_decl] s)
 	| [< s >] -> error (Custom "Missing variable identifier") p1
 
 and parse_var_decl final = parser
-	| [< name,final,t,pn = parse_var_decl_head final; v_decl = parse_var_assignment_resume final [] name pn t >] -> v_decl
+	| [< meta,name,final,t,pn = parse_var_decl_head final; v_decl = parse_var_assignment_resume final [] meta name pn t >] -> v_decl
 
 and inline_function = parser
 	| [< '(Kwd Inline,_); '(Kwd Function,p1) >] -> true, p1
@@ -1438,8 +1440,8 @@ and parse_guard = parser
 		e
 
 and expr_or_var = parser
-	| [< '(Kwd Var,p1); name,p2 = dollar_ident; >] -> EVars [(name,p2),false,None,None],punion p1 p2
-	| [< '(Kwd Final,p1); name,p2 = dollar_ident; >] -> EVars [(name,p2),true,None,None],punion p1 p2
+	| [< '(Kwd Var,p1); meta = parse_meta; name,p2 = dollar_ident; >] -> EVars [meta,(name,p2),false,None,None],punion p1 p2
+	| [< '(Kwd Final,p1); meta = parse_meta; name,p2 = dollar_ident; >] -> EVars [meta,(name,p2),true,None,None],punion p1 p2
 	| [< e = secure_expr >] -> e
 
 and parse_switch_cases eswitch cases = parser

+ 2 - 1
src/syntax/reification.ml

@@ -273,12 +273,13 @@ let reify in_macro =
 			) [] p in
 			expr "EUnop" [op;to_bool (flag = Postfix) p;loop e]
 		| EVars vl ->
-			expr "EVars" [to_array (fun ((n,pn),final,th,e) p ->
+			expr "EVars" [to_array (fun (meta,(n,pn),final,th,e) p ->
 				let fields = [
 					"name", to_string n pn;
 					"type", to_opt to_type_hint th p;
 					"expr", to_opt to_expr e p;
 					"isFinal",to_bool final p;
+					"meta", to_meta meta p;
 				] in
 				to_obj fields p
 			) vl p]

+ 2 - 2
src/typing/macroContext.ml

@@ -656,7 +656,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			with Error (Custom _,_) ->
 				(* if it's not a constant, let's make something that is typed as haxe.macro.Expr - for nice error reporting *)
 				(EBlock [
-					(EVars [("__tmp",null_pos),false,Some (CTPath ctexpr,p),Some (EConst (Ident "null"),p)],p);
+					(EVars [[],("__tmp",null_pos),false,Some (CTPath ctexpr,p),Some (EConst (Ident "null"),p)],p);
 					(EConst (Ident "__tmp"),p);
 				],p)
 			) in
@@ -709,7 +709,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 							else
 								List.map Interp.decode_field (Interp.decode_array v)
 						in
-						Some (EVars [("fields",null_pos),false,Some (CTAnonymous fields,p),None],p)
+						Some (EVars [[],("fields",null_pos),false,Some (CTAnonymous fields,p),None],p)
 					)
 				| MMacroType ->
 					"ComplexType",(fun () ->

+ 1 - 1
src/typing/matcher.ml

@@ -333,7 +333,7 @@ module Pattern = struct
 						if i = "_" then PatAny
 						else handle_ident i (pos e)
 				end
-			| EVars([(s,p),final,None,None]) ->
+			| EVars([_,(s,p),final,None,None]) ->
 				let v = add_local final s p in
 				PatVariable v
 			| ECall(e1,el) ->

+ 3 - 3
src/typing/typeloadFields.ml

@@ -221,7 +221,7 @@ let transform_abstract_field com this_t a_t a f =
 	| FProp _ when not stat ->
 		error "Member property accessors must be get/set or never" p;
 	| FFun fu when fst f.cff_name = "new" && not stat ->
-		let init p = (EVars [("this",null_pos),false,Some this_t,None],p) in
+		let init p = (EVars [[],("this",null_pos),false,Some this_t,None],p) in
 		let cast e = (ECast(e,None)),pos e in
 		let ret p = (EReturn (Some (cast (EConst (Ident "this"),p))),p) in
 		let meta = (Meta.Impl,[],null_pos) :: (Meta.NoCompletion,[],null_pos) :: f.cff_meta in
@@ -414,7 +414,7 @@ let build_enum_abstract ctx c a fields p =
 		| _ ->
 			()
 	) fields;
-	EVars [("",null_pos),false,Some (CTAnonymous fields,p),None],p
+	EVars [[],("",null_pos),false,Some (CTAnonymous fields,p),None],p
 
 let apply_macro ctx mode path el p =
 	let cpath, meth = (match List.rev (ExtString.String.nsplit path ".") with
@@ -657,7 +657,7 @@ let build_fields (ctx,cctx) c fields =
 	c.cl_build <- (fun() -> BuildMacro pending);
 	build_module_def ctx (TClassDecl c) c.cl_meta get_fields cctx.context_init (fun (e,p) ->
 		match e with
-		| EVars [_,_,Some (CTAnonymous f,p),None] ->
+		| EVars [_,_,_,Some (CTAnonymous f,p),None] ->
 			let f = List.map (fun f -> transform_field (ctx,cctx) c f fields p) f in
 			fields := f
 		| _ -> error "Class build macro must return a single variable with anonymous fields" p

+ 1 - 1
src/typing/typeloadModule.ml

@@ -650,7 +650,7 @@ let init_module_type ctx context_init (decl,p) =
 		in
 		TypeloadFields.build_module_def ctx (TEnumDecl e) e.e_meta get_constructs context_init (fun (e,p) ->
 			match e with
-			| EVars [_,_,Some (CTAnonymous fields,p),None] ->
+			| EVars [_,_,_,Some (CTAnonymous fields,p),None] ->
 				constructs := List.map (fun f ->
 					let args, params, t = (match f.cff_kind with
 					| FVar (t,None) -> [], [], t

+ 2 - 1
src/typing/typer.ml

@@ -1378,7 +1378,7 @@ and type_array_access ctx e1 e2 p mode =
 	Calls.array_access ctx e1 e2 mode p
 
 and type_vars ctx vl p =
-	let vl = List.map (fun ((v,pv),final,t,e) ->
+	let vl = List.map (fun (meta,(v,pv),final,t,e) ->
 		try
 			let t = Typeload.load_type_hint ctx p t in
 			let e = (match e with
@@ -1389,6 +1389,7 @@ and type_vars ctx vl p =
 					Some e
 			) in
 			let v = add_local_with_origin ctx TVOLocalVariable v t pv in
+			v.v_meta <- meta;
 			if final then v.v_final <- true;
 			if ctx.in_display && DisplayPosition.display_position#enclosed_in pv then
 				DisplayEmitter.display_variable ctx v pv;

+ 5 - 0
std/haxe/macro/Expr.hx

@@ -324,6 +324,11 @@ typedef Var = {
 		Whether or not the variable can be assigned to.
 	**/
 	var ?isFinal:Bool;
+
+	/**
+		The metadata of the variable.
+	**/
+	var ?meta:Metadata;
 }
 
 /**