Browse Source

Display stdin (#5120)

* Implement reading display file from stdin (closes #4651)

* disable compilation server test for now because of some weird sys.io.Process issues making it hang on linux/travis (the test works for me on windows)

* use typed define for display-stdin
Dan Korostelev 9 years ago
parent
commit
76935a7171

+ 31 - 14
src/main.ml

@@ -700,21 +700,28 @@ and wait_loop boot_com host port =
 	} in
 	global_cache := Some cache;
 	Typer.macro_enable_cache := true;
+	let current_stdin = ref None in
 	Typeload.parse_hook := (fun com2 file p ->
-		let sign = get_signature com2 in
 		let ffile = Common.unique_full_path file in
-		let ftime = file_time ffile in
-		let fkey = ffile ^ "!" ^ sign in
-		try
-			let time, data = Hashtbl.find cache.c_files fkey in
-			if time <> ftime then raise Not_found;
-			data
-		with Not_found ->
-			has_parse_error := false;
-			let data = Typeload.parse_file com2 file p in
-			if verbose then print_endline ("Parsed " ^ ffile);
-			if not !has_parse_error && ffile <> (!Parser.resume_display).Ast.pfile then Hashtbl.replace cache.c_files fkey (ftime,data);
-			data
+		let is_display_file = ffile = (!Parser.resume_display).Ast.pfile in
+
+		match is_display_file, !current_stdin with
+		| true, Some stdin when Common.defined com2 Define.DisplayStdin ->
+			Typeload.parse_file_from_string com2 file p stdin
+		| _ ->
+			let sign = get_signature com2 in
+			let ftime = file_time ffile in
+			let fkey = ffile ^ "!" ^ sign in
+			try
+				let time, data = Hashtbl.find cache.c_files fkey in
+				if time <> ftime then raise Not_found;
+				data
+			with Not_found ->
+				has_parse_error := false;
+				let data = Typeload.parse_file com2 file p in
+				if verbose then print_endline ("Parsed " ^ ffile);
+				if not !has_parse_error && (not is_display_file) then Hashtbl.replace cache.c_files fkey (ftime,data);
+				data
 	);
 	let cache_module m =
 		Hashtbl.replace cache.c_modules (m.m_path,m.m_extra.m_sign) m;
@@ -894,7 +901,16 @@ and wait_loop boot_com host port =
 			ctx
 		in
 		(try
-			let data = parse_hxml_data (read_loop 0) in
+			let s = (read_loop 0) in
+			let hxml =
+				try
+					let idx = String.index s '\001' in
+					current_stdin := Some (String.sub s (idx + 1) ((String.length s) - idx - 1));
+					(String.sub s 0 idx)
+				with Not_found ->
+					s
+			in
+			let data = parse_hxml_data hxml in
 			Unix.clear_nonblock sin;
 			if verbose then print_endline ("Processing Arguments [" ^ String.concat "," data ^ "]");
 			(try
@@ -934,6 +950,7 @@ and wait_loop boot_com host port =
 			(try ssend sin estr with _ -> ());
 		);
 		Unix.close sin;
+		current_stdin := None;
 		(* prevent too much fragmentation by doing some compactions every X run *)
 		incr run_count;
 		if !run_count mod 10 = 0 then begin

+ 2 - 0
src/typing/common.ml

@@ -177,6 +177,7 @@ module Define = struct
 		| DceDebug
 		| Debug
 		| Display
+		| DisplayStdin
 		| DllExport
 		| DllImport
 		| DocGen
@@ -267,6 +268,7 @@ module Define = struct
 		| DceDebug -> ("dce_debug","Show DCE log")
 		| Debug -> ("debug","Activated when compiling with -debug")
 		| Display -> ("display","Activated during completion")
+		| DisplayStdin -> ("display_stdin","Read the contents of a file specified in --display from standard input")
 		| DllExport -> ("dll_export", "GenCPP experimental linking")
 		| DllImport -> ("dll_import", "GenCPP experimental linking")
 		| DocGen -> ("doc_gen","Do not perform any removal/change in order to correctly generate documentation")

+ 10 - 4
src/typing/typeload.ml

@@ -221,17 +221,23 @@ let module_pass_1 ctx m tdecls loadp =
 	let decls = List.rev !decls in
 	decls, List.rev tdecls
 
-let parse_file com file p =
-	let ch = (try open_in_bin file with _ -> error ("Could not open " ^ file) p) in
+let parse_file_from_lexbuf com file p lexbuf =
 	let t = Common.timer "parsing" in
 	Lexer.init file true;
 	incr stats.s_files_parsed;
-	let data = (try Parser.parse com (Lexing.from_channel ch) with e -> close_in ch; t(); raise e) in
-	close_in ch;
+	let data = (try Parser.parse com lexbuf with e -> t(); raise e) in
 	t();
 	Common.log com ("Parsed " ^ file);
 	data
 
+let parse_file_from_string com file p string =
+	parse_file_from_lexbuf com file p (Lexing.from_string string)
+
+let parse_file com file p =
+	let use_stdin = (Common.defined com Define.DisplayStdin) && (Common.unique_full_path file) = !Parser.resume_display.pfile in
+	let ch = if use_stdin then stdin else (try open_in_bin file with _ -> error ("Could not open " ^ file) p) in
+	Std.finally (fun() -> close_in ch) (parse_file_from_lexbuf com file p) (Lexing.from_channel ch)
+
 let parse_hook = ref parse_file
 let type_module_hook = ref (fun _ _ _ -> None)
 let type_function_params_rec = ref (fun _ _ _ _ -> assert false)

+ 16 - 0
tests/misc/projects/Issue4651/CompServer.hx

@@ -0,0 +1,16 @@
+class CompServer {
+    static function main() {
+        var port = 4000;
+        var server = new sys.io.Process("haxe", ["--wait", "" + port]);
+        var socket = new sys.net.Socket();
+        socket.connect(new sys.net.Host("localhost"), port);
+        socket.write("--display Main.hx@43\n-D display-stdin");
+        socket.write("\x01");
+        socket.write(sys.io.File.getContent("Main.hx.stdin"));
+        socket.write("\x00");
+        var out = socket.read();
+        socket.close();
+        Sys.stderr().writeString(out);
+        server.kill();
+    }
+}

+ 4 - 0
tests/misc/projects/Issue4651/Main.hx

@@ -0,0 +1,4 @@
+some
+    invalid
+    crap
+        :-)

+ 1 - 0
tests/misc/projects/Issue4651/Main.hx.stdin

@@ -0,0 +1 @@
+class Main { static function main() { Main. } }

+ 4 - 0
tests/misc/projects/Issue4651/compile-server.hxml.disabled

@@ -0,0 +1,4 @@
+# --run CompServer
+-main CompServer
+-neko CompServer.n
+-cmd neko CompServer.n

+ 3 - 0
tests/misc/projects/Issue4651/compile-server.hxml.stderr

@@ -0,0 +1,3 @@
+<list>
+<i n="main"><t>Void -&gt; Unknown&lt;0&gt;</t><d></d></i>
+</list>

+ 1 - 0
tests/misc/projects/Issue4651/compile.hxml

@@ -0,0 +1 @@
+-cmd cat Main.hx.stdin | haxe --display Main.hx@43 -D display-stdin

+ 3 - 0
tests/misc/projects/Issue4651/compile.hxml.stderr

@@ -0,0 +1,3 @@
+<list>
+<i n="main"><t>Void -&gt; Unknown&lt;0&gt;</t><d></d></i>
+</list>