diff options
author | Andy Finch <andyfinch7@gmail.com> | 2020-02-01 03:02:23 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-01 12:02:23 +0100 |
commit | 4f8a5c0239cd633ea3fd15a27046da3edee2b2f2 (patch) | |
tree | 80467fdd1132a44dc7fce01d73261693ee6c7fb5 /deno_typescript | |
parent | 2cd3994902fb6a4d4d0603c839a78503d792b96a (diff) |
feat: support crate imports in deno_typescript (#3814)
Co-authored-by: Ryan Dahl <ry@tinyclouds.org>
Diffstat (limited to 'deno_typescript')
-rw-r--r-- | deno_typescript/compiler_main.js | 4 | ||||
-rw-r--r-- | deno_typescript/lib.rs | 19 | ||||
-rw-r--r-- | deno_typescript/ops.rs | 45 |
3 files changed, 48 insertions, 20 deletions
diff --git a/deno_typescript/compiler_main.js b/deno_typescript/compiler_main.js index 94b38e070..013d6e157 100644 --- a/deno_typescript/compiler_main.js +++ b/deno_typescript/compiler_main.js @@ -184,8 +184,8 @@ class Host { fileName = moduleMap.get(fileName); } - const { sourceCode, moduleName } = dispatch("readFile", { - fileName, + const { sourceCode, moduleName } = dispatch("loadModule", { + moduleUrl: fileName, languageVersion, shouldCreateNewSourceFile }); diff --git a/deno_typescript/lib.rs b/deno_typescript/lib.rs index 1bf6eb351..7977b7cfe 100644 --- a/deno_typescript/lib.rs +++ b/deno_typescript/lib.rs @@ -16,6 +16,7 @@ use deno_core::StartupData; use deno_core::ZeroCopyBuf; pub use ops::EmitResult; use ops::WrittenFile; +use std::collections::HashMap; use std::fs; use std::path::Path; use std::path::PathBuf; @@ -32,6 +33,8 @@ pub fn ts_version() -> String { pkg["version"].as_str().unwrap().to_string() } +type ExternCrateModules = HashMap<String, String>; + #[derive(Debug)] pub struct TSState { bundle: bool, @@ -40,6 +43,7 @@ pub struct TSState { /// A list of files emitted by typescript. WrittenFile is tuple of the form /// (url, corresponding_module, source_code) written_files: Vec<WrittenFile>, + extern_crate_modules: ExternCrateModules, } fn compiler_op<D>( @@ -62,21 +66,27 @@ pub struct TSIsolate { } impl TSIsolate { - fn new(bundle: bool) -> TSIsolate { + fn new( + bundle: bool, + maybe_extern_crate_modules: Option<ExternCrateModules>, + ) -> TSIsolate { let mut isolate = Isolate::new(StartupData::None, false); js_check(isolate.execute("assets/typescript.js", TYPESCRIPT_CODE)); js_check(isolate.execute("compiler_main.js", COMPILER_CODE)); + let extern_crate_modules = maybe_extern_crate_modules.unwrap_or_default(); + let state = Arc::new(Mutex::new(TSState { bundle, exit_code: 0, emit_result: None, written_files: Vec::new(), + extern_crate_modules, })); isolate.register_op( - "readFile", - compiler_op(state.clone(), ops::json_op(ops::read_file)), + "loadModule", + compiler_op(state.clone(), ops::json_op(ops::load_module)), ); isolate .register_op("exit", compiler_op(state.clone(), ops::json_op(ops::exit))); @@ -125,8 +135,9 @@ impl TSIsolate { pub fn compile_bundle( bundle_filename: &Path, root_names: Vec<PathBuf>, + extern_crate_modules: Option<ExternCrateModules>, ) -> Result<String, ErrBox> { - let ts_isolate = TSIsolate::new(true); + let ts_isolate = TSIsolate::new(true, extern_crate_modules); let config_json = serde_json::json!({ "compilerOptions": { diff --git a/deno_typescript/ops.rs b/deno_typescript/ops.rs index f76662620..f9b244397 100644 --- a/deno_typescript/ops.rs +++ b/deno_typescript/ops.rs @@ -35,16 +35,16 @@ pub fn json_op(d: Dispatcher) -> impl Fn(&mut TSState, &[u8]) -> CoreOp { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -struct ReadFile { - file_name: String, +struct LoadModule { + module_url: String, language_version: Option<i32>, should_create_new_source_file: bool, } -pub fn read_file(_s: &mut TSState, v: Value) -> Result<Value, ErrBox> { - let v: ReadFile = serde_json::from_value(v)?; - let (module_name, source_code) = if v.file_name.starts_with("$asset$/") { - let asset = v.file_name.replace("$asset$/", ""); +pub fn load_module(s: &mut TSState, v: Value) -> Result<Value, ErrBox> { + let v: LoadModule = serde_json::from_value(v)?; + let (module_name, source_code) = if v.module_url.starts_with("$asset$/") { + let asset = v.module_url.replace("$asset$/", ""); let source_code = match crate::get_asset(&asset) { Some(code) => code.to_string(), @@ -58,14 +58,31 @@ pub fn read_file(_s: &mut TSState, v: Value) -> Result<Value, ErrBox> { (asset, source_code) } else { - assert!(!v.file_name.starts_with("$assets$"), "you meant $asset$"); - let module_specifier = ModuleSpecifier::resolve_url_or_path(&v.file_name)?; - let path = module_specifier.as_url().to_file_path().unwrap(); - println!("cargo:rerun-if-changed={}", path.display()); - ( - module_specifier.as_str().to_string(), - std::fs::read_to_string(&path)?, - ) + assert!(!v.module_url.starts_with("$assets$"), "you meant $asset$"); + let module_specifier = ModuleSpecifier::resolve_url_or_path(&v.module_url)?; + let module_url = module_specifier.as_url(); + match module_url.scheme() { + "file" => { + let path = module_url.to_file_path().unwrap(); + println!("cargo:rerun-if-changed={}", path.display()); + ( + module_specifier.as_str().to_string(), + std::fs::read_to_string(&path)?, + ) + } + "crate" => { + let crate_name = module_url.host_str().unwrap(); + // TODO(afinch7) turn failures here into real error messages. + let path_prefix = s.extern_crate_modules.get(crate_name).unwrap(); + let path = + std::path::Path::new(path_prefix).join(&module_url.path()[1..]); + ( + module_specifier.as_str().to_string(), + std::fs::read_to_string(&path)?, + ) + } + _ => unimplemented!(), + } }; Ok(json!({ "moduleName": module_name, |