2
0
Эх сурвалжийг харах

[display] rework CompletionItem.type

Simon Krajewski 7 жил өмнө
parent
commit
ad6fc19644

+ 6 - 3
src/compiler/displayOutput.ml

@@ -71,7 +71,7 @@ let print_fields fields =
 		| ITMetadata(s,doc) -> "metadata",s,"",doc
 		| ITTimer(name,value) -> "timer",name,"",Some value
 		| ITLiteral s ->
-			let t = Option.default t_dynamic k.ci_type in
+			let t = match k.ci_type with None -> t_dynamic | Some (t,_) -> t in
 			"literal",s,s_type (print_context()) t,None
 		| ITLocal v -> "local",v.v_name,s_type (print_context()) v.v_type,None
 		| ITKeyword kwd -> "keyword",Ast.s_keyword kwd,"",None
@@ -426,8 +426,11 @@ module TypePathHandler = struct
 				| KAbstractImpl a -> Self (TAbstractDecl a)
 				| _ -> Self (TClassDecl c)
 			in
+			let todo t =
+				(t,CompletionType.CTMono)
+			in
 			let make_field_doc c cf =
-				make_ci_class_field (CompletionClassField.make cf CFSStatic (class_origin c) true) cf.cf_type
+				make_ci_class_field (CompletionClassField.make cf CFSStatic (class_origin c) true) (todo cf.cf_type)
 			in
 			let fields = match !statics with
 				| None -> types
@@ -436,7 +439,7 @@ module TypePathHandler = struct
 			let fields = match !enum_statics with
 				| None -> fields
 				| Some en -> PMap.fold (fun ef acc ->
-					make_ci_enum_field (CompletionEnumField.make ef (Self (TEnumDecl en)) true) ef.ef_type :: acc
+					make_ci_enum_field (CompletionEnumField.make ef (Self (TEnumDecl en)) true) (todo ef.ef_type) :: acc
 				) en.e_constrs fields
 			in
 			Some fields

+ 1 - 1
src/compiler/main.ml

@@ -1004,7 +1004,7 @@ with
 				DisplayOutput.print_fields fields
 		in
 		raise (DisplayOutput.Completion s)
-	| DisplayException(DisplayHover ({hitem = {CompletionItem.ci_type = Some t}} as hover)) ->
+	| DisplayException(DisplayHover ({hitem = {CompletionItem.ci_type = Some (t,_)}} as hover)) ->
 		let doc = CompletionItem.get_documentation hover.hitem in
 		raise (DisplayOutput.Completion (DisplayOutput.print_type t hover.hpos doc))
 	| DisplayException(DisplaySignatures(signatures,_,display_arg)) ->

+ 78 - 33
src/context/display/displayEmitter.ml

@@ -6,36 +6,78 @@ open DisplayException
 open DisplayTypes
 open DisplayMode
 open CompletionItem
+open CompletionType
+open ImportStatus
 open ClassFieldOrigin
 open DisplayTypes.CompletionResultKind
 open Common
 open Display
 open DisplayPosition
 
