浏览代码

[display] rework EDisplay handling

The parser can now communicate where it inserted the EDisplay node so we can distinguish them.
Simon Krajewski 7 年之前
父节点
当前提交
5db2f59c8a

+ 11 - 11
src/context/display.ml

@@ -44,9 +44,9 @@ let is_display_position p =
 	encloses_position !Parser.resume_display p
 
 module ExprPreprocessing = struct
-	let find_enclosing com e =
+	let find_enclosing com dk e =
 		let display_pos = ref (!Parser.resume_display) in
-		let mk_null p = (EDisplay(((EConst(Ident "null")),p),false),p) in
+		let mk_null p = (EDisplay(((EConst(Ident "null")),p),dk),p) in
 		let encloses_display_pos p =
 			if encloses_position !display_pos p then begin
 				let p = !display_pos in
@@ -69,7 +69,7 @@ module ExprPreprocessing = struct
 							if b || p.pmax <= p2.pmin then begin
 								(b,e :: el)
 							end else begin
-								let e_d = (EDisplay(mk_null p,false)),p in
+								let e_d = (EDisplay(mk_null p,dk)),p in
 								(true,e :: e_d :: el)
 							end
 						) (false,[]) el in
@@ -86,7 +86,7 @@ module ExprPreprocessing = struct
 		in
 		loop e
 
-	let find_before_pos com e =
+	let find_before_pos com dk e =
 		let display_pos = ref (!Parser.resume_display) in
 		let is_annotated p =
 			if p.pmin <= !display_pos.pmin && p.pmax >= !display_pos.pmax then begin
@@ -97,7 +97,7 @@ module ExprPreprocessing = struct
 		in
 		let loop e =
 			if is_annotated (pos e) then
-				(EDisplay(e,false),(pos e))
+				(EDisplay(e,dk),(pos e))
 			else
 				e
 		in
@@ -109,25 +109,25 @@ module ExprPreprocessing = struct
 	let find_display_call e =
 		let found = ref false in
 		let loop e = if !found then e else match fst e with
-			| ECall _ | ENew _ | EObjectDecl _ when is_display_position (pos e) ->
+			| ECall _ | ENew _ when is_display_position (pos e) ->
 				found := true;
-				(EDisplay(e,true),(pos e))
+				(EDisplay(e,DKCall),(pos e))
 			| _ ->
 				e
 		in
 		let rec map e = match fst e with
-			| EDisplay(_,true) ->
+			| EDisplay(_,DKCall) ->
 				found := true;
 				e
-			| EDisplay(e1,false) -> map e1
+			| EDisplay(e1,_) -> map e1
 			| _ -> loop (Ast.map_expr map e)
 		in
 		map e
 
 
 	let process_expr com e = match com.display.dms_kind with
-		| DMToplevel -> find_enclosing com e
-		| DMPosition | DMUsage _ | DMType -> find_before_pos com e
+		| DMToplevel -> find_enclosing com DKToplevel e
+		| DMPosition | DMUsage _ | DMType -> find_before_pos com DKMarked e
 		| DMSignature -> find_display_call e
 		| _ -> e
 end

+ 1 - 1
src/context/displayFields.ml

@@ -31,7 +31,7 @@ let get_submodule_fields ctx path =
 	) tl in
 	tl
 
-let collect ctx e_ast e with_type p =
+let collect ctx e_ast e dk with_type p =
 	let merge_core_doc = !merge_core_doc_ref in
 	let opt_args args ret = TFun(List.map(fun (n,o,t) -> n,true,t) args,ret) in
 	let e = match e.eexpr with

+ 16 - 2
src/core/ast.ml

