summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/Cargo.toml10
-rw-r--r--cli/ast/mod.rs208
-rw-r--r--cli/lsp/analysis.rs10
-rw-r--r--cli/tools/lint.rs19
-rw-r--r--cli/tools/repl.rs1
-rw-r--r--cli/tools/test.rs1
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]*?)```")?;