-let requires_import ctx path =
-	try
-		let mt' = ctx.g.do_load_type_def ctx null_pos {tpackage = []; tname = snd path; tparams = []; tsub = None} in
-		path <> (t_infos mt').mt_path
-	with _ ->
-		true
-
-let patch_type ctx t =
-	let rec patch t = match t with
-		| TInst(c,tl) when not (requires_import ctx c.cl_path) -> TInst({c with cl_path = ([],snd c.cl_path)},List.map patch tl)
-		| TEnum(en,tl) when not (requires_import ctx en.e_path) -> TEnum({en with e_path = ([],snd en.e_path)},List.map patch tl)
-		| TType(td,tl) when not (requires_import ctx td.t_path) -> TType({td with t_path = ([],snd td.t_path)},List.map patch tl)
-		| TAbstract(a,tl) when not (requires_import ctx a.a_path) -> TAbstract({a with a_path = ([],snd a.a_path)},List.map patch tl)
+let completion_type_of_type ctx t =
+	let get_import_status path =
+		try
+			let mt' = ctx.g.do_load_type_def ctx null_pos {tpackage = []; tname = snd path; tparams = []; tsub = None} in
+			if path <> (t_infos mt').mt_path then Shadowed else Imported
+		with _ ->
+			Unimported
+	in
+	let ctpath path = {
+		ct_dot_path = path;
+		ct_import_status = get_import_status path;
+	} in
+	let rec ppath path tl = {
+		ct_path = ctpath path;
+		ct_params = List.map from_type tl;
+	}
+	and from_type t = match t with
+		| TMono r ->
+			begin match !r with
+				| None -> CTMono
+				| Some t -> from_type t
+			end
+		| TLazy r ->
+			from_type (lazy_type r)
+		| TInst({cl_kind = KTypeParameter _} as c,_) ->
+			CTInst ({
+				ct_path = {
+					ct_dot_path = c.cl_path;
+					ct_import_status = Imported;
+				};
+				ct_params = [];
+			})
+		| TInst(c,tl) ->
+			CTInst (ppath c.cl_path tl)
+		| TEnum(en,tl) ->
+			CTInst (ppath en.e_path tl)
+		| TType(td,tl) ->
+			CTInst (ppath td.t_path tl)
+		| TAbstract(a,tl) ->
+			CTInst (ppath a.a_path tl)
+		| TFun(tl,t) ->
+			let funarg (name,opt,t) = {
+				ct_name = name;
+				ct_optional = opt;
+				ct_type = from_type t;
+				ct_value = None
+			} in
+			CTFunction {
+				ct_args = List.map funarg tl;
+				ct_return = from_type t;
+			}
 		| TAnon an ->
-			begin match !(an.a_status) with
-			| Statics {cl_kind = KAbstractImpl a} ->
-				an.a_status := AbstractStatics a
-			| _ ->
-				()
-			end;
-			Type.map patch t
-		| _ -> Type.map patch t
+			let afield af = {
+				ctf_field = af;
+				ctf_type = from_type af.cf_type;
+			} in
+			CTAnonymous {
+				ct_fields = PMap.fold (fun cf acc -> afield cf :: acc) an.a_fields [];
+				ct_status = !(an.a_status);
+			}
+		| TDynamic t ->
+			CTDynamic (if t == t_dynamic then None else Some (from_type t))
 	in
-	patch t
+	from_type t
 
 let display_module_type ctx mt p = match ctx.com.display.dms_kind with
 	| DMDefinition -> raise_position [(t_infos mt).mt_name_pos];
@@ -43,16 +85,18 @@ let display_module_type ctx mt p = match ctx.com.display.dms_kind with
 		let infos = t_infos mt in
 		reference_position := (snd infos.mt_path,infos.mt_name_pos,KModuleType)
 	| DMHover ->
-		let t = patch_type ctx (type_of_module_type mt) in
-		raise_hover (make_ci_type (CompletionModuleType.of_module_type mt) ImportStatus.Imported (Some t)) p
+		let t = type_of_module_type mt in
+		let ct = completion_type_of_type ctx t in
+		raise_hover (make_ci_type (CompletionModuleType.of_module_type mt) ImportStatus.Imported (Some (t,ct))) p
 	| _ -> ()
 
 let rec display_type ctx t p =
 	let dm = ctx.com.display in
 	match dm.dms_kind with
 	| DMHover ->
-		let t = patch_type ctx t in
-		raise_hover (make_ci_expr (mk (TConst TNull) t p)) p
+		let ct = completion_type_of_type ctx t in
+		let ci = make_ci_expr (mk (TConst TNull) t p) (t,ct) in
+		raise_hover ci p
 	| _ ->
 		try display_module_type ctx (module_type_of_type t) p
 		with Exit -> match follow t,follow !t_dynamic_def with
@@ -76,8 +120,8 @@ let display_variable ctx v p = match ctx.com.display.dms_kind with
 	| DMDefinition -> raise_position [v.v_pos]
 	| DMUsage _ -> reference_position := (v.v_name,v.v_pos,KVar)
 	| DMHover ->
-		let t = patch_type ctx v.v_type in
-		raise_hover (make_ci_local v t) p
+		let ct = completion_type_of_type ctx v.v_type in
+		raise_hover (make_ci_local v (v.v_type,ct)) p
 	| _ -> ()
 
 let display_field ctx origin scope cf p = match ctx.com.display.dms_kind with
@@ -101,8 +145,8 @@ let display_field ctx origin scope cf p = match ctx.com.display.dms_kind with
             | Self (TClassDecl c),CFSConstructor,TFun(tl,_) -> {cf with cf_type = TFun(tl,TInst(c,List.map snd c.cl_params))}
             | _ -> cf
         in
-		let t = patch_type ctx cf.cf_type in
-		raise_hover (make_ci_class_field (CompletionClassField.make cf scope origin true) t) p
+		let ct = completion_type_of_type ctx cf.cf_type in
+		raise_hover (make_ci_class_field (CompletionClassField.make cf scope origin true) (cf.cf_type,ct)) p
 	| _ -> ()
 
 let maybe_display_field ctx origin scope cf p =
@@ -112,8 +156,8 @@ let display_enum_field ctx en ef p = match ctx.com.display.dms_kind with
 	| DMDefinition -> raise_position [ef.ef_name_pos]
 	| DMUsage _ -> reference_position := (ef.ef_name,ef.ef_name_pos,KEnumField)
 	| DMHover ->
-		let t = patch_type ctx ef.ef_type in
-		raise_hover (make_ci_enum_field (CompletionEnumField.make ef (Self (TEnumDecl en)) true) t) p
+		let ct = completion_type_of_type ctx ef.ef_type in
+		raise_hover (make_ci_enum_field (CompletionEnumField.make ef (Self (TEnumDecl en)) true) (ef.ef_type,ct)) p
 	| _ -> ()
 
 let display_meta com meta p = match com.display.dms_kind with
@@ -164,7 +208,8 @@ let check_field_modifiers ctx c cf override display_modifier =
 			let missing_fields = List.fold_left (fun fields cf -> PMap.remove cf.cf_name fields) all_fields c.cl_ordered_fields in
 			let l = PMap.fold (fun (c,cf) fields ->
 				let origin = Parent (TClassDecl c) in
-				make_ci_class_field (CompletionClassField.make cf CFSMember origin true) cf.cf_type :: fields
+				let ct = completion_type_of_type ctx cf.cf_type in
+				make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct) :: fields
 			) missing_fields [] in
 			raise_fields l CROverride None
 		| _ -> ()

+ 0 - 1
src/context/display/displayException.ml

@@ -68,7 +68,6 @@ let to_json ctx de =
 		jobject [
 			"documentation",jopt jstring (CompletionItem.get_documentation hover.hitem);
 			"range",generate_pos_as_range hover.hpos;
-			"type",jopt (generate_type ctx) hover.hitem.ci_type; (* TODO: remove *)
 			"item",CompletionItem.to_json ctx hover.hitem;
 		]
 	| DisplayPosition pl ->

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

@@ -71,7 +71,8 @@ let collect_static_extensions ctx items e p =
 								let f = prepare_using_field f in
 								let f = { f with cf_params = []; cf_public = true; cf_type = TFun(args,ret) } in
 								let origin = StaticExtension(TClassDecl c) in
-								let item = make_ci_class_field (CompletionClassField.make f CFSMember origin true) f.cf_type in
+								let ct = DisplayEmitter.completion_type_of_type ctx f.cf_type in
+								let item = make_ci_class_field (CompletionClassField.make f CFSMember origin true) (f.cf_type,ct) in
 								PMap.add f.cf_name item acc
 							end
 						with Error (Unify _,_) ->
@@ -114,7 +115,8 @@ let collect ctx e_ast e dk with_type p =
 			PMap.foldi (fun k (c,cf) acc ->
 				if should_access c cf false && is_new_item acc cf.cf_name then begin
 					let origin = if c == c0 then Self(TClassDecl c) else Parent(TClassDecl c) in
-				 	let item = make_ci_class_field (CompletionClassField.make cf CFSMember origin true) cf.cf_type in
+					let ct = DisplayEmitter.completion_type_of_type ctx cf.cf_type in
+				 	let item = make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct) in
 					PMap.add k item acc
 				end else
 					acc
@@ -126,7 +128,8 @@ let collect ctx e_ast e dk with_type p =
 					let origin = Self(TAbstractDecl a) in
 					let cf = prepare_using_field cf in
 					let cf = if tl = [] then cf else {cf with cf_type = apply_params a.a_params tl cf.cf_type} in
-					let item = make_ci_class_field (CompletionClassField.make cf CFSMember origin true) cf.cf_type in
+					let ct = DisplayEmitter.completion_type_of_type ctx cf.cf_type in
+					let item = make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct) in
 					PMap.add cf.cf_name item acc
 				end else
 					acc
