diff options
Diffstat (limited to 'cli/build.rs')
-rw-r--r-- | cli/build.rs | 156 |
1 files changed, 96 insertions, 60 deletions
diff --git a/cli/build.rs b/cli/build.rs index 26b27a955..f1eb1829c 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -1,11 +1,14 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. use deno_core::error::custom_error; -use deno_core::op_sync; +use deno_core::error::AnyError; +use deno_core::op; use deno_core::serde::Deserialize; use deno_core::serde_json::json; use deno_core::serde_json::Value; +use deno_core::Extension; use deno_core::JsRuntime; +use deno_core::OpState; use deno_core::RuntimeOptions; use regex::Regex; use std::collections::HashMap; @@ -185,79 +188,112 @@ fn create_compiler_snapshot( build_libs.push(op_lib.to_owned()); } - let re_asset = Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex"); - let build_specifier = "asset:///bootstrap.ts"; + #[op] + fn op_build_info( + state: &mut OpState, + _args: Value, + _: (), + ) -> Result<Value, AnyError> { + let build_specifier = "asset:///bootstrap.ts"; + let build_libs = state.borrow::<Vec<&str>>(); + Ok(json!({ + "buildSpecifier": build_specifier, + "libs": build_libs, + })) + } - let mut js_runtime = JsRuntime::new(RuntimeOptions { - will_snapshot: true, - ..Default::default() - }); - js_runtime.register_op( - "op_build_info", - op_sync(move |_state, _args: Value, _: ()| { - Ok(json!({ - "buildSpecifier": build_specifier, - "libs": build_libs, - })) - }), - ); - js_runtime.register_op( - "op_cwd", - op_sync(move |_state, _args: Value, _: ()| Ok(json!("cache:///"))), - ); - // As of TypeScript 4.5, it tries to detect the existence of substitute lib - // files, which we currently don't use, so we just return false. - js_runtime.register_op( - "op_exists", - op_sync(move |_state, _args: LoadArgs, _: ()| Ok(json!(false))), - ); + #[op] + fn op_cwd( + _state: &mut OpState, + _args: Value, + _: (), + ) -> Result<Value, AnyError> { + Ok(json!("cache:///")) + } + + #[op] + fn op_exists( + _state: &mut OpState, + _args: Value, + _: (), + ) -> Result<Value, AnyError> { + Ok(json!(false)) + } + + #[op] // using the same op that is used in `tsc.rs` for loading modules and reading // files, but a slightly different implementation at build time. - js_runtime.register_op( - "op_load", - op_sync(move |_state, args: LoadArgs, _: ()| { - // we need a basic file to send to tsc to warm it up. - if args.specifier == build_specifier { + fn op_load( + state: &mut OpState, + args: LoadArgs, + _: (), + ) -> Result<Value, AnyError> { + let op_crate_libs = state.borrow::<HashMap<&str, &str>>(); + let path_dts = state.borrow::<PathBuf>(); + let re_asset = + Regex::new(r"asset:/{3}lib\.(\S+)\.d\.ts").expect("bad regex"); + let build_specifier = "asset:///bootstrap.ts"; + + // we need a basic file to send to tsc to warm it up. + if args.specifier == build_specifier { + Ok(json!({ + "data": r#"console.log("hello deno!");"#, + "hash": "1", + // this corresponds to `ts.ScriptKind.TypeScript` + "scriptKind": 3 + })) + // specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to + // parse out just the name so we can lookup the asset. + } else if let Some(caps) = re_asset.captures(&args.specifier) { + if let Some(lib) = caps.get(1).map(|m| m.as_str()) { + // if it comes from an op crate, we were supplied with the path to the + // file. + let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) { + PathBuf::from(op_crate_lib).canonicalize().unwrap() + // otherwise we are will generate the path ourself + } else { + path_dts.join(format!("lib.{}.d.ts", lib)) + }; + let data = std::fs::read_to_string(path)?; Ok(json!({ - "data": r#"console.log("hello deno!");"#, + "data": data, "hash": "1", // this corresponds to `ts.ScriptKind.TypeScript` "scriptKind": 3 })) - // specifiers come across as `asset:///lib.{lib_name}.d.ts` and we need to - // parse out just the name so we can lookup the asset. - } else if let Some(caps) = re_asset.captures(&args.specifier) { - if let Some(lib) = caps.get(1).map(|m| m.as_str()) { - // if it comes from an op crate, we were supplied with the path to the - // file. - let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) { - PathBuf::from(op_crate_lib).canonicalize().unwrap() - // otherwise we are will generate the path ourself - } else { - path_dts.join(format!("lib.{}.d.ts", lib)) - }; - let data = std::fs::read_to_string(path)?; - Ok(json!({ - "data": data, - "hash": "1", - // this corresponds to `ts.ScriptKind.TypeScript` - "scriptKind": 3 - })) - } else { - Err(custom_error( - "InvalidSpecifier", - format!("An invalid specifier was requested: {}", args.specifier), - )) - } } else { Err(custom_error( "InvalidSpecifier", format!("An invalid specifier was requested: {}", args.specifier), )) } - }), - ); - js_runtime.sync_ops_cache(); + } else { + Err(custom_error( + "InvalidSpecifier", + format!("An invalid specifier was requested: {}", args.specifier), + )) + } + } + let js_runtime = JsRuntime::new(RuntimeOptions { + will_snapshot: true, + extensions: vec![Extension::builder() + .ops(vec![ + op_build_info::decl(), + op_cwd::decl(), + op_exists::decl(), + op_load::decl(), + ]) + .state(move |state| { + state.put(op_crate_libs.clone()); + state.put(build_libs.clone()); + state.put(path_dts.clone()); + + Ok(()) + }) + .build()], + ..Default::default() + }); + create_snapshot(js_runtime, snapshot_path, files); } |