瀏覽代碼

changed EVars tuple into a record type

Aleksandr Kuzmenko 5 年之前
父節點
當前提交
51314e4c6c

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

@@ -72,13 +72,13 @@ 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,ml) as v :: vl ->
+					| v :: vl ->
 						if mark then
 							loop2 (v :: acc) mark vl
-						else if is_annotated pn then
+						else if is_annotated (snd v.ev_name) then
 							(* If the name is the display position, mark the expression *)
 							loop2 (v :: acc) true vl
-						else begin match eo with
+						else begin match v.ev_expr with
 							| None ->
 								(* If there is no expression, we don't have to do anything.
 								   Should the display position be on the type-hint, it will
@@ -90,13 +90,13 @@ module ExprPreprocessing = struct
 								   we cannot determine that correctly without knowing its position.
 								   Note: We know `e` itself isn't the display position because this entire
 								   algorithm is bottom-up and it would be marked already if it was. *)
-								let p0 = match tho with
+								let p0 = match v.ev_type with
 									| Some (_,pt) -> pt
-									| None -> pn
+									| None -> snd v.ev_name
 								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),ml) :: acc) mark vl
+								loop2 ({ v with ev_expr = Some e } :: acc) mark vl
 						end
 					| [] ->
 						List.rev acc,mark
@@ -196,7 +196,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 v -> is_annotated (snd v.ev_name)) vl then
 					annotate_marked e
 				else
 					raise Exit

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

@@ -12,9 +12,9 @@ let collect_module_symbols mname 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,_) ->
-				add s Variable p false;
-				expr_opt parent eo
+			List.iter (fun v ->
+				add (fst v.ev_name) Variable (snd v.ev_name) false;
+				expr_opt parent v.ev_expr
 			) vl
 		| ETry(e1,catches) ->
 			expr parent e1;

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

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

+ 35 - 13
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 * metadata) list
+	| EVars of evar list
 	| EFunction of function_kind * func
 	| EBlock of expr list
 	| EFor of expr * expr
@@ -271,6 +271,14 @@ and class_field = {
 	mutable cff_kind : class_field_kind;
 }
 
+and evar = {
+	ev_name : placed_name;
+	ev_final : bool;
+	ev_type : type_hint option;
+	ev_expr : expr option;
+	ev_meta : metadata;
+}
+
 type enum_flag =
 	| EPrivate
 	| EExtern
@@ -334,6 +342,15 @@ let mk_type_path ?(params=[]) ?sub (pack,name) =
 		raise (Invalid_argument "Empty module name is not allowed");
 	{ tpackage = pack; tname = name; tsub = sub; tparams = params; }
 
+let mk_evar ?(final=false) ?(t:type_hint option) ?eo ?(meta=[]) name =
+	{
+		ev_name = name;
+		ev_final = final;
+		ev_type = t;
+		ev_expr = eo;
+		ev_meta = meta;
+	}
+
 let is_lower_ident i =
 	if String.length i = 0 then
 		raise (Invalid_argument "Identifier name must not be empty")
@@ -666,10 +683,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,ml) ->
-			let t = opt type_hint t in
-			let eo = opt loop eo in
-			n,b,t,eo,ml
+		EVars (List.map (fun v ->
+			let t = opt type_hint v.ev_type in
+			let eo = opt loop v.ev_expr in
+			{ v with ev_type = t; ev_expr = eo }
 		) vl)
 	| EFunction (kind,f) -> EFunction (kind,func f)
 	| EBlock el -> EBlock (List.map loop el)
@@ -750,7 +767,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 v -> opt v.ev_expr) vl
 
 let s_object_key_name name =  function
 	| DoubleQuotes -> "\"" ^ StringHelper.s_escape name ^ "\""