@@ -169,8 +172,10 @@ let collect ctx e_ast e dk with_type p =
 							in
 							origin,true
 					in
-					if check then PMap.add name (make_ci_class_field (CompletionClassField.make cf CFSMember origin true) cf.cf_type) acc
-					else acc
+					if check then begin
+						let ct = DisplayEmitter.completion_type_of_type ctx cf.cf_type in
+						PMap.add name (make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct)) acc
+					end else acc
 				end else
 					acc
 			) an.a_fields items
@@ -180,7 +185,8 @@ let collect ctx e_ast e dk with_type p =
 				let t = opt_args args ret in
 				let cf = mk_field "bind" (tfun [t] t) p null_pos in
 				cf.cf_kind <- Method MethNormal;
-				let item = make_ci_class_field (CompletionClassField.make cf CFSStatic BuiltIn true) t in
+				let ct = DisplayEmitter.completion_type_of_type ctx t in
+				let item = make_ci_class_field (CompletionClassField.make cf CFSStatic BuiltIn true) (t,ct) in
 				PMap.add "bind" item items
 			end else
 				items
@@ -193,7 +199,8 @@ let collect ctx e_ast e dk with_type p =
 			let cf = mk_field "code" ctx.t.tint e.epos null_pos in
 			cf.cf_doc <- Some "The character code of this character (inlined at compile-time).";
 			cf.cf_kind <- Var { v_read = AccNormal; v_write = AccNever };
-			let item = make_ci_class_field (CompletionClassField.make cf CFSStatic BuiltIn true) cf.cf_type in
+			let ct = DisplayEmitter.completion_type_of_type ctx cf.cf_type in
+			let item = make_ci_class_field (CompletionClassField.make cf CFSStatic BuiltIn true) (cf.cf_type,ct) in
 			PMap.add cf.cf_name item PMap.empty
 		| _ ->
 			PMap.empty

+ 18 - 14
src/context/display/displayToplevel.ml

@@ -181,16 +181,20 @@ let collect ctx epos with_type =
 
 	(* Collection starts here *)
 
+	let tpair t =
+		let ct = DisplayEmitter.completion_type_of_type ctx t in
+		(t,ct)
+	in
 	if epos <> None then begin
 		(* locals *)
 		PMap.iter (fun _ v ->
 			if not (is_gen_local v) then
-				add (make_ci_local v v.v_type) (Some v.v_name)
+				add (make_ci_local v (tpair v.v_type)) (Some v.v_name)
 		) ctx.locals;
 
 		let add_field scope origin cf =
 			let is_qualified = is_qualified cctx cf.cf_name in
-			add (make_ci_class_field (CompletionClassField.make cf scope origin is_qualified) cf.cf_type) (Some cf.cf_name)
+			add (make_ci_class_field (CompletionClassField.make cf scope origin is_qualified) (tpair cf.cf_type)) (Some cf.cf_name)
 		in
 		let maybe_add_field scope origin cf =
 			if not (Meta.has Meta.NoCompletion cf.cf_meta) then add_field scope origin cf
