Browse Source

[display] deal with literal abstract

closes #10747
Simon Krajewski 2 years ago
parent
commit
933c084135
3 changed files with 17 additions and 6 deletions
  1. 4 4
      src/typing/functionArguments.ml
  2. 11 0
      src/typing/typerDisplay.ml
  3. 2 2
      tests/display/src/cases/Abstract.hx

+ 4 - 4
src/typing/functionArguments.ml

@@ -87,21 +87,21 @@ object(self)
 		| Some l ->
 			l
 		| None ->
-			let make_local name t meta pn =
-				let v = alloc_var (VUser TVOArgument) name t pn in
+			let make_local name kind t meta pn =
+				let v = alloc_var kind name t pn in
 				v.v_meta <- v.v_meta @ meta;
 				v
 			in
 			let rec loop acc is_abstract_this syntax typed = match syntax,typed with
 				| syntax,(name,_,t) :: typed when is_abstract_this ->
-					let v = make_local name t [] null_pos in
+					let v = make_local name VAbstractThis t [] null_pos in
 					v.v_meta <- (Meta.This,[],null_pos) :: v.v_meta;
 					loop ((v,None) :: acc) false syntax typed
 				| ((_,pn),opt,m,_,_) :: syntax,(name,eo,t) :: typed ->
 					delay ctx PTypeField (fun() -> self#check_rest (typed = []) eo opt t pn);
 					if not is_extern then check_local_variable_name ctx name TVOArgument pn;
 					let eo = type_function_arg_value ctx t eo do_display in
-					let v = make_local name t m pn in
+					let v = make_local name (VUser TVOArgument) t m pn in
 					if do_display && DisplayPosition.display_position#enclosed_in pn then
 						DisplayEmitter.display_variable ctx v pn;
 					loop ((v,eo) :: acc) false syntax typed

+ 11 - 0
src/typing/typerDisplay.ml

@@ -48,7 +48,18 @@ let completion_item_of_expr ctx e =
 		let t = tpair e.etype in
 		make_ci_expr e t
 	in
+	let was_probably_literal_abstract v t = match follow t with
+		| TAbstract(a,tl) ->
+			type_iseq (Abstract.get_underlying_type a tl) v.v_type
+		| _ ->
+			false
+	in
 	let rec loop e = match e.eexpr with
+		| TLocal ({v_kind = VAbstractThis} as v) when was_probably_literal_abstract v e.etype ->
+			(* `abstract` is typed as ((this : Underlying) : Abstract), so we detect it like that.
+			   This could lead to false positives if somebody really tries, but even in that case
+				the displayed type is not wrong. *)
+			make_ci_literal "abstract" (tpair e.etype)
 		| TLocal v | TVar(v,_) -> make_ci_local v (tpair ~values:(get_value_meta v.v_meta) v.v_type)
 		| TField(e1,FStatic(c,cf)) ->
 			let te,cf = DisplayToplevel.maybe_resolve_macro_field ctx e.etype c cf in

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

@@ -75,8 +75,8 @@ class Abstract extends DisplayTestCase {
 		final fields = toplevel(pos(2));
 		eq(false, hasToplevel(fields, "literal", "abstract"));
 		// TODO: improve display hints
-		// eq("cases.MyAbstract", type(pos(3)));
-		// eq("cases.AbGeneric<cases.AbGeneric.T>", type(pos(4)));
+		eq("cases.MyAbstract", type(pos(3)));
+		eq("cases.AbGeneric<cases.AbGeneric.T>", type(pos(4)));
 		eq("cases.AbGeneric.T", type(pos(5)));
 	}
 }