@@ -885,10 +902,10 @@ 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,ml) =
-		let s = n ^ (s_opt_type_hint tabs t ":") ^ s_opt_expr tabs e " = " in
-		if ml = [] then s
-		else (String.concat " " (List.map (s_metadata tabs) ml)) ^ " " ^ s
+	and s_var tabs v =
+		let s = (fst v.ev_name) ^ (s_opt_type_hint tabs v.ev_type ":") ^ s_opt_expr tabs v.ev_expr " = " in
+		if v.ev_meta = [] then s
+		else (String.concat " " (List.map (s_metadata tabs) v.ev_meta)) ^ " " ^ s
 	and s_case tabs (el,e1,e2,_) =
 		"case " ^ s_expr_list tabs el ", " ^
 		(match e1 with None -> ":" | Some e -> " if (" ^ s_expr_inner tabs e ^ "):") ^
@@ -1034,9 +1051,14 @@ module Expr = struct
 				loop e1
 			| EVars vl ->
 				add "EVars";
-				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
+				List.iter (fun v ->
+					let t_hint =
+						match v.ev_type with
+						| None -> ""
+						| Some (ct,_) -> ":" ^ Printer.s_complex_type "" ct
+					in
+					add (Printf.sprintf "%s  %s%s" tabs (fst v.ev_name) t_hint);
+					match v.ev_expr with
 					| None -> ()
 					| Some e ->
 						loop' (Printf.sprintf "%s      " tabs) e

+ 4 - 1
src/core/tOther.ml

@@ -103,7 +103,10 @@ 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), has_var_flag v VFinal, mk_type_hint v.v_type v.v_pos, eopt eo, v.v_meta])
+			let final = has_var_flag v VFinal
+			and t = mk_type_hint v.v_type v.v_pos
+			and eo = eopt eo in
+			EVars ([mk_evar ~final ?t ?eo ~meta:v.v_meta (v.v_name,v.v_pos)])
 		| 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

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

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

+ 11 - 8
src/macro/macroApi.ml

@@ -439,14 +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,ml) ->
+				10, [encode_array (List.map (fun v ->
 					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 ml;
+						"name",encode_placed_name v.ev_name;
+						"name_pos",encode_pos (pos v.ev_name);
+						"isFinal",vbool v.ev_final;
+						"type",null encode_ctype v.ev_type;
+						"expr",null loop v.ev_expr;
+						"meta",encode_meta_content v.ev_meta;
 					]
 				) vl)]
 			| EFunction (kind,f) ->
@@ -776,7 +776,10 @@ and decode_expr v =
 				let final = if vfinal == vnull then false else decode_bool vfinal in
 				let vmeta = field v "meta" in
 				let meta = if vmeta == vnull then [] else decode_meta_content vmeta in
-				((decode_placed_name (field v "name_pos") (field v "name")),final,opt decode_ctype (field v "type"),opt loop (field v "expr"),meta)
+				let name = (decode_placed_name (field v "name_pos") (field v "name"))
+				and t = opt decode_ctype (field v "type")
+				and eo = opt loop (field v "expr") in
+				mk_evar ~final ?t ?eo ~meta name
 			) (decode_array vl))
 		| 11, [kind;f] ->
 			EFunction (decode_function_kind kind,decode_fun f)

+ 7 - 7
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,ml) ->
-				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,ml)
+			let vl = List.map (fun v ->
+				let e = (match v.ev_expr with None -> None | Some e -> Some (loop e)) in
+				decl (fst v.ev_name) (Option.map fst v.ev_type) e;
+				{ v with ev_expr = 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 [mk_evar ("`tmp",null_pos)],p);
 								(EFor(header,(EBinop (OpAssign,etmp,(EConst (Ident name),p)),p)), p);
 								etmp
 							],p));
@@ -815,9 +815,9 @@ let optimize_completion_expr e args =
 							let name = (try
 								PMap.find id (!tmp_hlocals)
 							with Not_found ->
-								let e = subst_locals lc e in
+								let eo = 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 := (mk_evar ~eo (name,null_pos)) :: !tmp_locals;
 								tmp_hlocals := PMap.add id name !tmp_hlocals;
 								name
 							) in

+ 3 - 3
src/syntax/grammar.mly

@@ -1163,7 +1163,7 @@ and parse_var_assignment = parser
 
 and parse_var_assignment_resume final vl name pn t meta s =
 	let eo = parse_var_assignment s in