@@ -174,6 +174,13 @@ and func = {
 
 and placed_name = string * pos
 
+and display_kind =
+	| DKCall
+	| DKDot
+	| DKStructure
+	| DKToplevel
+	| DKMarked
+
 and expr_def =
 	| EConst of constant
 	| EArray of expr * expr
@@ -199,7 +206,7 @@ and expr_def =
 	| EUntyped of expr
 	| EThrow of expr
 	| ECast of expr * type_hint option
-	| EDisplay of expr * bool
+	| EDisplay of expr * display_kind
 	| EDisplayNew of placed_type_path
 	| ETernary of expr * expr * expr
 	| ECheckType of expr * type_hint
@@ -700,6 +707,13 @@ let s_object_key_name name =  function
 	| DoubleQuotes -> "\"" ^ s_escape name ^ "\""
 	| NoQuotes -> name
 
+let s_display_kind = function
+	| DKCall -> "DKCall"
+	| DKDot -> "DKDot"
+	| DKStructure -> "DKStructure"
+	| DKToplevel -> "DKToplevel"
+	| DKMarked -> "TKMarked"
+
 let s_expr e =
 	let rec s_expr_inner tabs (e,_) =
 		match e with
@@ -738,7 +752,7 @@ let s_expr e =
 		| ETernary (e1,e2,e3) -> s_expr_inner tabs e1 ^ " ? " ^ s_expr_inner tabs e2 ^ " : " ^ s_expr_inner tabs e3
 		| ECheckType (e,(t,_)) -> "(" ^ s_expr_inner tabs e ^ " : " ^ s_complex_type tabs t ^ ")"
 		| EMeta (m,e) -> s_metadata tabs m ^ " " ^ s_expr_inner tabs e
-		| EDisplay (e1,iscall) -> Printf.sprintf "#DISPLAY(%s, %b)" (s_expr_inner tabs e1) iscall
+		| EDisplay (e1,dk) -> Printf.sprintf "#DISPLAY(%s, %s)" (s_expr_inner tabs e1) (s_display_kind dk)
 		| EDisplayNew tp -> Printf.sprintf "#DISPLAY_NEW(%s)" (s_complex_type_path tabs tp)
 	and s_expr_list tabs el sep =
 		(String.concat sep (List.map (s_expr_inner tabs) el))

+ 22 - 4
src/macro/macroApi.ml

@@ -469,6 +469,16 @@ and encode_fun f =
 		"expr", null encode_expr f.f_expr
 	]
 
+and encode_display_kind dk =
+	let tag = match dk with
+	| DKCall -> 0
+	| DKDot -> 1
+	| DKStructure -> 2
+	| DKToplevel -> 3
+	| DKMarked -> 4
+	in
+	encode_enum ~pos:None ICType tag []
+
 and encode_expr e =
 	let rec loop (e,p) =
 		let tag, pl = match e with
@@ -547,8 +557,8 @@ and encode_expr e =
 				22, [loop e]
 			| ECast (e,t) ->
 				23, [loop e; null encode_ctype t]
-			| EDisplay (e,flag) ->
-				24, [loop e; vbool flag]
+			| EDisplay (e,dk) ->
+				24, [loop e; encode_display_kind dk]
 			| EDisplayNew t ->
 				25, [encode_path t]
 			| ETernary (econd,e1,e2) ->
@@ -745,6 +755,14 @@ and decode_ctype t =
 	| _ ->
 		raise Invalid_expr),p
 
+and decode_display_kind v = match fst (decode_enum v) with
+	| 0 -> DKCall
+	| 1 -> DKDot
+	| 2 -> DKStructure
+	| 3 -> DKToplevel
+	| 4 -> DKMarked
+	| _ -> raise Invalid_expr
+
 and decode_expr v =
 	let rec loop v =
 		let p = decode_pos (field v "pos") in
@@ -817,8 +835,8 @@ and decode_expr v =
 			EThrow (loop e)
 		| 23, [e;t] ->
 			ECast (loop e,opt decode_ctype t)
-		| 24, [e;f] ->
-			EDisplay (loop e,decode_bool f)
+		| 24, [e;dk] ->
+			EDisplay (loop e,decode_display_kind dk)
 		| 25, [t] ->
 			EDisplayNew (decode_path t)
 		| 26, [e1;e2;e3] ->

+ 3 - 0
src/optimization/optimizer.ml

@@ -1251,6 +1251,7 @@ let optimize_completion_expr e =
 		typing_side_effect := true;
 		locals.r <- PMap.add n (t,(match e with Some e when maybe_typed e -> incr iid; Some (!iid,e,{ r = locals.r }) | _ -> None)) locals.r
 	in
+	let e0 = e in
 	let rec loop e =
 		let p = snd e in
 		match fst e with
@@ -1351,6 +1352,8 @@ let optimize_completion_expr e =
 				(n,pn), (t,pt), e, p
 			) cl in
 			(ETry (et,cl),p)
+		| EDisplay(_,DKStructure) ->
+			raise (Return e0)
 		| EDisplay (s,call) ->
 			typing_side_effect := true;
 			let tmp_locals = ref [] in