@@ -231,7 +235,7 @@ let collect ctx epos with_type =
 				List.iter (fun cf ->
 					let ccf = CompletionClassField.make cf CFSMember (Self (TClassDecl c)) true in
 					if (Meta.has Meta.Enum cf.cf_meta) && not (Meta.has Meta.NoCompletion cf.cf_meta) then
-						add (make_ci_enum_abstract_field a ccf cf.cf_type) (Some cf.cf_name);
+						add (make_ci_enum_abstract_field a ccf (tpair cf.cf_type)) (Some cf.cf_name);
 				) c.cl_ordered_statics
 			| TTypeDecl t ->
 				begin match follow t.t_type with
@@ -243,7 +247,7 @@ let collect ctx epos with_type =
 				let origin = Self (TEnumDecl e) in
 				PMap.iter (fun _ ef ->
 					let is_qualified = is_qualified cctx ef.ef_name in
-					add (make_ci_enum_field (CompletionEnumField.make ef origin is_qualified) ef.ef_type) (Some ef.ef_name)
+					add (make_ci_enum_field (CompletionEnumField.make ef origin is_qualified) (tpair ef.ef_type)) (Some ef.ef_name)
 				) e.e_constrs;
 			| _ ->
 				()
@@ -266,7 +270,7 @@ let collect ctx epos with_type =
 					let cf = PMap.find s c.cl_statics in
 					let cf = if name = cf.cf_name then cf else {cf with cf_name = name} in
 					let origin = StaticImport (TClassDecl c) in
-					add (make_ci_class_field (CompletionClassField.make cf CFSStatic origin is_qualified) cf.cf_type) (Some name)
+					add (make_ci_class_field (CompletionClassField.make cf CFSStatic origin is_qualified) (tpair cf.cf_type)) (Some name)
 				in
 				match resolve_typedef mt with
 					| TClassDecl c -> class_import c;
@@ -274,7 +278,7 @@ let collect ctx epos with_type =
 						let ef = PMap.find s en.e_constrs in
 						let ef = if name = ef.ef_name then ef else {ef with ef_name = name} in
 						let origin = StaticImport (TEnumDecl en) in
-						add (make_ci_enum_field (CompletionEnumField.make ef origin is_qualified) ef.ef_type) (Some s)
+						add (make_ci_enum_field (CompletionEnumField.make ef origin is_qualified) (tpair ef.ef_type)) (Some s)
 					| TAbstractDecl {a_impl = Some c} -> class_import c;
 					| _ -> raise Not_found
 			with Not_found ->
@@ -282,15 +286,15 @@ let collect ctx epos with_type =
 		) ctx.m.module_globals;
 
 		(* literals *)
-		add (make_ci_literal "null" t_dynamic) (Some "null");
-		add (make_ci_literal "true" ctx.com.basic.tbool) (Some "true");
-		add (make_ci_literal "false" ctx.com.basic.tbool) (Some "false");
+		add (make_ci_literal "null" (tpair t_dynamic)) (Some "null");
+		add (make_ci_literal "true" (tpair ctx.com.basic.tbool)) (Some "true");
+		add (make_ci_literal "false" (tpair ctx.com.basic.tbool)) (Some "false");
 		begin match ctx.curfun with
 			| FunMember | FunConstructor | FunMemberClassLocal ->
 				let t = TInst(ctx.curclass,List.map snd ctx.curclass.cl_params) in
-				add (make_ci_literal "this" t) (Some "this");
+				add (make_ci_literal "this" (tpair t)) (Some "this");
 				begin match ctx.curclass.cl_super with
-					| Some(c,tl) -> add (make_ci_literal "super" (TInst(c,tl))) (Some "super")
+					| Some(c,tl) -> add (make_ci_literal "super" (tpair (TInst(c,tl)))) (Some "super")
 					| None -> ()
 				end
 			| _ ->
@@ -305,13 +309,13 @@ let collect ctx epos with_type =
 		List.iter (fun kwd -> add(make_ci_keyword kwd) (Some (s_keyword kwd))) kwds;
 
 		(* builtins *)
-		add (make_ci_literal "trace" (TFun(["value",false,t_dynamic],ctx.com.basic.tvoid))) (Some "trace")
+		add (make_ci_literal "trace" (tpair (TFun(["value",false,t_dynamic],ctx.com.basic.tvoid)))) (Some "trace")
 	end;
 
 	(* type params *)
 	List.iter (fun (s,t) -> match follow t with
 		| TInst(c,_) ->
-			add (make_ci_type_param c) (Some (snd c.cl_path))
+			add (make_ci_type_param c (tpair t)) (Some (snd c.cl_path))
 		| _ -> assert false
 	) ctx.type_params;
 
@@ -374,7 +378,7 @@ let collect ctx epos with_type =
 		| WithType t ->
 			let rec comp t' = match t' with
 				| None -> 9
-				| Some t' ->
+				| Some (t',_) ->
 				if type_iseq t' t then 0 (* equal types - perfect *)
 				else if t' == t_dynamic then 5 (* dynamic isn't good, but better than incompatible *)
 				else try Type.unify t' t; 1 (* assignable - great *)

+ 94 - 5
src/core/display/completionItem.ml

@@ -261,6 +261,96 @@ module PackageContentKind = struct
 		| PCKPackage -> 1
 end
 
