From 76935a7171ef585314e2edf44e815ed0dfc4100b Mon Sep 17 00:00:00 2001 From: Dan Korostelev Date: Sat, 16 Apr 2016 02:41:47 +0300 Subject: [PATCH] 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 --- src/main.ml | 45 +++++++++++++------ src/typing/common.ml | 2 + src/typing/typeload.ml | 14 ++++-- tests/misc/projects/Issue4651/CompServer.hx | 16 +++++++ tests/misc/projects/Issue4651/Main.hx | 4 ++ tests/misc/projects/Issue4651/Main.hx.stdin | 1 + .../Issue4651/compile-server.hxml.disabled | 4 ++ .../Issue4651/compile-server.hxml.stderr | 3 ++ tests/misc/projects/Issue4651/compile.hxml | 1 + .../projects/Issue4651/compile.hxml.stderr | 3 ++ 10 files changed, 75 insertions(+), 18 deletions(-) create mode 100644 tests/misc/projects/Issue4651/CompServer.hx create mode 100644 tests/misc/projects/Issue4651/Main.hx create mode 100644 tests/misc/projects/Issue4651/Main.hx.stdin create mode 100644 tests/misc/projects/Issue4651/compile-server.hxml.disabled create mode 100644 tests/misc/projects/Issue4651/compile-server.hxml.stderr create mode 100644 tests/misc/projects/Issue4651/compile.hxml create mode 100644 tests/misc/projects/Issue4651/compile.hxml.stderr diff --git a/src/main.ml b/src/main.ml index a6c6d1abdba..372ee83f2fe 100644 --- a/src/main.ml +++ b/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 diff --git a/src/typing/common.ml b/src/typing/common.ml index e1f28afdca7..10c15cd9fb2 100644 --- a/src/typing/common.ml +++ b/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") diff --git a/src/typing/typeload.ml b/src/typing/typeload.ml index 5f7fdaf6e53..b8dff1c1275 100644 --- a/src/typing/typeload.ml +++ b/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) diff --git a/tests/misc/projects/Issue4651/CompServer.hx b/tests/misc/projects/Issue4651/CompServer.hx new file mode 100644 index 00000000000..d5e8fc642c8 --- /dev/null +++ b/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(); + } +} \ No newline at end of file diff --git a/tests/misc/projects/Issue4651/Main.hx b/tests/misc/projects/Issue4651/Main.hx new file mode 100644 index 00000000000..5c7e0d6b62e --- /dev/null +++ b/tests/misc/projects/Issue4651/Main.hx @@ -0,0 +1,4 @@ +some + invalid + crap + :-) \ No newline at end of file diff --git a/tests/misc/projects/Issue4651/Main.hx.stdin b/tests/misc/projects/Issue4651/Main.hx.stdin new file mode 100644 index 00000000000..3c783dccd0e --- /dev/null +++ b/tests/misc/projects/Issue4651/Main.hx.stdin @@ -0,0 +1 @@ +class Main { static function main() { Main. } } diff --git a/tests/misc/projects/Issue4651/compile-server.hxml.disabled b/tests/misc/projects/Issue4651/compile-server.hxml.disabled new file mode 100644 index 00000000000..7f246faa5ea --- /dev/null +++ b/tests/misc/projects/Issue4651/compile-server.hxml.disabled @@ -0,0 +1,4 @@ +# --run CompServer +-main CompServer +-neko CompServer.n +-cmd neko CompServer.n diff --git a/tests/misc/projects/Issue4651/compile-server.hxml.stderr b/tests/misc/projects/Issue4651/compile-server.hxml.stderr new file mode 100644 index 00000000000..95814e94986 --- /dev/null +++ b/tests/misc/projects/Issue4651/compile-server.hxml.stderr @@ -0,0 +1,3 @@ + +Void -> Unknown<0> + diff --git a/tests/misc/projects/Issue4651/compile.hxml b/tests/misc/projects/Issue4651/compile.hxml new file mode 100644 index 00000000000..1015330537a --- /dev/null +++ b/tests/misc/projects/Issue4651/compile.hxml @@ -0,0 +1 @@ +-cmd cat Main.hx.stdin | haxe --display Main.hx@43 -D display-stdin \ No newline at end of file diff --git a/tests/misc/projects/Issue4651/compile.hxml.stderr b/tests/misc/projects/Issue4651/compile.hxml.stderr new file mode 100644 index 00000000000..95814e94986 --- /dev/null +++ b/tests/misc/projects/Issue4651/compile.hxml.stderr @@ -0,0 +1,3 @@ + +Void -> Unknown<0> +