소스 검색

[parser] store actual file data when parsing strings

see #10763
Simon Krajewski 2 년 전
부모
커밋
e648d1b70a
2개의 변경된 파일19개의 추가작업 그리고 1개의 파일을 삭제
  1. 8 0
      src/syntax/lexer.ml
  2. 11 1
      src/syntax/parserEntry.ml

+ 8 - 0
src/syntax/lexer.ml

@@ -73,6 +73,14 @@ let make_file file =
 		llastindex = 0;
 		llastindex = 0;
 	}
 	}
 
 
+let copy_file source dest =
+	dest.lline <- source.lline;
+	dest.lmaxline <- source.lmaxline;
+	dest.llines <- source.llines;
+	dest.lalines <- source.lalines;
+	dest.llast <- source.llast;
+	dest.llastindex <- source.llastindex
+
 let print_file file =
 let print_file file =
 	let sllines = String.concat ";" (List.map (fun (i1,i2) -> Printf.sprintf "(%i,%i)" i1 i2) file.llines) in
 	let sllines = String.concat ";" (List.map (fun (i1,i2) -> Printf.sprintf "(%i,%i)" i1 i2) file.llines) in
 	let slalines = String.concat ";" (Array.to_list (Array.map (fun (i1,i2) -> Printf.sprintf "(%i,%i)" i1 i2) file.lalines)) in
 	let slalines = String.concat ";" (Array.to_list (Array.map (fun (i1,i2) -> Printf.sprintf "(%i,%i)" i1 i2) file.lalines)) in

+ 11 - 1
src/syntax/parserEntry.ml

@@ -388,6 +388,13 @@ let parse entry ctx code file =
 let parse_string entry com s p error inlined =
 let parse_string entry com s p error inlined =
 	let old = Lexer.save() in
 	let old = Lexer.save() in
 	let old_file = (try Some (Hashtbl.find Lexer.all_files p.pfile) with Not_found -> None) in
 	let old_file = (try Some (Hashtbl.find Lexer.all_files p.pfile) with Not_found -> None) in
+	let restore_file_data =
+		let f = Lexer.make_file old.lfile in
+		Lexer.copy_file old f;
+		(fun () ->
+			Lexer.copy_file f old
+		)
+	in
 	let old_display = display_position#get in
 	let old_display = display_position#get in
 	let old_in_display_file = !in_display_file in
 	let old_in_display_file = !in_display_file in
 	let old_syntax_errors = !syntax_errors in
 	let old_syntax_errors = !syntax_errors in
@@ -401,7 +408,10 @@ let parse_string entry com s p error inlined =
 			in_display_file := old_in_display_file;
 			in_display_file := old_in_display_file;
 		end;
 		end;
 		syntax_errors := old_syntax_errors;
 		syntax_errors := old_syntax_errors;
-		Lexer.restore old
+		Lexer.restore old;
+		(* String parsing might mutate lexer_file information, e.g. from newline() calls. Here we
+		   restore the actual file data (issue #10763). *)
+		restore_file_data()
 	in
 	in
 	if inlined then
 	if inlined then
 		Lexer.init p.pfile
 		Lexer.init p.pfile