瀏覽代碼

[parser] allow type decl completion to trigger on the token too

see #7053
Simon Krajewski 7 年之前
父節點
當前提交
e106a99b18
共有 3 個文件被更改,包括 44 次插入28 次删除
  1. 2 27
      src/syntax/grammar.mly
  2. 30 1
      src/syntax/parser.ml
  3. 12 0
      tests/display/src/cases/Issue7053.hx

+ 2 - 27
src/syntax/grammar.mly

@@ -130,17 +130,7 @@ let rec	parse_file s =
 
 and parse_type_decls mode pmax pack acc s =
 	try
-		(* We check if we hit the magic type path here *)
-		if !in_display_file then begin
-			let pmin = match Stream.peek s with
-				| Some (Eof,_) | None -> max_int
-				| Some tk -> (pos tk).pmin
-			in
-			(* print_endline (Printf.sprintf "(%i <= %i) (%i > %i)" pmax !display_position.pmin pmin !display_position.pmax); *)
-			if pmax <= !display_position.pmin && pmin > !display_position.pmax then begin
-				delay_syntax_completion (SCTypeDecl mode) !display_position
-			end
-		end;
+		check_type_decl_completion mode pmax s;
 		match s with parser
 		| [< (v,p) = parse_type_decl mode >] ->
 			let mode = match v with
@@ -248,22 +238,7 @@ and parse_type_decl mode s =
 		| [< a,p = parse_abstract doc meta c >] ->
 			EAbstract a,p
 		| [< >] ->
-			if not !in_display_file then raise Stream.Failure;
-			let check_type_completion () = match Stream.peek s with
-				(* If there's an identifier coming up, it's probably an incomplete type
-				   declaration. Let's just raise syntax completion in that case because
-				   the parser would fail otherwise anyway. *)
-				| Some((Const(Ident _),p)) -> syntax_completion (SCTypeDecl mode) p
-				| _ -> raise Stream.Failure
-			in
-			match c with
-			| [] -> check_type_completion()
-			| (_,p) :: _ ->
-				if would_skip_display_position p s then begin
-					let flags = List.map fst c in
-					syntax_completion (SCAfterTypeFlag flags) p
-				end;
-				check_type_completion()
+			check_type_decl_flag_completion mode c s
 
 
 and parse_class doc meta cflags need_name s =

+ 30 - 1
src/syntax/parser.ml

@@ -267,4 +267,33 @@ let check_resume_range p s fyes fno =
 		else
 			fno()
 	end else
-		fno()
+		fno()
+
+let check_type_decl_flag_completion mode flags s =
+	if not !in_display_file then raise Stream.Failure;
+	let check_type_completion () = match Stream.peek s with
+		(* If there's an identifier coming up, it's probably an incomplete type
+			declaration. Let's just raise syntax completion in that case because
+			the parser would fail otherwise anyway. *)
+		| Some((Const(Ident _),p)) -> syntax_completion (SCTypeDecl mode) p
+		| _ -> raise Stream.Failure
+	in
+	match flags with
+	| [] -> check_type_completion()
+	| (_,p) :: _ ->
+		if would_skip_display_position p s then begin
+			let flags = List.map fst flags in
+			syntax_completion (SCAfterTypeFlag flags) p
+		end;
+		check_type_completion()
+
+let check_type_decl_completion mode pmax s =
+	if !in_display_file then begin
+		let pmin = match Stream.peek s with
+			| Some (Eof,_) | None -> max_int
+			| Some tk -> (pos tk).pmin
+		in
+		(* print_endline (Printf.sprintf "(%i <= %i) (%i >= %i)" pmax !display_position.pmin pmin !display_position.pmax); *)
+		if pmax <= !display_position.pmin && pmin >= !display_position.pmax then
+			delay_syntax_completion (SCTypeDecl mode) !display_position
+	end;

+ 12 - 0
tests/display/src/cases/Issue7053.hx

@@ -81,6 +81,18 @@ class Issue7053 extends DisplayTestCase {
 		}
 	}
 
+	/**
+	{-1-}class
+	**/
+	function testOnClass() {
+		var fields = toplevel(pos(1));
+		// technically, "package" should be here too. But I think the test system adds a
+		// package statement automatically, so it is omitted.
+		for (expected in ["import", "using", "private", "extern", "class", "interface", "enum", "abstract", "typedef", "final"]) {
+			eq(true, hasField(fields, expected, null, "keyword"));
+		}
+	}
+
 	/**
 	private {-1-}
 	**/