diff options
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/Cargo.toml | 4 | ||||
| -rw-r--r-- | cli/global_state.rs | 5 | ||||
| -rw-r--r-- | cli/swc_util.rs | 93 | ||||
| -rw-r--r-- | cli/tsc.rs | 65 |
4 files changed, 103 insertions, 64 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 3e1e1e75f..076a4e6b0 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -23,7 +23,7 @@ winapi = "0.3.8" [dependencies] deno_core = { path = "../core", version = "0.50.0" } -deno_lint = "0.1.17" +deno_lint = "0.1.19" atty = "0.2.14" base64 = "0.12.2" @@ -50,6 +50,8 @@ serde_derive = "1.0.112" serde_json = { version = "1.0.55", features = [ "preserve_order" ] } sys-info = "0.7.0" sourcemap = "6.0.0" +swc_ecma_transforms = "=0.16.0" +swc_ecma_codegen = "=0.29.1" tempfile = "3.1.0" termcolor = "1.1.0" tokio = { version = "0.2.22", features = ["full"] } diff --git a/cli/global_state.rs b/cli/global_state.rs index 8e5808c90..a26fc453e 100644 --- a/cli/global_state.rs +++ b/cli/global_state.rs @@ -174,10 +174,7 @@ impl GlobalState { if should_compile { if self.flags.no_check { - self - .ts_compiler - .transpile(self.clone(), permissions, module_graph) - .await?; + self.ts_compiler.transpile(module_graph).await?; } else { self .ts_compiler diff --git a/cli/swc_util.rs b/cli/swc_util.rs index 8203c4c3a..d79f7cccb 100644 --- a/cli/swc_util.rs +++ b/cli/swc_util.rs @@ -12,18 +12,29 @@ use crate::swc_common::Globals; use crate::swc_common::SourceMap; use crate::swc_common::Span; use crate::swc_ecma_ast; +use crate::swc_ecma_ast::Program; use crate::swc_ecma_parser::lexer::Lexer; use crate::swc_ecma_parser::EsConfig; use crate::swc_ecma_parser::JscTarget; use crate::swc_ecma_parser::Parser; -use crate::swc_ecma_parser::Session; use crate::swc_ecma_parser::SourceFileInput; use crate::swc_ecma_parser::Syntax; use crate::swc_ecma_parser::TsConfig; +use crate::swc_ecma_visit::FoldWith; +use deno_core::ErrBox; use std::error::Error; use std::fmt; use std::sync::Arc; use std::sync::RwLock; +use swc_common::chain; +use swc_ecma_codegen::text_writer::JsWriter; +use swc_ecma_codegen::Node; +use swc_ecma_transforms::fixer; +use swc_ecma_transforms::typescript; + +struct DummyHandler; + +impl swc_ecma_codegen::Handlers for DummyHandler {} fn get_default_es_config() -> EsConfig { let mut config = EsConfig::default(); @@ -179,34 +190,77 @@ impl AstParser { ); let buffered_err = self.buffered_error.clone(); - let session = Session { - handler: &self.handler, - }; - let syntax = get_syntax_for_media_type(media_type); let lexer = Lexer::new( - session, syntax, JscTarget::Es2019, SourceFileInput::from(&*swc_source_file), Some(&self.comments), ); - let mut parser = Parser::new_from(session, lexer); + let mut parser = Parser::new_from(lexer); - let parse_result = - parser - .parse_module() - .map_err(move |mut err: DiagnosticBuilder| { - err.emit(); - SwcDiagnosticBuffer::from_swc_error(buffered_err, self) - }); + let parse_result = parser.parse_module().map_err(move |err| { + let mut diagnostic = err.into_diagnostic(&self.handler); + diagnostic.emit(); + SwcDiagnosticBuffer::from_swc_error(buffered_err, self) + }); callback(parse_result) }) } + pub fn strip_types( + &self, + file_name: &str, + media_type: MediaType, + source_code: &str, + ) -> Result<String, ErrBox> { + self.parse_module(file_name, media_type, source_code, |parse_result| { + let module = parse_result?; + let program = Program::Module(module); + let mut compiler_pass = chain!(typescript::strip(), fixer()); + let program = swc_ecma_transforms::util::COMMENTS + .set(&self.comments, || program.fold_with(&mut compiler_pass)); + + let mut src_map_buf = vec![]; + let mut buf = vec![]; + { + let handlers = Box::new(DummyHandler); + let writer = Box::new(JsWriter::new( + self.source_map.clone(), + "\n", + &mut buf, + Some(&mut src_map_buf), + )); + let config = swc_ecma_codegen::Config { minify: false }; + let mut emitter = swc_ecma_codegen::Emitter { + cfg: config, + comments: Some(&self.comments), + cm: self.source_map.clone(), + wr: writer, + handlers, + }; + program.emit_with(&mut emitter)?; + } + let mut src = String::from_utf8(buf).map_err(ErrBox::from)?; + { + let mut buf = vec![]; + self + .source_map + .build_source_map_from(&mut src_map_buf, None) + .to_writer(&mut buf)?; + let map = String::from_utf8(buf)?; + + src.push_str("//# sourceMappingURL=data:application/json;base64,"); + let encoded_map = base64::encode(map.as_bytes()); + src.push_str(&encoded_map); + } + Ok(src) + }) + } + pub fn get_span_location(&self, span: Span) -> swc_common::Loc { self.source_map.lookup_char_pos(span.lo()) } @@ -227,3 +281,14 @@ impl AstParser { } } } + +#[test] +fn test_strip_types() { + let ast_parser = AstParser::default(); + let result = ast_parser + .strip_types("test.ts", MediaType::TypeScript, "const a: number = 10;") + .unwrap(); + assert!(result.starts_with( + "const a = 10;\n//# sourceMappingURL=data:application/json;base64," + )); +} diff --git a/cli/tsc.rs b/cli/tsc.rs index b3d8aebd9..7bc70c786 100644 --- a/cli/tsc.rs +++ b/cli/tsc.rs @@ -413,13 +413,6 @@ struct CompileResponse { build_info: Option<String>, stats: Option<Vec<Stat>>, } -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct TranspileResponse { - diagnostics: Diagnostic, - emit_map: HashMap<String, EmittedSource>, - stats: Option<Vec<Stat>>, -} // TODO(bartlomieju): possible deduplicate once TS refactor is stabilized #[derive(Deserialize)] @@ -742,8 +735,6 @@ impl TsCompiler { pub async fn transpile( &self, - global_state: GlobalState, - permissions: Permissions, module_graph: ModuleGraph, ) -> Result<(), ErrBox> { let mut source_files: Vec<TranspileSourceFile> = Vec::new(); @@ -762,44 +753,30 @@ impl TsCompiler { return Ok(()); } - let source_files_json = - serde_json::to_value(source_files).expect("Filed to serialize data"); - let compiler_config = self.config.clone(); - let cwd = std::env::current_dir().unwrap(); - let performance = - matches!(global_state.flags.log_level, Some(Level::Debug)); - let j = match (compiler_config.path, compiler_config.content) { - (Some(config_path), Some(config_data)) => json!({ - "config": str::from_utf8(&config_data).unwrap(), - "configPath": config_path, - "cwd": cwd, - "performance": performance, - "sourceFiles": source_files_json, - "type": msg::CompilerRequestType::Transpile, - }), - _ => json!({ - "performance": performance, - "sourceFiles": source_files_json, - "type": msg::CompilerRequestType::Transpile, - }), - }; + let mut emit_map = HashMap::new(); - let req_msg = j.to_string(); + for source_file in source_files { + let parser = AstParser::default(); + let stripped_source = parser.strip_types( + &source_file.file_name, + MediaType::TypeScript, + &source_file.source_code, + )?; - let json_str = - execute_in_same_thread(global_state.clone(), permissions, req_msg) - .await?; - - let transpile_response: TranspileResponse = - serde_json::from_str(&json_str)?; + // TODO(bartlomieju): this is superfluous, just to make caching function happy + let emitted_filename = PathBuf::from(&source_file.file_name) + .with_extension("js") + .to_string_lossy() + .to_string(); + let emitted_source = EmittedSource { + filename: source_file.file_name.to_string(), + contents: stripped_source, + }; - if !transpile_response.diagnostics.items.is_empty() { - return Err(ErrBox::from(transpile_response.diagnostics)); + emit_map.insert(emitted_filename, emitted_source); } - maybe_log_stats(transpile_response.stats); - - self.cache_emitted_files(transpile_response.emit_map)?; + self.cache_emitted_files(emit_map)?; Ok(()) } @@ -1710,9 +1687,7 @@ mod tests { ) .unwrap(); - let result = ts_compiler - .transpile(mock_state.clone(), Permissions::allow_all(), module_graph) - .await; + let result = ts_compiler.transpile(module_graph).await; assert!(result.is_ok()); let compiled_file = ts_compiler.get_compiled_module(&out.url).unwrap(); let source_code = compiled_file.code; |