+module CompletionType = struct
+	type ct_path = {
+		ct_dot_path : path;
+		ct_import_status : ImportStatus.t;
+	}
+
+	and ct_path_with_params = {
+		ct_path : ct_path;
+		ct_params : t list;
+	}
+
+	and ct_function_argument = {
+		ct_name : string;
+		ct_optional : bool;
+		ct_type : t;
+		ct_value : tconstant option;
+	}
+
+	and ct_function = {
+		ct_args : ct_function_argument list;
+		ct_return : t;
+	}
+
+	and ct_anonymous_field = {
+		ctf_field : tclass_field;
+		ctf_type : t;
+	}
+
+	and ct_anonymous = {
+		ct_fields : ct_anonymous_field list;
+		ct_status : anon_status;
+	}
+
+	and t =
+		| CTMono
+		| CTInst of ct_path_with_params
+		| CTEnum of ct_path_with_params
+		| CTTypedef of ct_path_with_params
+		| CTAbstract of ct_path_with_params
+		| CTFunction of ct_function
+		| CTAnonymous of ct_anonymous
+		| CTDynamic of t option
+
+	let to_json ctx ct =
+		let generate_path path =
+			jobject [
+				"pack",jarray (List.map jstring (fst path.ct_dot_path));
+				"name",jstring (snd path.ct_dot_path);
+				"importStatus",jint (ImportStatus.to_int path.ct_import_status);
+			]
+		in
+		let rec generate_path_with_params pwp = jobject [
+			"path",generate_path pwp.ct_path;
+			"params",jlist generate_type pwp.ct_params;
+		]
+		and generate_function_argument cfa = jobject [
+			"name",jstring cfa.ct_name;
+			"opt",jbool cfa.ct_optional;
+			"t",generate_type cfa.ct_type;
+			"value",jopt (generate_tconstant ctx) cfa.ct_value;
+		]
+		and generate_function ctf = jobject [
+			"args",jlist generate_function_argument ctf.ct_args;
+			"ret",generate_type ctf.ct_return;
+		]
+		and generate_anon_field af =
+			let fields = generate_class_field' ctx CFSMember af.ctf_field in
+			let fields = List.filter (fun (n,_) -> n <> "type") fields in
+			let fields = ("type",generate_type af.ctf_type) :: fields in
+			jobject fields
+		and generate_anon cta = jobject [
+			"status",generate_anon_status ctx cta.ct_status;
+			"fields",jlist generate_anon_field cta.ct_fields;
+		]
+		and generate_type ct =
+			let name,args = match ct with
+				| CTMono -> "TMono",None
+				| CTInst pwp -> "TInst",Some (generate_path_with_params pwp)
+				| CTEnum pwp -> "TEnum",Some (generate_path_with_params pwp)
+				| CTTypedef pwp -> "TTypedef",Some (generate_path_with_params pwp)
+				| CTAbstract pwp -> "TAbstract",Some (generate_path_with_params pwp)
+				| CTFunction ctf -> "TFun",Some (generate_function ctf)
+				| CTAnonymous cta -> "TAnonymous",Some (generate_anon cta)
+				| CTDynamic cto -> "TDynamic",Option.map generate_type cto;
+			in
+			generate_adt ctx None name args
+		in
+		generate_type ct
+end
+
 open CompletionModuleType
 open CompletionClassField
 open CompletionEnumField
