Przeglądaj źródła

[display] clean up position handling

closes #5967
Simon Krajewski 7 lat temu
rodzic
commit
ed90ec4670

+ 2 - 5
src/context/display.ml

@@ -22,10 +22,7 @@ let is_display_file file =
 	file <> "?" && Path.unique_full_path file = (!Parser.resume_display).pfile
 
 let encloses_position p_target p =
-	p.pmin <= p_target.pmin && p.pmax >= p_target.pmax
-
-let really_encloses_position p_target p =
-	p.pmin <= p_target.pmin && p.pmax > p_target.pmax
+	p.pmin < p_target.pmin && p.pmax >= p_target.pmax
 
 let is_display_position p =
 	encloses_position !Parser.resume_display p
@@ -33,7 +30,7 @@ let is_display_position p =
 module ExprPreprocessing = struct
 	let find_before_pos com is_completion e =
 		let display_pos = ref (!Parser.resume_display) in
-		let is_annotated p = p.pmin < !display_pos.pmin && p.pmax >= !display_pos.pmax in
+		let is_annotated p = encloses_position !display_pos p in
 		let annotate e dk =
 			display_pos := { pfile = ""; pmin = -2; pmax = -2 };
 			(EDisplay(e,dk),pos e)

+ 115 - 0
src/core/ast.ml

@@ -908,4 +908,119 @@ module Expr = struct
 			loop fl
 		with Exit ->
 			true
