diff options
Diffstat (limited to 'cli/compiler.rs')
-rw-r--r-- | cli/compiler.rs | 102 |
1 files changed, 98 insertions, 4 deletions
diff --git a/cli/compiler.rs b/cli/compiler.rs index 3a036a627..4233262a3 100644 --- a/cli/compiler.rs +++ b/cli/compiler.rs @@ -50,16 +50,22 @@ impl ModuleMetaData { type CompilerConfig = Option<(String, Vec<u8>)>; /// Creates the JSON message send to compiler.ts's onmessage. -fn req(root_names: Vec<String>, compiler_config: CompilerConfig) -> Buf { +fn req( + root_names: Vec<String>, + compiler_config: CompilerConfig, + bundle: Option<String>, +) -> Buf { let j = if let Some((config_path, config_data)) = compiler_config { json!({ "rootNames": root_names, + "bundle": bundle, "configPath": config_path, "config": str::from_utf8(&config_data).unwrap(), }) } else { json!({ "rootNames": root_names, + "bundle": bundle, }) }; j.to_string().into_boxed_str().into_boxed_bytes() @@ -82,6 +88,67 @@ pub fn get_compiler_config( } } +pub fn bundle_async( + state: ThreadSafeState, + module_name: String, + out_file: String, +) -> impl Future<Item = (), Error = Diagnostic> { + debug!( + "Invoking the compiler to bundle. module_name: {}", + module_name + ); + + let root_names = vec![module_name.clone()]; + let compiler_config = get_compiler_config(&state, "typescript"); + let req_msg = req(root_names, compiler_config, Some(out_file)); + + // Count how many times we start the compiler worker. + state.metrics.compiler_starts.fetch_add(1, Ordering::SeqCst); + + let mut worker = Worker::new( + "TS".to_string(), + startup_data::compiler_isolate_init(), + // TODO(ry) Maybe we should use a separate state for the compiler. + // as was done previously. + state.clone(), + ); + js_check(worker.execute("denoMain()")); + js_check(worker.execute("workerMain()")); + js_check(worker.execute("compilerMain()")); + + let resource = worker.state.resource.clone(); + let compiler_rid = resource.rid; + let first_msg_fut = resources::post_message_to_worker(compiler_rid, req_msg) + .then(move |_| worker) + .then(move |result| { + if let Err(err) = result { + // TODO(ry) Need to forward the error instead of exiting. + eprintln!("{}", err.to_string()); + std::process::exit(1); + } + debug!("Sent message to worker"); + let stream_future = + resources::get_message_stream_from_worker(compiler_rid).into_future(); + stream_future.map(|(f, _rest)| f).map_err(|(f, _rest)| f) + }); + + first_msg_fut.map_err(|_| panic!("not handled")).and_then( + move |maybe_msg: Option<Buf>| { + debug!("Received message from worker"); + + if let Some(msg) = maybe_msg { + let json_str = std::str::from_utf8(&msg).unwrap(); + debug!("Message: {}", json_str); + if let Some(diagnostics) = Diagnostic::from_emit_result(json_str) { + return Err(diagnostics); + } + } + + Ok(()) + }, + ) +} + pub fn compile_async( state: ThreadSafeState, module_meta_data: &ModuleMetaData, @@ -95,7 +162,7 @@ pub fn compile_async( let root_names = vec![module_name.clone()]; let compiler_config = get_compiler_config(&state, "typescript"); - let req_msg = req(root_names, compiler_config); + let req_msg = req(root_names, compiler_config, None); // Count how many times we start the compiler worker. state.metrics.compiler_starts.fetch_add(1, Ordering::SeqCst); @@ -197,7 +264,13 @@ mod tests { maybe_source_map: None, }; - out = compile_sync(ThreadSafeState::mock(), &out).unwrap(); + out = compile_sync( + ThreadSafeState::mock(vec![ + String::from("./deno"), + String::from("hello.js"), + ]), + &out, + ).unwrap(); assert!( out .maybe_output_code @@ -210,8 +283,29 @@ mod tests { #[test] fn test_get_compiler_config_no_flag() { let compiler_type = "typescript"; - let state = ThreadSafeState::mock(); + let state = ThreadSafeState::mock(vec![ + String::from("./deno"), + String::from("hello.js"), + ]); let out = get_compiler_config(&state, compiler_type); assert_eq!(out, None); } + + #[test] + fn test_bundle_async() { + let specifier = "./tests/002_hello.ts"; + use crate::worker; + let module_name = worker::root_specifier_to_url(specifier) + .unwrap() + .to_string(); + + let state = ThreadSafeState::mock(vec![ + String::from("./deno"), + String::from("./tests/002_hello.ts"), + String::from("$deno$/bundle.js"), + ]); + let out = + bundle_async(state, module_name, String::from("$deno$/bundle.js")); + assert_eq!(tokio_util::block_on(out), Ok(())); + } } |