+ 25 - 15
src/syntax/grammar.mly

@@ -715,8 +715,7 @@ and block2 name ident p s =
 			let e = EObjectDecl acc,punion p (pos e) in
 			display e
 		in
-		let fl = parse_obj_decl name e p s in
-		EObjectDecl fl
+		fst (parse_obj_decl name e p s)
 	| [< >] ->
 		let e = expr_next (EConst ident,p) s in
 		try
@@ -754,8 +753,13 @@ and parse_block_elt = parser
 	| [< e = expr; _ = semicolon >] -> e
 
 and parse_obj_decl name e p0 s =
-	let rec loop acc = match s with parser
+	let has_resume = ref false in
+	let make_obj_decl el p1 =
+		EObjectDecl (List.rev el),punion p0 p1
+	in
+	let rec loop p_end acc = match s with parser
 		| [< '(Comma,p1); s >] ->
+			if is_resuming p1 then has_resume := true;
 			let next key = match s with parser
 				| [< '(DblDot,_) >] ->
 					let e = try
@@ -765,10 +769,10 @@ and parse_obj_decl name e p0 s =
 						end
 					with Display e ->
 						let acc = (key,e) :: acc in
-						let e = EObjectDecl (List.rev acc),punion p0 (pos e) in
+						let e = make_obj_decl acc (pos e) in
 						display e
 					in
-					loop ((key,e) :: acc)
+					loop (pos e) ((key,e) :: acc)
 				| [< >] -> serror()
 			in
 			begin match s with parser
@@ -777,15 +781,21 @@ and parse_obj_decl name e p0 s =
 				| [< >] ->
 					let p2 = pos (next_token s) in
 					if encloses_resume (punion p1 p2) then begin
-						let e = EObjectDecl (List.rev acc),punion p0 p2 in
-						let e = EDisplay(e,false),(pos e) in
+						let e = make_obj_decl acc p2 in
+						let e = EDisplay(e,DKStructure),(pos e) in
 						display e
 					end else
-						acc
+						acc,p_end
 			end
-		| [< >] -> acc
+		| [< >] -> acc,p_end
 	in
-	List.rev (loop [name,e])
+	let el,p_end = loop p0 [name,e] in
+	let e = make_obj_decl el p_end in
+	if !has_resume then begin
+		let e = EDisplay(e,DKStructure),(pos e) in
+		display e
+	end else
+		e
 
 and parse_array_decl p1 s =
 	let secure_expr acc s = try
@@ -921,11 +931,11 @@ and expr = parser
 			display (make_meta name params e p)
 		end
 	| [< '(BrOpen,p1); s >] ->
-		if is_resuming p1 then display (EDisplay ((EObjectDecl [],p1),false),p1);
+		if is_resuming p1 then display (EDisplay ((EObjectDecl [],p1),DKStructure),p1);
 		(match s with parser
 		| [< '(Binop OpOr,p2) when do_resume() >] ->
 			set_resume p1;
-			display (EDisplay ((EObjectDecl [],p1),false),p1);
+			display (EDisplay ((EObjectDecl [],p1),DKStructure),p1);
 		| [< b = block1; s >] ->
 			let p2 = match s with parser
 				| [< '(BrClose,p2) >] -> p2
@@ -1055,7 +1065,7 @@ and expr_next e1 = parser
 		| EConst(Ident n) -> expr_next (EMeta((Meta.from_string n,[],snd e1),eparam), punion p1 p2) s
 		| _ -> assert false)
 	| [< '(Dot,p); s >] ->
-		if is_resuming p then display (EDisplay (e1,false),p);
+		if is_resuming p then display (EDisplay (e1,DKDot),p);
 		(match s with parser
 		| [< '(Kwd Macro,p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,"macro") , punion (pos e1) p2) s
 		| [< '(Kwd Extern,p2) when p.pmax = p2.pmin; s >] -> expr_next (EField (e1,"extern") , punion (pos e1) p2) s
@@ -1064,7 +1074,7 @@ and expr_next e1 = parser
 		| [< '(Dollar v,p2); s >] -> expr_next (EField (e1,"$"^v) , punion (pos e1) p2) s
 		| [< '(Binop OpOr,p2) when do_resume() >] ->
 			set_resume p;
-			display (EDisplay (e1,false),p) (* help for debug display mode *)
+			display (EDisplay (e1,DKDot),p) (* help for debug display mode *)
 		| [< >] ->
 			(* turn an integer followed by a dot into a float *)
 			match e1 with
@@ -1157,7 +1167,7 @@ and parse_catches etry catches pmax = parser
 and parse_call_params f p1 s =
 	let make_display_call el p2 =
 		let e = f el p2 in
-		display (EDisplay(e,true),pos e)
+		display (EDisplay(e,DKCall),pos e)
 	in
 	if is_resuming p1 then make_display_call [] p1;
 	let rec parse_next_param acc p1 =

+ 3 - 2
src/syntax/reification.ml

@@ -140,6 +140,7 @@ let reify in_macro =
 	and to_type_hint (t,p) _ =
 		(* to_obj ["type",to_ctype t p;"pos",to_pos p] p *)
 		to_ctype (t,p) p
+	and to_display_kind dk p = mk_enum "DisplayKind" (s_display_kind dk) [] p
 	and to_fun f p =
 		let p = {p with pmax = p.pmin} in
 		let farg ((n,_),o,_,t,e) p =
@@ -323,8 +324,8 @@ let reify in_macro =
 			expr "EThrow" [loop e]
 		| ECast (e,ct) ->
 			expr "ECast" [loop e; to_opt to_type_hint ct p]
-		| EDisplay (e,flag) ->
-			expr "EDisplay" [loop e; to_bool flag p]
+		| EDisplay (e,dk) ->
+			expr "EDisplay" [loop e; to_display_kind dk p]
 		| EDisplayNew t ->
 			expr "EDisplayNew" [to_tpath t p]
 		| ETernary (e1,e2,e3) ->

+ 15 - 9
src/typing/forLoop.ml

@@ -219,17 +219,17 @@ let optimize_for_loop_iterator ctx v e1 e2 p =
 	]) ctx.t.tvoid p
 
 let type_for_loop ctx handle_display it e2 p =
-	let rec loop_ident display e1 = match e1 with
-		| EConst(Ident i),p -> i,p,display
-		| EDisplay(e1,_),_ -> loop_ident true e1
+	let rec loop_ident dko e1 = match e1 with
+		| EConst(Ident i),p -> i,p,dko
+		| EDisplay(e1,dk),_ -> loop_ident (Some dk) e1
 		| _ -> error "Identifier expected" (pos e1)
 	in
-	let rec loop display e1 = match fst e1 with
-		| EBinop(OpIn,e1,e2) -> loop_ident display e1,e2
-		| EDisplay(e1,_) -> loop true e1
+	let rec loop dko e1 = match fst e1 with
+		| EBinop(OpIn,e1,e2) -> loop_ident dko e1,e2
+		| EDisplay(e1,dk) -> loop (Some dk) e1
 		| _ -> error "For expression should be 'v in expr'" (snd it)
 	in
-	let (i, pi, display), e1 = loop false it in
+	let (i, pi, dko), e1 = loop None it in
 	let e1 = type_expr ctx e1 Value in
 	let old_loop = ctx.in_loop in
 	let old_locals = save_locals ctx in
@@ -259,13 +259,19 @@ let type_for_loop ctx handle_display it e2 p =
 					mk (TConst TNull) t_dynamic p
 			)
 		) in
-		if display then ignore(handle_display ctx (EConst(Ident i.v_name),i.v_pos) (WithType i.v_type));
+		begin match dko with
+		| None -> ()
+		| Some dk -> ignore(handle_display ctx (EConst(Ident i.v_name),i.v_pos) dk (WithType i.v_type))
+		end;
 		let e2 = type_expr ctx e2 NoValue in
 		(try optimize_for_loop_iterator ctx i e1 e2 p with Exit -> mk (TFor (i,e1,e2)) ctx.t.tvoid p)
 	in
 	let e = match optimize_for_loop ctx (i,pi) e1 e2 p with
 		| Some e ->
-			if display then ignore(handle_display ctx (EConst(Ident i),pi) Value);
+			begin match dko with
+			| None -> ()
+			| Some dk -> ignore(handle_display ctx (EConst(Ident i),pi) dk Value);
+			end;
 			e
 		| None -> default()
 	in

+ 12 - 10
src/typing/matcher.ml

@@ -439,17 +439,20 @@ module Pattern = struct
 				) pctx1.current_locals;
 				PatOr(pat1,pat2)
 			| EBinop(OpAssign,e1,e2) ->
-				let rec loop in_display e = match e with
+				let rec loop dko e = match e with
 					| (EConst (Ident s),p) ->
 						let v = add_local s p in
-						if in_display then ignore(TyperDisplay.display_expr ctx e (mk (TLocal v) v.v_type p) (WithType t) p);
+						begin match dko with
+						| None -> ()
+						| Some dk -> ignore(TyperDisplay.display_expr ctx e (mk (TLocal v) v.v_type p) dk (WithType t) p);
+						end;
 						let pat = make pctx false t e2 in
 						PatBind(v,pat)
-					| (EParenthesis e1,_) -> loop in_display e1
-					| (EDisplay(e1,_),_) -> loop true e1
+					| (EParenthesis e1,_) -> loop dko e1
+					| (EDisplay(e1,dk),_) -> loop (Some dk) e1
 					| _ -> fail()
 				in
-				loop false e1
+				loop None e1
 			| EBinop(OpArrow,e1,e2) ->
 				let restore = save_locals ctx in
 				ctx.locals <- pctx.ctx_locals;
@@ -459,10 +462,9 @@ module Pattern = struct
 				restore();
 				let pat = make pctx toplevel e1.etype e2 in
 				PatExtractor(v,e1,pat)
-			| EDisplay(e,iscall) ->
+			| EDisplay(e,dk) ->
 				let pat = loop e in
-				let _ = if iscall then TyperDisplay.handle_signature_display ctx e (WithType t)
-				else TyperDisplay.handle_display ctx e (WithType t) in
+				ignore(TyperDisplay.handle_edisplay ctx e dk (WithType t));
 				pat
 			| _ ->
 				fail()
@@ -535,8 +537,8 @@ module Case = struct
 		List.iter (fun (v,t) -> v.v_type <- t) old_types;
 		save();
 		if ctx.is_display_file && Display.is_display_position p then begin match eo,eo_ast with
-			| Some e,Some e_ast -> ignore(TyperDisplay.display_expr ctx e_ast e with_type p)
-			| None,None -> ignore(TyperDisplay.display_expr ctx (EBlock [],p) (mk (TBlock []) ctx.t.tvoid p) with_type p)
+			| Some e,Some e_ast -> ignore(TyperDisplay.display_expr ctx e_ast e DKMarked with_type p)
+			| None,None -> ignore(TyperDisplay.display_expr ctx (EBlock [],p) (mk (TBlock []) ctx.t.tvoid p) DKMarked with_type p)
 			| _ -> assert false
 		end;
 		{

+ 1 - 1
src/typing/typeloadFunction.ml

@@ -116,7 +116,7 @@ let type_function ctx args ret fmode f do_display p =
 		| Parser.TypePath (_,None,_) | Exit ->
 			type_expr ctx e NoValue
 		| Display.DisplayType (t,_,_) when (match follow t with TMono _ -> true | _ -> false) ->
-			type_expr ctx (if ctx.com.display.dms_kind = DMToplevel then Display.ExprPreprocessing.find_enclosing ctx.com e else e) NoValue
+			type_expr ctx (if ctx.com.display.dms_kind = DMToplevel then Display.ExprPreprocessing.find_enclosing ctx.com DKToplevel e else e) NoValue
 	end in
 	let e = match e.eexpr with
 		| TMeta((Meta.MergeBlock,_,_), ({eexpr = TBlock el} as e1)) -> e1

+ 5 - 8
src/typing/typer.ml

@@ -1889,7 +1889,7 @@ and type_try ctx e1 catches with_type p =
 		let e = type_expr ctx e_ast with_type in
 		(* If the catch position is the display position it means we get completion on the catch keyword or some
 		   punctuation. Otherwise we wouldn't reach this point. *)
-		if ctx.is_display_file && Display.is_display_position pc then ignore(TyperDisplay.display_expr ctx e_ast e with_type pc);
+		if ctx.is_display_file && Display.is_display_position pc then ignore(TyperDisplay.display_expr ctx e_ast e DKMarked with_type pc);
 		v.v_type <- t2;
 		locals();
 		if with_type <> NoValue then unify ctx e.etype e1.etype e.epos;
@@ -2311,8 +2311,8 @@ and type_call ctx e el (with_type:with_type) p =
 			mk (TCall (e_unprotect,[e])) e.etype e.epos
 		else
 			e
-	| (EDisplay((EConst (Ident "super"),_ as e1),false),_),_ ->
-		TyperDisplay.handle_display ctx (ECall(e1,el),p) with_type
+	| (EDisplay((EConst (Ident "super"),_ as e1),dk),_),_ ->
+		TyperDisplay.handle_display ctx (ECall(e1,el),p) dk with_type
 	| (EConst (Ident "super"),sp) , el ->
 		if ctx.curfun <> FunConstructor then error "Cannot call super constructor outside class constructor" p;
 		let el, t = (match ctx.curclass.cl_super with
@@ -2443,11 +2443,8 @@ and type_expr ctx (e,p) (with_type:with_type) =
 		mk (TCast (e,None)) (mk_mono()) p
 	| ECast (e, Some t) ->
 		type_cast ctx e t p
-	| EDisplay (e,iscall) ->
-		begin match ctx.com.display.dms_kind with
-			| DMField | DMSignature when iscall -> TyperDisplay.handle_signature_display ctx e with_type
-			| _ -> TyperDisplay.handle_display ctx e with_type
-		end
+	| EDisplay (e,dk) ->
+		TyperDisplay.handle_edisplay ctx e dk with_type
 	| EDisplayNew t ->
 		assert false
 	| ECheckType (e,t) ->

+ 34 - 23
src/typing/typerDisplay.ml

@@ -9,7 +9,7 @@ open Fields
 open Calls
 open Error
 
-let rec handle_display ctx e_ast with_type =
+let rec handle_display ctx e_ast dk with_type =
 	let old = ctx.in_display,ctx.in_call_args in
 	ctx.in_display <- true;
 	ctx.in_call_args <- false;
@@ -39,7 +39,7 @@ let rec handle_display ctx e_ast with_type =
 	in
 	ctx.in_display <- fst old;
 	ctx.in_call_args <- snd old;
-	display_expr ctx e_ast e with_type p
+	display_expr ctx e_ast e dk with_type p
 
 and handle_signature_display ctx e_ast with_type =
 	ctx.in_display <- true;
@@ -109,27 +109,9 @@ and handle_signature_display ctx e_ast with_type =
 		| ENew(tpath,el) ->
 			let t = Typeload.load_instance ctx tpath true p in
 			handle_call (find_constructor_types t) el (pos tpath)
-		| EObjectDecl fl ->
-			let fail () = error "Unexpected type or something" p in
-			begin match with_type with
-			| WithType t ->
-				begin match follow t with
-				| TAnon an ->
-					let fl = PMap.foldi (fun k cf acc ->
-						if Expr.field_mem_assoc k fl then acc
-						else ((k,false,cf.cf_type),cf.cf_name_pos) :: acc
-					) an.a_fields [] in
-					let fl = List.sort (fun (_,p1) (_,p2) -> compare p1 p2) fl in
-					let fl = List.map fst fl in
-					let fl = [(fl,t),None] in
-					raise (Display.DisplaySignatures (fl,0))
-				| _ -> fail()
-				end
-			| _ -> fail()
-			end
 		| _ -> error "Call expected" p
 
-and display_expr ctx e_ast e with_type p =
+and display_expr ctx e_ast e dk with_type p =
 	let get_super_constructor () = match ctx.curclass.cl_super with
 		| None -> error "Current class does not have a super" p
 		| Some (c,params) ->
@@ -231,5 +213,34 @@ and display_expr ctx e_ast e with_type p =
 	| DMToplevel ->
 		raise (Display.DisplayToplevel (DisplayToplevel.collect ctx false))
 	| DMField | DMNone | DMModuleSymbols _ | DMDiagnostics _ | DMStatistics ->
-		let fields = DisplayFields.collect ctx e_ast e with_type p in
-		raise (Display.DisplayFields fields)
+		let fields = DisplayFields.collect ctx e_ast e dk with_type p in
+		raise (Display.DisplayFields fields)
+
+let handle_structure_display ctx e with_type =
+	let p = pos e in
+	match fst e with
+	| EObjectDecl fl ->
+		let fail () = [] in
+		let fields = match with_type with
+		| WithType t ->
+			begin match follow t with
+			| TAnon an ->
+				let fields = PMap.foldi (fun k cf acc ->
+					if Expr.field_mem_assoc k fl then acc
+					else ((k,Display.FKVar cf.cf_type,cf.cf_doc)) :: acc
+				) an.a_fields [] in
+				fields
+			| _ -> fail()
+			end
+		| _ -> fail()
+		in
+		raise (Display.DisplayFields fields)
+	| _ ->
+		error "Expected object expression" p
+
+
+let handle_edisplay ctx e dk with_type =
+	match dk,ctx.com.display.dms_kind with
+	| DKCall,(DMSignature | DMField) -> handle_signature_display ctx e with_type
+	| DKStructure,DMField -> handle_structure_display ctx e with_type
+	| _ -> handle_display ctx e dk with_type

+ 9 - 1
std/haxe/macro/Expr.hx

@@ -509,7 +509,7 @@ enum ExprDef {
 	/**
 		Internally used to provide completion.
 	**/
-	EDisplay( e : Expr, isCall : Bool );
+	EDisplay( e : Expr, displayKind:DisplayKind );
 
 	/**
 		Internally used to provide completion.
@@ -532,6 +532,14 @@ enum ExprDef {
 	EMeta( s : MetadataEntry, e : Expr );
 }
 
+enum DisplayKind {
+	DKCall;
+	DKDot;
+	DKStructure;
+	DKToplevel;
+	DKMarked;
+}
+
 /**
 	Represents a type syntax in the AST.
 **/

+ 1 - 1
std/haxe/macro/ExprTools.hx

@@ -183,7 +183,7 @@ class ExprTools {
 			case EUntyped(e): EUntyped(f(e));
 			case EThrow(e): EThrow(f(e));
 			case ECast(e, t): ECast(f(e), t);
-			case EDisplay(e, isCall): EDisplay(f(e), isCall);
+			case EDisplay(e, dk): EDisplay(f(e), dk);
 			case ETernary(econd, eif, eelse): ETernary(f(econd), f(eif), f(eelse));
 			case ECheckType(e, t): ECheckType(f(e), t);
 			case EDisplayNew(_),

+ 8 - 19
tests/display/src/cases/Issue5767.hx

@@ -13,7 +13,7 @@ class Issue5767 extends DisplayTestCase {
 	}
 	**/
 	function testGama11() {
-		sigEq(0, [["b:String"]], signature(pos(1)));
+		eq(true, hasField(fields(pos(1)), "b", "String"));
 	}
 
 	/**
@@ -26,7 +26,7 @@ class Issue5767 extends DisplayTestCase {
 	}
 	**/
 	function testGama11Intact() {
-		sigEq(0, [["b:String"]], signature(pos(1)));
+		eq(true, hasField(fields(pos(1)), "b", "String"));
 	}
 
 	/**
@@ -43,7 +43,9 @@ class Issue5767 extends DisplayTestCase {
 	}
 	**/
 	function testOrder() {
-		sigEq(0, [["b:Int", "c:Bool"]], signature(pos(1)));
+		var fields = fields(pos(1));
+		eq(true, hasField(fields, "b", "Int"));
+		eq(true, hasField(fields, "c", "Bool"));
 	}
 
 	/**
@@ -64,7 +66,7 @@ class Issue5767 extends DisplayTestCase {
 	}
 	**/
 	function testNested() {
-		sigEq(0, [["a:Bool"]], signature(pos(1)));
+		eq(true, hasField(fields(pos(1)), "a", "Bool"));
 	}
 
 	/**
@@ -85,7 +87,7 @@ class Issue5767 extends DisplayTestCase {
 	}
 	**/
 	function testFirstArg() {
-		sigEq(0, [["a:Bool"]], signature(pos(1)));
+		eq(true, hasField(fields(pos(1)), "a", "Bool"));
 	}
 
 	/**
@@ -102,19 +104,6 @@ class Issue5767 extends DisplayTestCase {
 	}
 	**/
 	function testIntact() {
-		sigEq(0, [["c:String"]], signature(pos(1)));
-	}
-
-	function sigEq(arg:Int, params:Array<Array<String>>, sig:SignatureHelp, ?pos:haxe.PosInfos) {
-		eq(arg, sig.activeParameter, pos);
-		eq(params.length, sig.signatures.length, pos);
-		for (i in 0...params.length) {
-			var sigInf = sig.signatures[i];
-			var args = params[i];
-			eq(sigInf.parameters.length, args.length, pos);
-			for (i in 0...args.length) {
-				eq(sigInf.parameters[i].label, args[i], pos);
-			}
-		}
+		eq(true, hasField(fields(pos(1)), "c", "String"));
 	}
 }