summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/Cargo.toml4
-rw-r--r--cli/global_state.rs5
-rw-r--r--cli/swc_util.rs93
-rw-r--r--cli/tsc.rs65
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;