+
+	let dump_with_pos e =
+		let buf = Buffer.create 0 in
+		let add = Buffer.add_string buf in
+		let rec loop' tabs (e,p) =
+			let add s = add (Printf.sprintf "%4i-%4i %s%s\n" p.pmin p.pmax tabs s) in
+			let loop e = loop' (tabs ^ "  ") e in
+			match e with
+			| EConst ct -> add (s_constant ct)
+			| EArray(e1,e2) ->
+				add "EArray";
+				loop e1;
+				loop e2;
+			| EBinop(op,e1,e2) ->
+				add ("EBinop " ^ (s_binop op));
+				loop e1;
+				loop e2;
+			| EField(e1,s) ->
+				add ("EField " ^ s);
+				loop e1
+			| EParenthesis e1 ->
+				add "EParenthesis";
+				loop e1
+			| EObjectDecl fl ->
+				add "EObjectDecl";
+				List.iter (fun ((n,p,_),e1) ->
+					loop' (Printf.sprintf "%s  %s" tabs n) e1
+				) fl;
+			| EArrayDecl el ->
+				add "EArrayDecl";
+				List.iter loop el
+			| ECall(e1,el) ->
+				add "ECall";
+				loop e1;
+				List.iter loop el
+			| ENew((tp,_),el) ->
+				add ("ENew " ^ s_type_path(tp.tpackage,tp.tname));
+				List.iter loop el
+			| EUnop(op,_,e1) ->
+				add ("EUnop " ^ (s_unop op));
+				loop e1
+			| EVars vl ->
+				add "EVars";
+				List.iter (fun ((n,p),_,eo) -> match eo with
+					| None -> ()
+					| Some e -> loop' (Printf.sprintf "%s  %s" tabs n) e
+				) vl
+			| EFunction(so,f) ->
+				add "EFunction";
+				Option.may loop f.f_expr;
+			| EBlock el ->
+				add "EBlock";
+				List.iter loop el
+			| EFor(e1,e2) ->
+				add "EFor";
+				loop e1;
+				loop e2;
+			| EIf(e1,e2,eo) ->
+				add "EIf";
+				loop e1;
+				loop e2;
+				Option.may loop eo;
+			| EWhile(e1,e2,_) ->
+				add "EWhile";
+				loop e1;
+				loop e2;
+			| ESwitch(e1,cases,def) ->
+				add "ESwitch";
+				loop e1;
+				List.iter (fun (el,eg,eo,p) ->
+					List.iter (loop' (tabs ^ "    ")) el;
+					Option.may (loop' (tabs ^ "      ")) eo;
+				) cases;
+				Option.may (fun (eo,_) -> Option.may (loop' (tabs ^ "      ")) eo) def
+			| ETry(e1,catches) ->
+				add "ETry";
+				loop e1;
+				List.iter (fun (_,_,e,_) ->
+					loop' (tabs ^ "    ") e
+				) catches
+			| EReturn eo ->
+				add "EReturn";
+				Option.may loop eo;
+			| EBreak ->
+				add "EBreak";
+			| EContinue ->
+				add "EContinue"
+			| EUntyped e1 ->
+				add "EUntyped";
+				loop e1;
+			| EThrow e1 ->
+				add "EThrow";
+				loop e1
+			| ECast(e1,_) ->
+				add "ECast";
+				loop e1;
+			| EDisplay(e1,dk) ->
+				add ("EDisplay " ^ (s_display_kind dk));
+				loop e1
+			| ETernary(e1,e2,e3) ->
+				add "ETernary";
+				loop e1;
+				loop e2;
+				loop e3;
+			| ECheckType(e1,_) ->
+				add "ECheckType";
+				loop e1;
+			| EMeta((m,_,_),e1) ->
+				add ("EMeta " ^ fst (Meta.get_info m));
+				loop e1
+			| EDisplayNew _ ->
+				assert false
+		in
+		loop' "" e;
+		Buffer.contents buf
 end

+ 5 - 7
src/syntax/grammar.mly

@@ -350,7 +350,7 @@ and parse_meta_entry = parser
 	[< '(At,p1); s >] ->
 		let meta = check_resume p1 (fun () -> Some (Meta.Last,[],p1)) (fun () -> None) in
 		match s with parser
-		| [< name,p = parse_meta_name p1; params = parse_meta_params p; s >] -> (name,params,p)
+		| [< name,p = parse_meta_name p1; params = parse_meta_params p; s >] -> (name,params,punion p1 p)
 		| [< >] -> match meta with None -> serror() | Some meta -> meta
 
 and parse_meta = parser
@@ -801,7 +801,7 @@ and parse_array_decl p1 s =
 	in
 	let resume_or_fail p1 =
 		if do_resume () then begin
-			let p = punion p1 (pos (next_token s)) in
+			let p = punion_next p1 s in
 			[mk_null_expr p],p
 		end else serror()
 	in
@@ -1179,9 +1179,7 @@ and parse_call_params f p1 s =
 			expr s
 		with
 		| Stream.Error _ | Stream.Failure as exc ->
-			let p2 = pos (next_token s) in
-			if do_resume() then
-				mk_null_expr (punion p1 p2)
+			if do_resume() then mk_null_expr (punion_next p1 s)
 			else raise exc
 		| Display e ->
 			display (f (List.rev (e :: acc)) (pos e))
@@ -1209,12 +1207,12 @@ and toplevel_expr s =
 and secure_expr s =
 	match s with parser
 	| [< e = expr >] -> e
-	| [< >] -> if do_resume() then mk_null_expr (punion (pos (last_token s)) (pos (next_token s))) else serror()
+	| [< >] -> if do_resume() then mk_null_expr (punion_next (pos (last_token s)) s) else serror()
 
 and expr_or_fail fail s =
 	match s with parser
 	| [< e = expr >] -> e
-	| [< >] -> if do_resume() then mk_null_expr (punion (pos (last_token s)) (pos (next_token s))) else fail()
+	| [< >] -> if do_resume() then mk_null_expr (punion_next (pos (last_token s)) s) else fail()
 
 let rec validate_macro_cond e = match fst e with
 	| EConst (Ident _)

+ 9 - 3
src/syntax/parser.ml

@@ -119,7 +119,7 @@ let set_resume p =
 let had_resume = ref false
 
 let encloses_resume p =
-	p.pmin <= !resume_display.pmin && p.pmax >= !resume_display.pmax
+	p.pmin < !resume_display.pmin && p.pmax >= !resume_display.pmax
 
 let would_skip_resume p1 s =
 	match Stream.npeek 1 s with
@@ -199,9 +199,15 @@ let next_token s = match Stream.peek s with
 	| Some tk -> tk
 	| _ -> last_token s
 
-let mk_null_expr p = (EConst(Ident "null"),p)
+let punion_next p1 s =
+	let _,p2 = next_token s in
+	{
+		pfile = p1.pfile;
+		pmin = p1.pmin;
+		pmax = p2.pmax - 1;
+	}
 
-let mk_display_expr p = (EDisplay(mk_null_expr p,DKMarked),p)
+let mk_null_expr p = (EConst(Ident "null"),p)
 
 let check_resume p fyes fno =
 	if !is_completion && is_resuming p then (had_resume := true; fyes()) else fno()

+ 15 - 0
tests/display/src/cases/Issue5967.hx

@@ -0,0 +1,15 @@
+package cases;
+
+class Issue5967 extends DisplayTestCase {
+	/**
+	function call():Void { };
+	call({-1-}a{-2-},{-3-},{-4-} {-5-}
+	**/
+	@:funcCode function test1() {
+		sigEq(0, [[]], signature(pos(1)));
+		sigEq(0, [[]], signature(pos(2)));
+		sigEq(1, [[]], signature(pos(3)));
+		sigEq(2, [[]], signature(pos(4)));
+		sigEq(2, [[]], signature(pos(5)));
+	}
+}