Selaa lähdekoodia

add positions to property accessors (closes #5533)

Simon Krajewski 9 vuotta sitten
vanhempi
commit
6bccdd64ba

+ 2 - 2
src/generators/gencs.ml

@@ -3573,7 +3573,7 @@ let convert_ilfield ctx p field =
 	let kind = match readonly with
 		| true ->
 			cff_meta := (Meta.ReadOnly, [], cff_pos) :: !cff_meta;
-			FProp ("default", "never", Some (convert_signature ctx p field.fsig.snorm,null_pos), None)
+			FProp (("default",null_pos), ("never",null_pos), Some (convert_signature ctx p field.fsig.snorm,null_pos), None)
 		| false ->
 			FVar (Some (convert_signature ctx p field.fsig.snorm,null_pos), None)
 	in
@@ -3809,7 +3809,7 @@ let convert_ilprop ctx p prop is_explicit_impl =
 	in
 
 	let kind =
-		FProp (get, set, Some(convert_signature ctx p ilsig,null_pos), None)
+		FProp ((get,null_pos), (set,null_pos), Some(convert_signature ctx p ilsig,null_pos), None)
 	in
 	{
 		cff_name = prop.pname,null_pos;

+ 1 - 1
src/generators/genjava.ml

@@ -2789,7 +2789,7 @@ let convert_java_enum ctx p pe =
 
 		let kind = match field.jf_kind with
 			| JKField when !readonly ->
-				FProp ("default", "null", Some (convert_signature ctx p field.jf_signature,null_pos), None)
+				FProp (("default",null_pos), ("null",null_pos), Some (convert_signature ctx p field.jf_signature,null_pos), None)
 			| JKField ->
 				FVar (Some (convert_signature ctx p field.jf_signature,null_pos), None)
 			| JKMethod ->

+ 3 - 3
src/generators/genswf.ml

@@ -197,7 +197,7 @@ let build_class com c file =
 		match f.hlf_kind with
 		| HFVar v ->
 			if v.hlv_const then
-				cf.cff_kind <- FProp ("default","never",Some (make_type v.hlv_type,null_pos),None)
+				cf.cff_kind <- FProp (("default",null_pos),("never",null_pos),Some (make_type v.hlv_type,null_pos),None)
 			else
 				cf.cff_kind <- FVar (Some (make_dyn_type v.hlv_type,null_pos),None);
 			cf :: acc
@@ -302,7 +302,7 @@ let build_class com c file =
 			cff_doc = None;
 			cff_access = flags;
 			cff_meta = [];
-			cff_kind = if get && set then FVar (Some (make_dyn_type t,null_pos), None) else FProp ((if get then "default" else "never"),(if set then "default" else "never"),Some (make_dyn_type t,null_pos),None);
+			cff_kind = if get && set then FVar (Some (make_dyn_type t,null_pos), None) else FProp (((if get then "default" else "never"),null_pos),((if set then "default" else "never"),null_pos),Some (make_dyn_type t,null_pos),None);
 		}
 	in
 	let fields = Hashtbl.fold (fun (name,stat) t acc ->
@@ -325,7 +325,7 @@ let build_class com c file =
 			| f :: l ->
 				match f.cff_kind with
 				| FVar (Some (CTPath { tpackage = []; tname = ("String" | "Int" | "UInt") as tname },null_pos),None)
-				| FProp ("default","never",Some (CTPath { tpackage = []; tname = ("String" | "Int" | "UInt") as tname },null_pos),None) when List.mem AStatic f.cff_access ->
+				| FProp (("default",_),("never",_),Some (CTPath { tpackage = []; tname = ("String" | "Int" | "UInt") as tname },null_pos),None) when List.mem AStatic f.cff_access ->
 					if !real_type = "" then real_type := tname else if !real_type <> tname then raise Exit;
 					{
 						ec_name = f.cff_name;

+ 2 - 2
src/macro/interp.ml

@@ -4008,7 +4008,7 @@ and encode_field (f:class_field) =
 	let tag, pl = match f.cff_kind with
 		| FVar (t,e) -> 0, [null encode_ctype t; null encode_expr e]
 		| FFun f -> 1, [encode_fun f]
-		| FProp (get,set, t, e) -> 2, [enc_string get; enc_string set; null encode_ctype t; null encode_expr e]
+		| FProp (get,set, t, e) -> 2, [encode_placed_name get; encode_placed_name set; null encode_ctype t; null encode_expr e]
 	in
 	enc_obj [
 		"name",encode_placed_name f.cff_name;
@@ -4343,7 +4343,7 @@ and decode_field v =
 		| 1, [f] ->
 			FFun (decode_fun f)
 		| 2, [get;set; t; e] ->
-			FProp (dec_string get, dec_string set, opt decode_ctype t, opt decode_expr e)
+			FProp (decode_placed_name get VNull, decode_placed_name set VNull, opt decode_ctype t, opt decode_expr e)
 		| _ ->
 			raise Invalid_expr
 	in

+ 2 - 2
src/syntax/ast.ml

@@ -225,7 +225,7 @@ and access =
 and class_field_kind =
 	| FVar of type_hint option * expr option
 	| FFun of func
-	| FProp of string * string * type_hint option * expr option
+	| FProp of placed_name * placed_name * type_hint option * expr option
 
 and class_field = {
 	cff_name : placed_name;
@@ -684,7 +684,7 @@ let s_expr e =
 		if List.length f.cff_access > 0 then String.concat " " (List.map s_access f.cff_access) else "" ^
 		match f.cff_kind with
 		| FVar (t,e) -> "var " ^ (fst f.cff_name) ^ s_opt_type_hint tabs t " : " ^ s_opt_expr tabs e " = "
-		| FProp (get,set,t,e) -> "var " ^ (fst f.cff_name) ^ "(" ^ get ^ "," ^ set ^ ")" ^ s_opt_type_hint tabs t " : " ^ s_opt_expr tabs e " = "
+		| FProp ((get,_),(set,_),t,e) -> "var " ^ (fst f.cff_name) ^ "(" ^ get ^ "," ^ set ^ ")" ^ s_opt_type_hint tabs t " : " ^ s_opt_expr tabs e " = "
 		| FFun func -> "function " ^ (fst f.cff_name) ^ s_func tabs func
 	and s_metadata tabs (s,e,_) =
 		"@" ^ Meta.to_string s ^ if List.length e > 0 then "(" ^ s_expr_list tabs e ", " ^ ")" else ""

+ 5 - 5
src/syntax/parser.ml

@@ -324,7 +324,7 @@ let reify in_macro =
 			let n, vl = (match k with
 				| FVar (ct,e) -> "FVar", [to_opt to_type_hint ct p;to_opt to_expr e p]
 				| FFun f -> "FFun", [to_fun f p]
-				| FProp (get,set,t,e) -> "FProp", [to_string get p; to_string set p; to_opt to_type_hint t p; to_opt to_expr e p]
+				| FProp (get,set,t,e) -> "FProp", [to_placed_name get; to_placed_name set; to_opt to_type_hint t p; to_opt to_expr e p]
 			) in
 			mk_enum "FieldType" n vl p
 		in
@@ -562,10 +562,10 @@ let lower_ident_or_macro = parser
 	| [< '(Kwd Extern,_) >] -> "extern"
 
 let property_ident = parser
-	| [< i, _ = ident >] -> i
-	| [< '(Kwd Dynamic,_) >] -> "dynamic"
-	| [< '(Kwd Default,_) >] -> "default"
-	| [< '(Kwd Null,_) >] -> "null"
+	| [< i,p = ident >] -> i,p
+	| [< '(Kwd Dynamic,p) >] -> "dynamic",p
+	| [< '(Kwd Default,p) >] -> "default",p
+	| [< '(Kwd Null,p) >] -> "null",p
 
 let get_doc s =
 	(* do the peek first to make sure we fetch the doc *)

+ 38 - 28
src/typing/typeload.ml

@@ -33,7 +33,7 @@ let transform_abstract_field com this_t a_t a f =
 	let stat = List.mem AStatic f.cff_access in
 	let p = f.cff_pos in
 	match f.cff_kind with
-	| FProp (("get" | "never"),("set" | "never"),_,_) when not stat ->
+	| FProp ((("get" | "never"),_),(("set" | "never"),_),_,_) when not stat ->
 		(* TODO: hack to avoid issues with abstract property generation on As3 *)
 		if Common.defined com Define.As3 then f.cff_meta <- (Meta.Extern,[],null_pos) :: f.cff_meta;
 		{ f with cff_access = AStatic :: f.cff_access; cff_meta = (Meta.Impl,[],null_pos) :: f.cff_meta }
@@ -627,7 +627,7 @@ and load_complex_type ctx allow_display p (t,pn) =
 					t
 				| FProp (i1,i2,t,e) ->
 					no_expr e;
-					let access m get =
+					let access (m,_) get =
 						match m with
 						| "null" -> AccNo
 						| "never" -> AccNever
@@ -1818,7 +1818,7 @@ let build_enum_abstract ctx c a fields p =
 			begin match eo with
 				| None ->
 					if not c.cl_extern then error "Value required" field.cff_pos
-					else field.cff_kind <- FProp("default","never",ct,None)
+					else field.cff_kind <- FProp(("default",null_pos),("never",null_pos),ct,None)
 				| Some e ->
 					field.cff_access <- AInline :: field.cff_access;
 					let e = (ECast(e,None),(pos e)) in
@@ -2586,24 +2586,25 @@ module ClassInitializer = struct
 				tfun [ta] ret, tfun [ta;ret] ret
 			| _ -> tfun [] ret, TFun(["value",false,ret],ret)
 		in
+		let find_accessor m =
+			(* on pf_overload platforms, the getter/setter may have been defined as an overloaded function; get all overloads *)
+			if ctx.com.config.pf_overload then
+				if fctx.is_static then
+					let f = PMap.find m c.cl_statics in
+					(f.cf_type, f) :: (List.map (fun f -> f.cf_type, f) f.cf_overloads)
+				else
+					Overloads.get_overloads c m
+			else
+				[ if fctx.is_static then
+					let f = PMap.find m c.cl_statics in
+					f.cf_type, f
+				else match class_field c (List.map snd c.cl_params) m with
+					| _, t,f -> t,f ]
+		in
 		let check_method m t req_name =
 			if ctx.com.display.dms_error_policy = EPIgnore then () else
 			try
-				let overloads =
-					(* on pf_overload platforms, the getter/setter may have been defined as an overloaded function; get all overloads *)
-					if ctx.com.config.pf_overload then
-						if fctx.is_static then
-							let f = PMap.find m c.cl_statics in
-							(f.cf_type, f) :: (List.map (fun f -> f.cf_type, f) f.cf_overloads)
-						else
-							Overloads.get_overloads c m
-					else
-						[ if fctx.is_static then
-							let f = PMap.find m c.cl_statics in
-							f.cf_type, f
-						else match class_field c (List.map snd c.cl_params) m with
-							| _, t,f -> t,f ]
-				in
+				let overloads = find_accessor m in
 				(* choose the correct overload if and only if there is more than one overload found *)
 				let rec get_overload overl = match overl with
 					| [tf] -> tf
@@ -2654,28 +2655,37 @@ module ClassInitializer = struct
 							display_error ctx ("Method " ^ m ^ " required by property " ^ name ^ " is missing") p
 					end
 		in
+		let display_accessor m p =
+			try
+				let cf = match find_accessor m with [_,cf] -> cf | _ -> raise Not_found in
+				Display.DisplayEmitter.display_field ctx.com.display cf p
+			with Not_found ->
+				()
+		in
 		let get = (match get with
-			| "null" -> AccNo
-			| "dynamic" -> AccCall
-			| "never" -> AccNever
-			| "default" -> AccNormal
-			| _ ->
+			| "null",_ -> AccNo
+			| "dynamic",_ -> AccCall
+			| "never",_ -> AccNever
+			| "default",_ -> AccNormal
+			| get,pget ->
 				let get = if get = "get" then "get_" ^ name else get in
+				if fctx.is_display_field && Display.is_display_position pget then delay ctx PTypeField (fun () -> display_accessor get pget);
 				if not cctx.is_lib then delay ctx PTypeField (fun() -> check_method get t_get (if get <> "get" && get <> "get_" ^ name then Some ("get_" ^ name) else None));
 				AccCall
 		) in
 		let set = (match set with
-			| "null" ->
+			| "null",_ ->
 				(* standard flash library read-only variables can't be accessed for writing, even in subclasses *)
 				if c.cl_extern && (match c.cl_path with "flash" :: _	, _ -> true | _ -> false) && ctx.com.platform = Flash then
 					AccNever
 				else
 					AccNo
-			| "never" -> AccNever
-			| "dynamic" -> AccCall
-			| "default" -> AccNormal
-			| _ ->
+			| "never",_ -> AccNever
+			| "dynamic",_ -> AccCall
+			| "default",_ -> AccNormal
+			| set,pset ->
 				let set = if set = "set" then "set_" ^ name else set in
+				if fctx.is_display_field && Display.is_display_position pset then delay ctx PTypeField (fun () -> display_accessor set pset);
 				if not cctx.is_lib then delay ctx PTypeField (fun() -> check_method set t_set (if set <> "set" && set <> "set_" ^ name then Some ("set_" ^ name) else None));
 				AccCall
 		) in

+ 20 - 0
tests/display/src/cases/PropertyAccessors.hx

@@ -0,0 +1,20 @@
+package cases;
+
+class PropertyAccessors extends DisplayTestCase {
+	/**
+	class Main {
+		static var test(ge{-1-}t, se{-2-}t):String;
+
+		static public {-3-}function get_test() return "foo"{-4-};
+		static public {-5-}function set_test(s:String) return s{-6-};
+
+		static function main() { }
+	}
+	**/
+	function test() {
+		eq(range(3, 4), position(pos(1)));
+		eq(range(5, 6), position(pos(2)));
+		eq("Void -> String", type(pos(1)));
+		eq("s : String -> String", type(pos(2)));
+	}
+}