@@ -283,7 +373,7 @@ type t_kind =
 
 type t = {
 	ci_kind : t_kind;
-	ci_type : Type.t option;
+	ci_type : (Type.t * CompletionType.t) option;
 }
 
 let make kind t = {
@@ -303,8 +393,8 @@ let make_ci_timer name value = make (ITTimer(name,value)) None
 let make_ci_metadata s doc = make (ITMetadata(s,doc)) None
 let make_ci_keyword kwd = make (ITKeyword kwd) None
 let make_ci_anon an t = make (ITAnonymous an) (Some t)
-let make_ci_expr e = make (ITExpression e) (Some e.etype)
-let make_ci_type_param c = make (ITTypeParameter c) (Some (TInst(c,[])))
+let make_ci_expr e t = make (ITExpression e) (Some t)
+let make_ci_type_param c t = make (ITTypeParameter c) (Some t)
 
 let get_index item = match item.ci_kind with
 	| ITLocal _ -> 0
@@ -472,7 +562,6 @@ let to_json ctx item =
 		]
 		| ITLiteral s -> "Literal",jobject [
 			"name",jstring s;
-			"type",jopt (generate_type ctx) item.ci_type; (* TODO: remove *)
 		]
 		| ITTimer(s,value) -> "Timer",jobject [
 			"name",jstring s;
@@ -501,5 +590,5 @@ let to_json ctx item =
 	jobject (
 		("kind",jstring kind) ::
 		("args",data) ::
-		(match item.ci_type with None -> [] | Some t -> ["type",generate_type ctx t])
+		(match item.ci_type with None -> [] | Some t -> ["type",CompletionType.to_json ctx (snd t)])
 	)

+ 15 - 11
src/core/displayTypes.ml

@@ -84,21 +84,25 @@ module CompletionResultKind = struct
 		let i,args = match kind with
 			| CRField(item,p) ->
 				let t = CompletionItem.get_type item in
-				let module_type = match t with
-					| None -> jnull
-					| Some t ->
+				let t = match t with
+					| None ->
+						None
+					| Some (t,ct) ->
 						try
 							let mt = module_type_of_type t in
-							generate_module_type ctx mt
+							Some (generate_module_type ctx mt,CompletionItem.CompletionType.to_json ctx ct)
 						with _ ->
-							jnull
+							None
 				in
-				0,Some (jobject [
-					"item",CompletionItem.to_json ctx item;
-					"range",generate_pos_as_range p;
-					"type",jopt (generate_type ctx) t;
-					"moduleType",module_type (* ARGH *)
-				])
+				let fields =
+					("item",CompletionItem.to_json ctx item) ::
+					("range",generate_pos_as_range p) ::
+					(match t with
+						| None -> []
+						| Some (mt,ct) -> ["type",ct;"moduleType",mt]
+					)
+				in
+				0,Some (jobject fields)
 			| CRStructureField -> 1,None
 			| CRToplevel t ->
 				let args = match t with

+ 18 - 15
src/core/json/genjson.ml

@@ -180,26 +180,26 @@ let rec generate_type ctx t =
 	let name,args = loop t in
 	generate_adt ctx None name args
 
+and generate_anon_status ctx status =
+	let name,args = match status with
+		| Closed -> "AClosed",None
+		| Opened -> "AOpened",None
+		| Const -> "AConst",None
+		| Extend tl -> "AExtend", Some (generate_types ctx tl)
+		| Statics c -> "AClassStatics",Some (class_ref ctx c)
+		| EnumStatics en -> "AEnumStatics",Some (enum_ref ctx en)
+		| AbstractStatics a -> "AAbstractStatics", Some (abstract_ref ctx a)
+	in
+	generate_adt ctx None name args
+
 and generate_anon ctx an =
 	let generate_anon_fields () =
 		let fields = PMap.fold (fun cf acc -> generate_class_field ctx CFSMember cf :: acc) an.a_fields [] in
 		jarray fields
 	in
-	let generate_anon_status () =
-		let name,args = match !(an.a_status) with
-			| Closed -> "AClosed",None
-			| Opened -> "AOpened",None
-			| Const -> "AConst",None
-			| Extend tl -> "AExtend", Some (generate_types ctx tl)
-			| Statics c -> "AClassStatics",Some (class_ref ctx c)
-			| EnumStatics en -> "AEnumStatics",Some (enum_ref ctx en)
-			| AbstractStatics a -> "AAbstractStatics", Some (abstract_ref ctx a)
-		in
-		generate_adt ctx None name args
-	in
 	jobject [
 		"fields",generate_anon_fields();
-		"status",generate_anon_status ();
+		"status",generate_anon_status ctx !(an.a_status);
 	]
 
 and generate_function_argument ctx (name,opt,t) =
@@ -435,7 +435,7 @@ and generate_texpr ctx e =
 
 (* fields *)
 
-and generate_class_field ctx cfs cf =
+and generate_class_field' ctx cfs cf =
 	let generate_class_kind () =
 		let generate_var_access va =
 			let name,args = match va with
@@ -469,7 +469,7 @@ and generate_class_field ctx cfs cf =
 		| GMFull | GMWithoutDoc -> jopt (generate_texpr ctx) cf.cf_expr
 		| GMMinimum -> jnull
 	in
-	jobject [
+	[
 		"name",jstring cf.cf_name;
 		"type",generate_type ctx cf.cf_type;
 		"isPublic",jbool cf.cf_public;
@@ -483,6 +483,9 @@ and generate_class_field ctx cfs cf =
 		"scope",jint (Obj.magic cfs);
 	]
 
+and generate_class_field ctx cfs cf =
+	jobject (generate_class_field' ctx cfs cf)
+
 let generate_enum_field ctx ef =
 	jobject [
 		"name",jstring ef.ef_name;

+ 26 - 14
src/typing/typerDisplay.ml

@@ -24,24 +24,28 @@ let completion_item_of_expr ctx e =
 		with _ ->
 			false
 	in
+	let tpair t =
+		let ct = DisplayEmitter.completion_type_of_type ctx t in
+		(t,ct)
+	in
 	let of_field e origin cf scope =
 		let is_qualified = retype e cf.cf_name e.etype in
-		make_ci_class_field (CompletionClassField.make cf scope origin is_qualified) (DisplayEmitter.patch_type ctx e.etype)
+		make_ci_class_field (CompletionClassField.make cf scope origin is_qualified) (tpair e.etype)
 	in
 	let of_enum_field e origin ef =
 		let is_qualified = retype e ef.ef_name e.etype in
-		make_ci_enum_field (CompletionEnumField.make ef origin is_qualified) (DisplayEmitter.patch_type ctx e.etype)
+		make_ci_enum_field (CompletionEnumField.make ef origin is_qualified) (tpair e.etype)
 	in
 	let itexpr e =
-		let t = DisplayEmitter.patch_type ctx e.etype in
-		make_ci_expr {e with etype = t}
+		let t = tpair e.etype in
+		make_ci_expr e t
 	in
 	let class_origin c = match c.cl_kind with
 		| KAbstractImpl a -> Self (TAbstractDecl a)
 		| _ -> Self (TClassDecl c)
 	in
 	let rec loop e = match e.eexpr with
-		| TLocal v | TVar(v,_) -> make_ci_local v (DisplayEmitter.patch_type ctx v.v_type)
+		| TLocal v | TVar(v,_) -> make_ci_local v (tpair v.v_type)
 		| TField(e1,FStatic(c,cf)) ->
 			let origin = match e1.eexpr with
 				| TMeta((Meta.StaticExtension,_,_),_) -> StaticExtension (TClassDecl c)
@@ -69,16 +73,16 @@ let completion_item_of_expr ctx e =
 			end
 		| TTypeExpr (TClassDecl {cl_kind = KAbstractImpl a}) ->
 			let t = TType(abstract_module_type a (List.map snd a.a_params),[]) in
-			let t = DisplayEmitter.patch_type ctx t in
+			let t = tpair t in
 			make_ci_type (CompletionModuleType.of_module_type (TAbstractDecl a)) ImportStatus.Imported (Some t)
 		| TTypeExpr mt ->
-			let t = DisplayEmitter.patch_type ctx e.etype in
+			let t = tpair e.etype in
 			make_ci_type (CompletionModuleType.of_module_type mt) ImportStatus.Imported (Some t) (* TODO *)
 		| TConst (TThis | TSuper) -> itexpr e (* TODO *)
-		| TConst(ct) -> make_ci_literal (s_const ct) e.etype
+		| TConst(ct) -> make_ci_literal (s_const ct) (tpair e.etype)
 		| TObjectDecl _ ->
 			begin match follow e.etype with
-				| TAnon an -> make_ci_anon an e.etype
+				| TAnon an -> make_ci_anon an (tpair e.etype)
 				| _ -> itexpr e
 			end
 		| TNew(c,tl,_) ->
@@ -105,7 +109,7 @@ let completion_item_of_expr ctx e =
 					| TFun(args,_) -> TFun(args,TInst(c,tl))
 					| _ -> t
 				in
-				make_ci_class_field (CompletionClassField.make {cf with cf_type = t} CFSConstructor (class_origin c) true) (DisplayEmitter.patch_type ctx t)
+				make_ci_class_field (CompletionClassField.make {cf with cf_type = t} CFSConstructor (class_origin c) true) (tpair t)
 			(* end *)
 		| TCall({eexpr = TConst TSuper; etype = t} as e1,_) ->
 			itexpr e1 (* TODO *)
@@ -316,16 +320,20 @@ let handle_structure_display ctx e t an =
 		| TType(td,_) -> Self (TTypeDecl td)
 		| _ -> AnonymousStructure an
 	in
+	let tpair t =
+		let ct = DisplayEmitter.completion_type_of_type ctx t in
+		(t,ct)
+	in
 	match fst e with
 	| EObjectDecl fl ->
 		let fields = List.fold_left (fun acc cf ->
 			if Expr.field_mem_assoc cf.cf_name fl then acc
-			else (make_ci_class_field (CompletionClassField.make cf CFSMember origin true) cf.cf_type) :: acc
+			else (make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (tpair cf.cf_type)) :: acc
 		) [] fields in
 		raise_fields fields CRStructureField None
 	| EBlock [] ->
 		let fields = List.fold_left (fun acc cf ->
-			make_ci_class_field (CompletionClassField.make cf CFSMember origin true) cf.cf_type :: acc
+			make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (tpair cf.cf_type) :: acc
 		) [] fields in
 		raise_fields fields CRStructureField None
 	| _ ->
@@ -335,6 +343,10 @@ let 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;
+	let tpair t =
+		let ct = DisplayEmitter.completion_type_of_type ctx t in
+		(t,ct)
+	in
 	let e = match e_ast,with_type with
 	| (EConst (Ident "$type"),_),_ ->
 		let mono = mk_mono() in
@@ -345,7 +357,7 @@ let handle_display ctx e_ast dk with_type =
 			raise_signatures [((arg,mono),doc)] 0 0
 		| _ ->
 			let t = TFun(arg,mono) in
-			raise_hover (make_ci_expr (mk (TIdent "trace") t (pos e_ast))) (pos e_ast);
+			raise_hover (make_ci_expr (mk (TIdent "trace") t (pos e_ast)) (tpair t)) (pos e_ast);
 		end
 	| (EConst (Ident "trace"),_),_ ->
 		let doc = Some "Print given arguments" in
@@ -356,7 +368,7 @@ let handle_display ctx e_ast dk with_type =
 			raise_signatures [((arg,ret),doc)] 0 0
 		| _ ->
 			let t = TFun(arg,ret) in
-			raise_hover (make_ci_expr (mk (TIdent "trace") t (pos e_ast))) (pos e_ast);
+			raise_hover (make_ci_expr (mk (TIdent "trace") t (pos e_ast)) (tpair t)) (pos e_ast);
 		end
 	| (EConst (Ident "_"),p),WithType t ->
 		mk (TConst TNull) t p (* This is "probably" a bind skip, let's just use the expected type *)

+ 24 - 0
std/haxe/display/JsonModuleTypes.hx

@@ -31,11 +31,34 @@ typedef JsonPos = {
 
 typedef JsonDoc = Null<String>;
 
+enum abstract ImportStatus(Int) {
+    /**
+        This type is already available with it's unqualified name for one of these reasons:
+          - it's a toplevel type
+          - it's imported with an `import` in the current module
+          - it's imported in an `import.hx` file
+    **/
+    var Imported = 0;
+
+    /**
+        The type is currently not imported. It can be accessed either
+        with its fully qualified name or by inserting an import.
+    **/
+    var Unimported = 1;
+
+    /**
+        A type with the same name is already imported in the module.
+        The fully qualified name has to be used to access it.
+    **/
+    var Shadowed = 2;
+}
+
 /* Type instance */
 
 typedef JsonPath = {
 	var pack: Array<String>;
 	var name: String;
+	var ?importStatus:ImportStatus;
 }
 
 typedef JsonPathWithParams = {
@@ -47,6 +70,7 @@ typedef JsonFunctionArgument = {
 	var name: String;
 	var opt: Bool;
 	var t: JsonType<Dynamic>;
+	var ?value: JsonTodo;
 }
 
 typedef JsonFunctionSignature = {

+ 1 - 1
tests/display/src/cases/Basic.hx

@@ -110,6 +110,6 @@ class Basic extends DisplayTestCase {
 	}
 	**/
 	function testCtorClosureType() {
-		eq("someName : Int -> Some", type(pos(1)));
+		eq("someName : Int -> cases.Some", type(pos(1)));
 	}
 }

+ 3 - 3
tests/display/src/cases/BuildMacro.hx

@@ -23,9 +23,9 @@ class BuildMacro extends DisplayTestCase {
 	}
 	**/
 	function test1() {
-		eq("MyString", type(pos(2)));
-		eq("MyString", type(pos(3)));
-		eq("MyString", type(pos(4)));
+		eq("cases.MyString", type(pos(2)));
+		eq("cases.MyString", type(pos(3)));
+		eq("cases.MyString", type(pos(4)));
 		eq(range(7, 8), position(pos(3)));
 		eq(range(7, 8), position(pos(4)));
 		eq(range(5, 6), position(pos(2)));

+ 2 - 2
tests/display/src/cases/Issue5141.hx

@@ -13,7 +13,7 @@ class Issue5141 extends DisplayTestCase {
 	}
 	**/
 	function testTypedef() {
-		eq("MyHandler", type(pos(1)));
+		eq("cases.MyHandler", type(pos(1)));
 		sigEq(0, [[":Int", ":String"]], signature(pos(2)));
 	}
 
@@ -30,7 +30,7 @@ class Issue5141 extends DisplayTestCase {
 	}
 	**/
 	function testAbstract() {
-		eq("MyCallable", type(pos(1)));
+		eq("cases.MyCallable", type(pos(1)));
 		sigEq(0, [[":Int", ":String"]], signature(pos(2)));
 	}
 }

+ 1 - 1
tests/display/src/cases/Issue5166.hx

@@ -8,7 +8,7 @@ class Issue5166 extends DisplayTestCase {
 
 	**/
 	function test() {
-		eq("E", type(pos(2)));
+		eq("cases.E", type(pos(2)));
 		eq(range(2, 1), position(pos(2)));
 	}
 }

+ 2 - 2
tests/display/src/cases/Issue6029.hx

@@ -11,7 +11,7 @@ class Issue6029 extends DisplayTestCase {
 		}
 	**/
 	function test() {
-		eq("A", type(pos(1)));
-		eq("B", type(pos(2)));
+		eq("cases.A", type(pos(1)));
+		eq("cases.B", type(pos(2)));
 	}
 }

+ 1 - 1
tests/display/src/cases/Issue6275.hx

@@ -13,7 +13,7 @@ class Issue6275 extends DisplayTestCase {
 	}
 	**/
 	function test() {
-		eq("s : String -> Main", type(pos(2)));
+		eq("s : String -> cases.Main", type(pos(2)));
 		eq(range(4, 5), position(pos(1)));
 		eq(range(1, 3), usage(pos(2))[0]);
 	}

+ 1 - 1
tests/display/src/cases/Issue6381.hx

@@ -15,7 +15,7 @@ class Issue6381 extends DisplayTestCase {
 	}
 	**/
 	function test() {
-		eq("Option<String>", type(pos(2)));
+		eq("haxe.ds.Option<String>", type(pos(2)));
 		eq(range(1, 3), position(pos(2)));
 		eq(range(4, 5), usage(pos(2))[0]);
 	}

+ 1 - 1
tests/display/src/cases/Issue6405.hx

@@ -19,7 +19,7 @@ class Issue6405 extends DisplayTestCase {
 		eq(range(2, 3), position(pos(1)));
 		var usage = usage(pos(2));
 		arrayEq([range(1, 5)], usage);
-		eq("Expr", type(pos(1)));
+		eq("haxe.macro.Expr", type(pos(1)));
 		var fields = fields(pos(4));
 		eq(true, hasField(fields, "expr", "haxe.macro.ExprDef"));
 		eq(true, hasField(fields, "toString", "Void -> String"));

+ 1 - 1
tests/display/src/cases/Issue7022.hx

@@ -11,6 +11,6 @@ class Issue7022 extends DisplayTestCase {
 	}
 	**/
 	function test() {
-		eq("Void -> Main", type(pos(1)));
+		eq("Void -> cases.Main", type(pos(1)));
 	}
 }

+ 2 - 2
tests/display/src/cases/Super.hx

@@ -13,7 +13,7 @@ class Super extends DisplayTestCase {
 	**/
 	function testSuperCall() {
 		eq(range(1, 2), position(pos(3)));
-		eq("Base<String>", type(pos(3)));
+		eq("cases.Base<String>", type(pos(3)));
 		arrayEq([range(4, 5)], usage(pos(3)));
 	}
 
@@ -29,7 +29,7 @@ class Super extends DisplayTestCase {
 	**/
 	function testSuperField() {
 		eq(range(1, 2), position(pos(3)));
-		eq("Base<String>", type(pos(3)));
+		eq("cases.Base<String>", type(pos(3)));
 		eq(range(4, 5), position(pos(6)));
 		eq("Void -> Void", type(pos(6)));
 	}

+ 1 - 1
tests/display/src/cases/Type.hx

@@ -5,6 +5,6 @@ class Type extends DisplayTestCase {
 	abstract {-1-}A(Int) {}
 	**/
 	function testAbstractDecl() {
-		eq("A", type(pos(1)));
+		eq("cases.A", type(pos(1)));
 	}
 }