Przeglądaj źródła

[display] change handling of overload completion

see #8669
Simon Krajewski 6 lat temu
rodzic
commit
caf8864e6c

+ 6 - 0
src-json/meta.json

@@ -246,6 +246,12 @@
 		"doc": "Marks types that are directly referenced by non-extern code.",
 		"internal": true
 	},
+	{
+		"name": "DisplayOverride",
+		"metadata": ":?display.override",
+		"doc": "Internally used to mark override fields for completion",
+		"internal": true
+	},
 	{
 		"name": "DynamicObject",
 		"metadata": ":dynamicObject",

+ 2 - 2
src/context/display/displayEmitter.ml

@@ -296,7 +296,7 @@ let check_field_modifiers ctx c cf override display_modifier =
 			| _ ->
 				()
 			end
-		| _,Some (AOverride,p) when ctx.com.display.dms_kind = DMDefault ->
+		| Some _,_ when ctx.com.display.dms_kind = DMDefault ->
 			let all_fields = TClass.get_all_super_fields c in
 			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 ->
@@ -306,5 +306,5 @@ let check_field_modifiers ctx c cf override display_modifier =
 				make_ci_class_field (CompletionClassField.make cf CFSMember origin true) (cf.cf_type,ct) :: fields
 			) missing_fields [] in
 			let l = sort_fields l NoValue TKOverride in
-			raise_fields l CROverride (make_subject (Some cf.cf_name) p)
+			raise_fields l CROverride (make_subject (Some cf.cf_name) cf.cf_name_pos)
 		| _ -> ()

+ 17 - 19
src/syntax/grammar.mly

@@ -840,27 +840,25 @@ and parse_class_field tdecl s =
 		| [< f = parse_function_field doc meta al >] ->
 			f
 		| [< >] ->
-			let check_override_completion po =
-				(* If there's an identifier in the stream, it must be a unfinished filter for
-				   an override completion, e.g. `override toStr|`. In that case we simply ignore
-				   the identifier. *)
-				begin match Stream.peek s with
-				| Some (Const (Ident _),_) -> Stream.junk s
-				| _ -> ()
-				end;
-				would_skip_display_position po s
-			in
 			begin match List.rev al with
 				| [] -> raise Stream.Failure
-				| (AOverride,po) :: _ when check_override_completion po ->
-					let f = {
-						f_params = [];
-						f_args = [];
-						f_type = None;
-						f_expr = None
-					} in
-					let _,p2 = next_token s in
-					(magic_display_field_name,p2),punion po p2,FFun f,al,meta
+				| (AOverride,po) :: _ ->
+					begin match check_completion po s with
+					| None ->
+						serror()
+					| Some(so,p) ->
+						let f = {
+							f_params = [];
+							f_args = [];
+							f_type = None;
+							f_expr = None
+						} in
+						let name = match so with
+							| None -> ""
+							| Some s -> s
+						in
+						(name,p),punion po p,FFun f,al,(Meta.DisplayOverride,[],null_pos) :: meta
+					end
 				| _ -> serror()
 			end
 		) in

+ 11 - 0
src/syntax/parser.ml

@@ -309,6 +309,17 @@ let check_resume_range p s fyes fno =
 	end else
 		fno()
 
+let check_completion p0 s =
+	match Stream.peek s with
+	| Some((Const(Ident name),p)) when display_position#enclosed_in p ->
+		Stream.junk s;
+		(Some(Some name,p))
+	| _ ->
+		if would_skip_display_position p0 s then
+			Some(None,DisplayPosition.display_position#with_pos p0)
+		else
+			None
+
 let check_type_decl_flag_completion mode flags s =
 	if not !in_display_file || not (is_completion()) then raise Stream.Failure;
 	let mode () = match flags with

+ 1 - 1
src/typing/typeloadFields.ml

@@ -1118,7 +1118,7 @@ let create_method (ctx,cctx,fctx) c f fd p =
 					cf.cf_expr <- None;
 					cf.cf_type <- t
 				| _ ->
-					if cf.cf_name = Parser.magic_display_field_name then DisplayEmitter.check_field_modifiers ctx c cf fctx.override fctx.display_modifier;
+					if Meta.has Meta.DisplayOverride cf.cf_meta then DisplayEmitter.check_field_modifiers ctx c cf fctx.override fctx.display_modifier;
 					let e , fargs = TypeloadFunction.type_function ctx args ret fmode fd fctx.is_display_field p in
 					begin match fctx.field_kind with
 					| FKNormal when not fctx.is_static -> TypeloadCheck.check_overriding ctx c cf

+ 10 - 0
tests/server/src/DisplayTests.hx

@@ -374,4 +374,14 @@ typedef Foo = {
 		checkReplaceRange(markers, 1, 2, response);
 		equals("char", response.filterString);
 	}
+
+	function testIssue8669_override() {
+		complete("import haxe.io.Bytes; class Main extends Bytes { static function main() { } override {-1-}}", 1);
+		checkReplaceRange(markers, 1, 1, response);
+		equals("", response.filterString);
+
+		complete("import haxe.io.Bytes; class Main extends Bytes { static function main() { } override {-1-}get{-2-}}", 2);
+		checkReplaceRange(markers, 1, 2, response);
+		equals("get", response.filterString);
+	}
 }