-	((name,pn),final,t,eo,meta)
+	mk_evar ~final ?t ?eo ~meta (name,pn)
 
 and parse_var_decls_next final vl = parser
 	| [< '(Comma,p1); meta,name,final,t,pn = parse_var_decl_head final; s >] ->
@@ -1501,8 +1501,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); np = dollar_ident; >] -> EVars [mk_evar np],punion p1 (snd np)
+	| [< '(Kwd Final,p1); np = dollar_ident; >] -> EVars [mk_evar ~final:true np],punion p1 (snd np)
 	| [< e = secure_expr >] -> e
 
 and parse_switch_cases eswitch cases = parser

+ 6 - 6
src/syntax/reification.ml

@@ -278,13 +278,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,ml) p ->
+			expr "EVars" [to_array (fun v 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 ml p;
+					"name", to_string (fst v.ev_name) (snd v.ev_name);
+					"type", to_opt to_type_hint v.ev_type p;
+					"expr", to_opt to_expr v.ev_expr p;
+					"isFinal",to_bool v.ev_final p;
+					"meta",to_meta v.ev_meta p;
 				] in
 				to_obj fields p
 			) vl p]

+ 1 - 1
src/typing/macroContext.ml

@@ -730,7 +730,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 [mk_evar ~t:(CTAnonymous fields,p) ("fields",null_pos)],p)
 					)
 				| MMacroType ->
 					"ComplexType",(fun () ->

+ 1 - 1
src/typing/matcher.ml

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

+ 3 - 3
src/typing/typeloadFields.ml

@@ -226,7 +226,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 [mk_evar ~t:this_t ("this",null_pos)],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
@@ -419,7 +419,7 @@ let build_enum_abstract ctx c a fields p =
 		| _ ->
 			()
 	) fields;
-	EVars [("",null_pos),false,Some (CTAnonymous fields,p),None,[]],p
+	EVars [mk_evar ~t:(CTAnonymous fields,p) ("",null_pos)],p
 
 let apply_macro ctx mode path el p =
 	let cpath, meth = (match List.rev (ExtString.String.nsplit path ".") with
@@ -664,7 +664,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 [{ ev_type = Some (CTAnonymous f,p); ev_expr = 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

@@ -736,7 +736,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 [{ ev_type = Some (CTAnonymous fields,p); ev_expr = None }] ->
 				constructs := List.map (fun f ->
 					let args, params, t = (match f.cff_kind with
 					| FVar (t,None) -> [], [], t

+ 9 - 7
src/typing/typer.ml

@@ -1443,26 +1443,28 @@ 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,ml) ->
+	let vl = List.map (fun ev ->
+		let n = fst ev.ev_name
+		and pv = snd ev.ev_name in
 		try
-			let t = Typeload.load_type_hint ctx p t in
-			let e = (match e with
+			let t = Typeload.load_type_hint ctx p ev.ev_type in
+			let e = (match ev.ev_expr with
 				| None -> None
 				| Some e ->
 					let e = type_expr ctx e (WithType.with_type t) in
 					let e = AbstractCast.cast_or_unify ctx t e p in
 					Some e
 			) in
-			let v = add_local_with_origin ctx TVOLocalVariable v t pv in
-			v.v_meta <- ml;
-			if final then add_var_flag v VFinal;
+			let v = add_local_with_origin ctx TVOLocalVariable n t pv in
+			v.v_meta <- ev.ev_meta;
+			if ev.ev_final then add_var_flag v VFinal;
 			if ctx.in_display && DisplayPosition.display_position#enclosed_in pv then
 				DisplayEmitter.display_variable ctx v pv;
 			v,e
 		with
 			Error (e,p) ->
 				check_error ctx e p;
-				add_local ctx VGenerated v t_dynamic pv, None (* TODO: What to do with this... *)
+				add_local ctx VGenerated n t_dynamic pv, None (* TODO: What to do with this... *)
 	) vl in
 	delay ctx PTypeField (fun() ->
 		List.iter