diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/Cargo.toml | 10 | ||||
-rw-r--r-- | cli/ast/mod.rs | 208 | ||||
-rw-r--r-- | cli/lsp/analysis.rs | 10 | ||||
-rw-r--r-- | cli/tools/lint.rs | 19 | ||||
-rw-r--r-- | cli/tools/repl.rs | 1 | ||||
-rw-r--r-- | cli/tools/test.rs | 1 |
6 files changed, 129 insertions, 120 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 28a22b359..08b97c9b5 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -39,11 +39,11 @@ winapi = "0.3.9" winres = "0.1.11" [dependencies] -deno_ast = { version = "0.2.0", features = ["bundler", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] } +deno_ast = { version = "0.3.0", features = ["bundler", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] } deno_core = { version = "0.102.0", path = "../core" } -deno_doc = "0.15.0" -deno_graph = "0.6.0" -deno_lint = { version = "0.16.0", features = ["docs"] } +deno_doc = "0.16.0" +deno_graph = "0.7.0" +deno_lint = { version = "0.17.0", features = ["docs"] } deno_runtime = { version = "0.28.0", path = "../runtime" } deno_tls = { version = "0.7.0", path = "../ext/tls" } @@ -54,7 +54,7 @@ data-url = "0.1.0" dissimilar = "1.0.2" dprint-plugin-json = "0.13.0" dprint-plugin-markdown = "0.10.0" -dprint-plugin-typescript = "0.55.0" +dprint-plugin-typescript = "0.57.2" encoding_rs = "0.8.28" env_logger = "0.8.4" fancy-regex = "0.7.1" diff --git a/cli/ast/mod.rs b/cli/ast/mod.rs index 7a05b9caf..8706e9b7f 100644 --- a/cli/ast/mod.rs +++ b/cli/ast/mod.rs @@ -13,6 +13,7 @@ use deno_ast::swc::common::comments::SingleThreadedComments; use deno_ast::swc::common::BytePos; use deno_ast::swc::common::FileName; use deno_ast::swc::common::Globals; +use deno_ast::swc::common::Mark; use deno_ast::swc::common::SourceMap; use deno_ast::swc::common::Spanned; use deno_ast::swc::parser::lexer::Lexer; @@ -23,6 +24,7 @@ use deno_ast::swc::transforms::hygiene; use deno_ast::swc::transforms::pass::Optional; use deno_ast::swc::transforms::proposals; use deno_ast::swc::transforms::react; +use deno_ast::swc::transforms::resolver_with_mark; use deno_ast::swc::transforms::typescript; use deno_ast::swc::visit::FoldWith; use deno_ast::Diagnostic; @@ -214,77 +216,81 @@ pub fn transpile( source_map .new_source_file(file_name, parsed_source.source().text().to_string()); let comments = parsed_source.comments().as_single_threaded(); // needs to be mutable + let globals = Globals::new(); + deno_ast::swc::common::GLOBALS.set(&globals, || { + let top_level_mark = Mark::fresh(Mark::root()); + let jsx_pass = chain!( + resolver_with_mark(top_level_mark), + react::react( + source_map.clone(), + Some(&comments), + react::Options { + pragma: options.jsx_factory.clone(), + pragma_frag: options.jsx_fragment_factory.clone(), + // this will use `Object.assign()` instead of the `_extends` helper + // when spreading props. + use_builtins: true, + ..Default::default() + }, + top_level_mark, + ), + ); + let mut passes = chain!( + Optional::new(jsx_pass, options.transform_jsx), + Optional::new(transforms::DownlevelImportsFolder, options.repl_imports), + Optional::new(transforms::StripExportsFolder, options.repl_imports), + proposals::decorators::decorators(proposals::decorators::Config { + legacy: true, + emit_metadata: options.emit_metadata + }), + helpers::inject_helpers(), + typescript::strip::strip_with_config(strip_config_from_emit_options( + options + )), + fixer(Some(&comments)), + hygiene(), + ); - let jsx_pass = react::react( - source_map.clone(), - Some(&comments), - react::Options { - pragma: options.jsx_factory.clone(), - pragma_frag: options.jsx_fragment_factory.clone(), - // this will use `Object.assign()` instead of the `_extends` helper - // when spreading props. - use_builtins: true, - ..Default::default() - }, - ); - let mut passes = chain!( - Optional::new(jsx_pass, options.transform_jsx), - Optional::new(transforms::DownlevelImportsFolder, options.repl_imports), - Optional::new(transforms::StripExportsFolder, options.repl_imports), - proposals::decorators::decorators(proposals::decorators::Config { - legacy: true, - emit_metadata: options.emit_metadata - }), - // DownlevelImportsFolder::new(), // todo: make this conditional - helpers::inject_helpers(), - typescript::strip::strip_with_config(strip_config_from_emit_options( - options - )), - fixer(Some(&comments)), - hygiene(), - ); - - let program = deno_ast::swc::common::GLOBALS.set(&Globals::new(), || { - helpers::HELPERS.set(&helpers::Helpers::new(false), || { + let program = helpers::HELPERS.set(&helpers::Helpers::new(false), || { program.fold_with(&mut passes) - }) - }); - - let mut src_map_buf = vec![]; - let mut buf = vec![]; - { - let writer = Box::new(JsWriter::new( - source_map.clone(), - "\n", - &mut buf, - Some(&mut src_map_buf), - )); - let config = deno_ast::swc::codegen::Config { minify: false }; - let mut emitter = deno_ast::swc::codegen::Emitter { - cfg: config, - comments: Some(&comments), - cm: source_map.clone(), - wr: writer, - }; - program.emit_with(&mut emitter)?; - } - let mut src = String::from_utf8(buf)?; - let mut map: Option<String> = None; - { - let mut buf = Vec::new(); - source_map - .build_source_map_from(&mut src_map_buf, None) - .to_writer(&mut buf)?; - - if options.inline_source_map { - src.push_str("//# sourceMappingURL=data:application/json;base64,"); - let encoded_map = base64::encode(buf); - src.push_str(&encoded_map); - } else { - map = Some(String::from_utf8(buf)?); + }); + + let mut src_map_buf = vec![]; + let mut buf = vec![]; + { + let writer = Box::new(JsWriter::new( + source_map.clone(), + "\n", + &mut buf, + Some(&mut src_map_buf), + )); + let config = deno_ast::swc::codegen::Config { minify: false }; + let mut emitter = deno_ast::swc::codegen::Emitter { + cfg: config, + comments: Some(&comments), + cm: source_map.clone(), + wr: writer, + }; + program.emit_with(&mut emitter)?; } - } - Ok((src, map)) + let mut src = String::from_utf8(buf)?; + let mut map: Option<String> = None; + { + let mut buf = Vec::new(); + source_map + .build_source_map_from(&mut src_map_buf, None) + .to_writer(&mut buf)?; + + if options.inline_source_map { + src.push_str("//# sourceMappingURL=data:application/json;base64,"); + let encoded_map = base64::encode(buf); + src.push_str(&encoded_map); + } else { + map = Some(String::from_utf8(buf)?); + } + } + Ok((src, map)) + }) } /// A low level function which transpiles a source module into an swc @@ -317,38 +323,43 @@ pub fn transpile_module( } })?; - let jsx_pass = react::react( - cm, - Some(&comments), - react::Options { - pragma: emit_options.jsx_factory.clone(), - pragma_frag: emit_options.jsx_fragment_factory.clone(), - // this will use `Object.assign()` instead of the `_extends` helper - // when spreading props. - use_builtins: true, - ..Default::default() - }, - ); - let mut passes = chain!( - Optional::new(jsx_pass, emit_options.transform_jsx), - proposals::decorators::decorators(proposals::decorators::Config { - legacy: true, - emit_metadata: emit_options.emit_metadata - }), - helpers::inject_helpers(), - typescript::strip::strip_with_config(strip_config_from_emit_options( - emit_options - )), - fixer(Some(&comments)), - ); + deno_ast::swc::common::GLOBALS.set(globals, || { + let top_level_mark = Mark::fresh(Mark::root()); + let jsx_pass = chain!( + resolver_with_mark(top_level_mark), + react::react( + cm, + Some(&comments), + react::Options { + pragma: emit_options.jsx_factory.clone(), + pragma_frag: emit_options.jsx_fragment_factory.clone(), + // this will use `Object.assign()` instead of the `_extends` helper + // when spreading props. + use_builtins: true, + ..Default::default() + }, + top_level_mark, + ), + ); + let mut passes = chain!( + Optional::new(jsx_pass, emit_options.transform_jsx), + proposals::decorators::decorators(proposals::decorators::Config { + legacy: true, + emit_metadata: emit_options.emit_metadata + }), + helpers::inject_helpers(), + typescript::strip::strip_with_config(strip_config_from_emit_options( + emit_options + )), + fixer(Some(&comments)), + ); - let module = deno_ast::swc::common::GLOBALS.set(globals, || { - helpers::HELPERS.set(&helpers::Helpers::new(false), || { + let module = helpers::HELPERS.set(&helpers::Helpers::new(false), || { module.fold_with(&mut passes) - }) - }); + }); - Ok((source_file, module)) + Ok((source_file, module)) + }) } #[cfg(test)] @@ -385,6 +396,7 @@ mod tests { media_type: deno_ast::MediaType::TypeScript, capture_tokens: false, maybe_syntax: None, + scope_analysis: false, }) .expect("could not parse module"); let (code, maybe_map) = transpile(&module, &EmitOptions::default()) @@ -413,6 +425,7 @@ mod tests { media_type: deno_ast::MediaType::Tsx, capture_tokens: false, maybe_syntax: None, + scope_analysis: true, // ensure scope analysis doesn't conflict with a second resolver pass }) .expect("could not parse module"); let (code, _) = transpile(&module, &EmitOptions::default()) @@ -448,6 +461,7 @@ mod tests { media_type: deno_ast::MediaType::TypeScript, capture_tokens: false, maybe_syntax: None, + scope_analysis: false, }) .expect("could not parse module"); let (code, _) = transpile(&module, &EmitOptions::default()) diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index b5fca62f4..643de5c56 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -199,15 +199,10 @@ pub fn get_lint_references( parsed_source: &deno_ast::ParsedSource, maybe_lint_config: Option<&LintConfig>, ) -> Result<Vec<Reference>, AnyError> { - let syntax = deno_ast::get_syntax(parsed_source.media_type()); let lint_rules = get_configured_rules(maybe_lint_config, vec![], vec![], vec![])?; - let linter = create_linter(syntax, lint_rules); - // TODO(dsherret): do not re-parse here again - let (_, lint_diagnostics) = linter.lint( - parsed_source.specifier().to_string(), - parsed_source.source().text_str().to_string(), - )?; + let linter = create_linter(parsed_source.media_type(), lint_rules); + let lint_diagnostics = linter.lint_with_ast(parsed_source); Ok( lint_diagnostics @@ -357,6 +352,7 @@ pub fn parse_module( // capture the tokens for linting and formatting capture_tokens: true, maybe_syntax: None, + scope_analysis: true, // for deno_lint }) } diff --git a/cli/tools/lint.rs b/cli/tools/lint.rs index a565fee1f..6948d2a1f 100644 --- a/cli/tools/lint.rs +++ b/cli/tools/lint.rs @@ -13,7 +13,6 @@ use crate::fmt_errors; use crate::fs_util::{collect_files, is_supported_ext}; use crate::tools::fmt::run_parallelized; use crate::{colors, file_watcher}; -use deno_ast::swc::parser::Syntax; use deno_ast::MediaType; use deno_core::error::{anyhow, generic_error, AnyError, JsStackFrame}; use deno_core::serde_json; @@ -231,27 +230,26 @@ pub fn print_rules_list(json: bool) { } pub fn create_linter( - syntax: Syntax, - rules: Arc<Vec<Box<dyn LintRule>>>, + media_type: MediaType, + rules: Vec<Arc<dyn LintRule>>, ) -> Linter { LinterBuilder::default() .ignore_file_directive("deno-lint-ignore-file") .ignore_diagnostic_directive("deno-lint-ignore") - .syntax(syntax) + .media_type(media_type) .rules(rules) .build() } fn lint_file( file_path: PathBuf, - lint_rules: Arc<Vec<Box<dyn LintRule>>>, + lint_rules: Vec<Arc<dyn LintRule>>, ) -> Result<(Vec<LintDiagnostic>, String), AnyError> { let file_name = file_path.to_string_lossy().to_string(); let source_code = fs::read_to_string(&file_path)?; let media_type = MediaType::from(&file_path); - let syntax = deno_ast::get_syntax(media_type); - let linter = create_linter(syntax, lint_rules); + let linter = create_linter(media_type, lint_rules); let (_, file_diagnostics) = linter.lint(file_name, source_code.clone())?; @@ -262,15 +260,14 @@ fn lint_file( /// Treats input as TypeScript. /// Compatible with `--json` flag. fn lint_stdin( - lint_rules: Arc<Vec<Box<dyn LintRule>>>, + lint_rules: Vec<Arc<dyn LintRule>>, ) -> Result<(Vec<LintDiagnostic>, String), AnyError> { let mut source_code = String::new(); if stdin().read_to_string(&mut source_code).is_err() { return Err(generic_error("Failed to read from stdin")); } - let syntax = deno_ast::get_syntax(MediaType::TypeScript); - let linter = create_linter(syntax, lint_rules); + let linter = create_linter(MediaType::TypeScript, lint_rules); let (_, file_diagnostics) = linter.lint(STDIN_FILE_NAME.to_string(), source_code.clone())?; @@ -489,7 +486,7 @@ pub(crate) fn get_configured_rules( rules_tags: Vec<String>, rules_include: Vec<String>, rules_exclude: Vec<String>, -) -> Result<Arc<Vec<Box<dyn LintRule>>>, AnyError> { +) -> Result<Vec<Arc<dyn LintRule>>, AnyError> { if maybe_lint_config.is_none() && rules_tags.is_empty() && rules_include.is_empty() diff --git a/cli/tools/repl.rs b/cli/tools/repl.rs index 0144db660..7bad940d4 100644 --- a/cli/tools/repl.rs +++ b/cli/tools/repl.rs @@ -655,6 +655,7 @@ impl ReplSession { media_type: deno_ast::MediaType::TypeScript, capture_tokens: false, maybe_syntax: None, + scope_analysis: false, })?; let transpiled_src = transpile( diff --git a/cli/tools/test.rs b/cli/tools/test.rs index aec6e6856..bccd6d731 100644 --- a/cli/tools/test.rs +++ b/cli/tools/test.rs @@ -566,6 +566,7 @@ fn extract_files_from_source_comments( media_type, capture_tokens: false, maybe_syntax: None, + scope_analysis: false, })?; let comments = parsed_source.comments().get_vec(); let blocks_regex = Regex::new(r"```([^\n]*)\n([\S\s]*?)```")?; |