diff options
Diffstat (limited to 'cli/tsc.rs')
-rw-r--r-- | cli/tsc.rs | 194 |
1 files changed, 68 insertions, 126 deletions
diff --git a/cli/tsc.rs b/cli/tsc.rs index b9a8c9c4c..61d877e2d 100644 --- a/cli/tsc.rs +++ b/cli/tsc.rs @@ -8,29 +8,26 @@ use crate::disk_cache::DiskCache; use crate::file_fetcher::SourceFile; use crate::file_fetcher::SourceFileFetcher; use crate::flags::Flags; -use crate::fmt_errors::JsError; use crate::global_state::GlobalState; use crate::js; use crate::media_type::MediaType; use crate::module_graph::ModuleGraph; use crate::module_graph::ModuleGraphLoader; -use crate::ops; use crate::permissions::Permissions; use crate::source_maps::SourceMapGetter; -use crate::state::CliModuleLoader; use crate::tsc_config; use crate::version; -use crate::worker::Worker; -use core::task::Context; use deno_core::error::generic_error; use deno_core::error::AnyError; -use deno_core::futures::future::Future; -use deno_core::futures::future::FutureExt; +use deno_core::error::JsError; +use deno_core::json_op_sync; use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::url::Url; +use deno_core::JsRuntime; use deno_core::ModuleSpecifier; +use deno_core::RuntimeOptions; use log::debug; use log::info; use log::Level; @@ -44,15 +41,12 @@ use std::collections::HashSet; use std::fs; use std::io; use std::ops::Deref; -use std::ops::DerefMut; use std::path::Path; use std::path::PathBuf; -use std::pin::Pin; use std::str; use std::sync::atomic::Ordering; use std::sync::Arc; use std::sync::Mutex; -use std::task::Poll; use swc_common::comments::Comment; use swc_common::comments::CommentKind; use swc_ecmascript::dep_graph; @@ -125,71 +119,6 @@ pub struct CompiledModule { pub name: String, } -pub struct CompilerWorker { - worker: Worker, - response: Arc<Mutex<Option<String>>>, -} - -impl CompilerWorker { - pub fn new( - name: String, - permissions: Permissions, - global_state: Arc<GlobalState>, - ) -> Self { - let main_module = - ModuleSpecifier::resolve_url_or_path("./$deno$compiler.ts").unwrap(); - // TODO(bartlomieju): compiler worker shouldn't require any loader/state - let loader = CliModuleLoader::new(None); - let mut worker = Worker::new( - name, - Some(js::compiler_isolate_init()), - permissions, - main_module, - global_state, - loader, - false, - true, - ); - let response = Arc::new(Mutex::new(None)); - ops::runtime::init(&mut worker); - ops::errors::init(&mut worker); - ops::timers::init(&mut worker); - ops::compiler::init(&mut worker, response.clone()); - Self { worker, response } - } - - pub fn get_response(&mut self) -> String { - let mut maybe_response = self.response.lock().unwrap(); - assert!( - maybe_response.is_some(), - "Unexpected missing response from TS compiler" - ); - maybe_response.take().unwrap() - } -} - -impl Deref for CompilerWorker { - type Target = Worker; - fn deref(&self) -> &Self::Target { - &self.worker - } -} - -impl DerefMut for CompilerWorker { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.worker - } -} - -impl Future for CompilerWorker { - type Output = Result<(), AnyError>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { - let inner = self.get_mut(); - inner.worker.poll_unpin(cx) - } -} - lazy_static! { /// Matches the `@deno-types` pragma. static ref DENO_TYPES_RE: Regex = @@ -224,24 +153,6 @@ fn warn_ignored_options( } } -/// Create a new worker with snapshot of TS compiler and setup compiler's -/// runtime. -fn create_compiler_worker( - global_state: &Arc<GlobalState>, - permissions: Permissions, -) -> CompilerWorker { - // TODO(bartlomieju): this metric is never used anywhere - // Count how many times we start the compiler worker. - global_state.compiler_starts.fetch_add(1, Ordering::SeqCst); - - let mut worker = - CompilerWorker::new("TS".to_string(), permissions, global_state.clone()); - worker - .execute("globalThis.bootstrapCompilerRuntime()") - .unwrap(); - worker -} - #[derive(Clone)] pub enum TargetLib { Main, @@ -548,7 +459,6 @@ impl TsCompiler { global_state: &Arc<GlobalState>, source_file: &SourceFile, target: TargetLib, - permissions: Permissions, module_graph: &ModuleGraph, allow_js: bool, ) -> Result<(), AnyError> { @@ -634,8 +544,7 @@ impl TsCompiler { let req_msg = j.to_string(); - let json_str = - execute_in_same_thread(global_state, permissions, req_msg).await?; + let json_str = execute_in_tsc(global_state.clone(), req_msg)?; let compile_response: CompileResponse = serde_json::from_str(&json_str)?; @@ -754,8 +663,7 @@ impl TsCompiler { let req_msg = j.to_string(); - let json_str = - execute_in_same_thread(global_state, permissions, req_msg).await?; + let json_str = execute_in_tsc(global_state.clone(), req_msg)?; let bundle_response: BundleResponse = serde_json::from_str(&json_str)?; @@ -1047,16 +955,62 @@ impl TsCompiler { } } -async fn execute_in_same_thread( - global_state: &Arc<GlobalState>, - permissions: Permissions, +fn execute_in_tsc( + global_state: Arc<GlobalState>, req: String, ) -> Result<String, AnyError> { - let mut worker = create_compiler_worker(&global_state, permissions); + // TODO(bartlomieju): this is only used in testing, I'm not sure it's + // worth keeping around + // Count how many times we start the compiler worker. + global_state.compiler_starts.fetch_add(1, Ordering::SeqCst); + + let mut js_runtime = JsRuntime::new(RuntimeOptions { + startup_snapshot: Some(js::compiler_isolate_init()), + ..Default::default() + }); + + let debug_flag = global_state + .flags + .log_level + .map_or(false, |l| l == log::Level::Debug); + let response = Arc::new(Mutex::new(None)); + + { + js_runtime.register_op( + "op_fetch_asset", + crate::op_fetch_asset::op_fetch_asset(HashMap::default()), + ); + let res = response.clone(); + js_runtime.register_op( + "op_compiler_respond", + json_op_sync(move |_state, args, _bufs| { + let mut response_slot = res.lock().unwrap(); + let replaced_value = response_slot.replace(args.to_string()); + assert!( + replaced_value.is_none(), + "op_compiler_respond found unexpected existing compiler output", + ); + Ok(json!({})) + }), + ); + } + + let bootstrap_script = format!( + "globalThis.bootstrapCompilerRuntime({{ debugFlag: {} }})", + debug_flag + ); + js_runtime.execute("<compiler>", &bootstrap_script)?; + let script = format!("globalThis.tsCompilerOnMessage({{ data: {} }});", req); - worker.execute2("<compiler>", &script)?; - (&mut *worker).await?; - Ok(worker.get_response()) + js_runtime.execute("<compiler>", &script)?; + + let maybe_response = response.lock().unwrap().take(); + assert!( + maybe_response.is_some(), + "Unexpected missing response from TS compiler" + ); + + Ok(maybe_response.unwrap()) } async fn create_runtime_module_graph( @@ -1099,7 +1053,7 @@ async fn create_runtime_module_graph( Ok((root_names, module_graph_loader.get_graph())) } -fn js_error_to_errbox(error: AnyError) -> AnyError { +fn extract_js_error(error: AnyError) -> AnyError { match error.downcast::<JsError>() { Ok(js_error) => { let msg = format!("Error in TS compiler:\n{}", js_error); @@ -1195,10 +1149,8 @@ pub async fn runtime_compile( let compiler = global_state.ts_compiler.clone(); - let json_str = execute_in_same_thread(global_state, permissions, req_msg) - .await - .map_err(js_error_to_errbox)?; - + let json_str = + execute_in_tsc(global_state.clone(), req_msg).map_err(extract_js_error)?; let response: RuntimeCompileResponse = serde_json::from_str(&json_str)?; if response.diagnostics.0.is_empty() && sources.is_none() { @@ -1304,9 +1256,8 @@ pub async fn runtime_bundle( }) .to_string(); - let json_str = execute_in_same_thread(global_state, permissions, req_msg) - .await - .map_err(js_error_to_errbox)?; + let json_str = + execute_in_tsc(global_state.clone(), req_msg).map_err(extract_js_error)?; let _response: RuntimeBundleResponse = serde_json::from_str(&json_str)?; // We're returning `Ok()` instead of `Err()` because it's not runtime // error if there were diagnostics produced; we want to let user handle @@ -1316,8 +1267,7 @@ pub async fn runtime_bundle( /// This function is used by `Deno.transpileOnly()` API. pub async fn runtime_transpile( - global_state: &Arc<GlobalState>, - permissions: Permissions, + global_state: Arc<GlobalState>, sources: &HashMap<String, String>, maybe_options: &Option<String>, ) -> Result<Value, AnyError> { @@ -1343,9 +1293,8 @@ pub async fn runtime_transpile( }) .to_string(); - let json_str = execute_in_same_thread(global_state, permissions, req_msg) - .await - .map_err(js_error_to_errbox)?; + let json_str = + execute_in_tsc(global_state, req_msg).map_err(extract_js_error)?; let v = serde_json::from_str::<Value>(&json_str) .expect("Error decoding JSON string."); Ok(v) @@ -1628,14 +1577,7 @@ mod tests { .unwrap(); let result = ts_compiler - .compile( - &mock_state, - &out, - TargetLib::Main, - Permissions::allow_all(), - &module_graph, - false, - ) + .compile(&mock_state, &out, TargetLib::Main, &module_graph, false) .await; assert!(result.is_ok()); let compiled_file = ts_compiler.get_compiled_module(&out.url).unwrap(); |