diff options
-rw-r--r-- | Cargo.lock | 4 | ||||
-rw-r--r-- | cli/Cargo.toml | 2 | ||||
-rw-r--r-- | cli/args/mod.rs | 21 | ||||
-rw-r--r-- | cli/lsp/analysis.rs | 4 | ||||
-rw-r--r-- | cli/lsp/config.rs | 28 | ||||
-rw-r--r-- | cli/lsp/diagnostics.rs | 26 | ||||
-rw-r--r-- | cli/tools/lint/mod.rs | 31 |
7 files changed, 103 insertions, 13 deletions
diff --git a/Cargo.lock b/Cargo.lock index 40a0a8229..2b2b52c8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1589,9 +1589,9 @@ dependencies = [ [[package]] name = "deno_lint" -version = "0.58.4" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0622dde23f672fa3bb0788cef3cfc31ea21fc8570cd2b7e862d1e6575a527efe" +checksum = "0568595fd7f8ad76ddf66d70c1c5e3e680ad95c3d5abb44556e94d824643d6e2" dependencies = [ "anyhow", "deno_ast", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 2018aa73f..0533e1317 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -70,7 +70,7 @@ deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] deno_doc = { version = "=0.137.0", features = ["html", "syntect"] } deno_emit = "=0.41.0" deno_graph = { version = "=0.77.2", features = ["tokio_executor"] } -deno_lint = { version = "=0.58.4", features = ["docs"] } +deno_lint = { version = "=0.59.1", features = ["docs"] } deno_lockfile.workspace = true deno_npm = "=0.21.0" deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] } diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 69adee970..5bdecca9b 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -1445,6 +1445,27 @@ impl CliOptions { LintOptions::resolve(maybe_lint_config, Some(lint_flags), &self.initial_cwd) } + pub fn resolve_lint_config( + &self, + ) -> Result<deno_lint::linter::LintConfig, AnyError> { + let ts_config_result = + self.resolve_ts_config_for_emit(TsConfigType::Emit)?; + + let (transpile_options, _) = + crate::args::ts_config_to_transpile_and_emit_options( + ts_config_result.ts_config, + )?; + + Ok(deno_lint::linter::LintConfig { + default_jsx_factory: transpile_options + .jsx_automatic + .then(|| transpile_options.jsx_factory.clone()), + default_jsx_fragment_factory: transpile_options + .jsx_automatic + .then(|| transpile_options.jsx_fragment_factory.clone()), + }) + } + pub fn resolve_config_excludes(&self) -> Result<PathOrPatternSet, AnyError> { let maybe_config_files = if let Some(config_file) = &self.maybe_config_file { diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index 9c7025781..f60f2e044 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -9,6 +9,7 @@ use super::tsc; use crate::args::jsr_url; use crate::tools::lint::create_linter; +use deno_lint::linter::LintConfig; use deno_runtime::fs_util::specifier_to_file_path; use deno_ast::SourceRange; @@ -169,9 +170,10 @@ fn as_lsp_range( pub fn get_lint_references( parsed_source: &deno_ast::ParsedSource, lint_rules: Vec<&'static dyn LintRule>, + lint_config: LintConfig, ) -> Result<Vec<Reference>, AnyError> { let linter = create_linter(lint_rules); - let lint_diagnostics = linter.lint_with_ast(parsed_source); + let lint_diagnostics = linter.lint_with_ast(parsed_source, lint_config); Ok( lint_diagnostics diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index 364999cff..02f3d5afb 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -24,6 +24,7 @@ use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::serde_json::Value; use deno_core::ModuleSpecifier; +use deno_lint::linter::LintConfig; use deno_lockfile::Lockfile; use deno_npm::npm_rc::ResolvedNpmRc; use deno_runtime::deno_node::PackageJson; @@ -1055,6 +1056,9 @@ impl Default for LspTsConfig { "target": "esnext", "useDefineForClassFields": true, "useUnknownInCatchVariables": false, + "jsx": "react", + "jsxFactory": "React.createElement", + "jsxFragmentFactory": "React.Fragment", })), } } @@ -1087,6 +1091,7 @@ pub struct ConfigData { pub config_file: Option<Arc<ConfigFile>>, pub fmt_options: Arc<FmtOptions>, pub lint_options: Arc<LintOptions>, + pub lint_config: LintConfig, pub lint_rules: Arc<ConfiguredRules>, pub ts_config: Arc<LspTsConfig>, pub byonm: bool, @@ -1253,6 +1258,28 @@ impl ConfigData { let ts_config = LspTsConfig::new(config_file.as_ref()); + let lint_config = if ts_config.inner.0.get("jsx").and_then(|v| v.as_str()) + == Some("react") + { + let default_jsx_factory = + ts_config.inner.0.get("jsxFactory").and_then(|v| v.as_str()); + let default_jsx_fragment_factory = ts_config + .inner + .0 + .get("jsxFragmentFactory") + .and_then(|v| v.as_str()); + deno_lint::linter::LintConfig { + default_jsx_factory: default_jsx_factory.map(String::from), + default_jsx_fragment_factory: default_jsx_fragment_factory + .map(String::from), + } + } else { + deno_lint::linter::LintConfig { + default_jsx_factory: None, + default_jsx_fragment_factory: None, + } + }; + let vendor_dir = config_file.as_ref().and_then(|c| c.vendor_dir_path()); // Load lockfile @@ -1429,6 +1456,7 @@ impl ConfigData { config_file: config_file.map(Arc::new), fmt_options, lint_options, + lint_config, lint_rules, ts_config: Arc::new(ts_config), byonm, diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index 35da778dc..9e54c8106 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -38,6 +38,7 @@ use deno_graph::source::ResolutionMode; use deno_graph::Resolution; use deno_graph::ResolutionError; use deno_graph::SpecifierError; +use deno_lint::linter::LintConfig; use deno_lint::rules::LintRule; use deno_runtime::deno_fs; use deno_runtime::deno_node; @@ -804,12 +805,27 @@ fn generate_lint_diagnostics( continue; } let version = document.maybe_lsp_version(); - let (lint_options, lint_rules) = config + let (lint_options, lint_config, lint_rules) = config .tree .scope_for_specifier(specifier) .and_then(|s| config_data_by_scope.get(s)) - .map(|d| (d.lint_options.clone(), d.lint_rules.clone())) - .unwrap_or_default(); + .map(|d| { + ( + d.lint_options.clone(), + d.lint_config.clone(), + d.lint_rules.clone(), + ) + }) + .unwrap_or_else(|| { + ( + Arc::default(), + LintConfig { + default_jsx_factory: None, + default_jsx_fragment_factory: None, + }, + Arc::default(), + ) + }); diagnostics_vec.push(DiagnosticRecord { specifier: specifier.clone(), versioned: VersionedDiagnostics { @@ -817,6 +833,7 @@ fn generate_lint_diagnostics( diagnostics: generate_document_lint_diagnostics( &document, &lint_options, + lint_config, lint_rules.rules.clone(), ), }, @@ -828,6 +845,7 @@ fn generate_lint_diagnostics( fn generate_document_lint_diagnostics( document: &Document, lint_options: &LintOptions, + lint_config: LintConfig, lint_rules: Vec<&'static dyn LintRule>, ) -> Vec<lsp::Diagnostic> { if !lint_options.files.matches_specifier(document.specifier()) { @@ -836,7 +854,7 @@ fn generate_document_lint_diagnostics( match document.maybe_parsed_source() { Some(Ok(parsed_source)) => { if let Ok(references) = - analysis::get_lint_references(&parsed_source, lint_rules) + analysis::get_lint_references(&parsed_source, lint_rules, lint_config) { references .into_iter() diff --git a/cli/tools/lint/mod.rs b/cli/tools/lint/mod.rs index aeb919976..7253c99b2 100644 --- a/cli/tools/lint/mod.rs +++ b/cli/tools/lint/mod.rs @@ -17,6 +17,7 @@ use deno_core::parking_lot::Mutex; use deno_core::serde_json; use deno_graph::FastCheckDiagnostic; use deno_lint::diagnostic::LintDiagnostic; +use deno_lint::linter::LintConfig; use deno_lint::linter::LintFileOptions; use deno_lint::linter::Linter; use deno_lint::linter::LinterBuilder; @@ -79,6 +80,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { let factory = CliFactory::from_flags(flags)?; let cli_options = factory.cli_options(); let lint_options = cli_options.resolve_lint_options(lint_flags)?; + let lint_config = cli_options.resolve_lint_config()?; let files = collect_lint_files(cli_options, lint_options.files.clone()) .and_then(|files| { @@ -105,7 +107,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { files }; - lint_files(factory, lint_options, lint_paths).await?; + lint_files(factory, lint_options, lint_config, lint_paths).await?; Ok(()) }) }, @@ -116,6 +118,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { let cli_options = factory.cli_options(); let is_stdin = lint_flags.is_stdin(); let lint_options = cli_options.resolve_lint_options(lint_flags)?; + let lint_config = cli_options.resolve_lint_config()?; let files = &lint_options.files; let success = if is_stdin { let reporter_kind = lint_options.reporter_kind; @@ -125,7 +128,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { cli_options.maybe_config_file().as_ref(), )?; let file_path = cli_options.initial_cwd().join(STDIN_FILE_NAME); - let r = lint_stdin(&file_path, lint_rules.rules); + let r = lint_stdin(&file_path, lint_rules.rules, lint_config); let success = handle_lint_result( &file_path.to_string_lossy(), r, @@ -143,7 +146,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { } })?; debug!("Found {} files", target_files.len()); - lint_files(factory, lint_options, target_files).await? + lint_files(factory, lint_options, lint_config, target_files).await? }; if !success { std::process::exit(1); @@ -156,6 +159,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { async fn lint_files( factory: CliFactory, lint_options: LintOptions, + lint_config: LintConfig, paths: Vec<PathBuf>, ) -> Result<bool, AnyError> { let caches = factory.caches()?; @@ -221,6 +225,7 @@ async fn lint_files( let linter = create_linter(lint_rules.rules); let reporter_lock = reporter_lock.clone(); let incremental_cache = incremental_cache.clone(); + let lint_config = lint_config.clone(); let fix = lint_options.fix; deno_core::unsync::spawn(async move { run_parallelized(paths, { @@ -232,7 +237,7 @@ async fn lint_files( return Ok(()); } - let r = lint_file(&linter, &file_path, file_text, fix); + let r = lint_file(&linter, &file_path, file_text, lint_config, fix); if let Ok((file_source, file_diagnostics)) = &r { if file_diagnostics.is_empty() { // update the incremental cache if there were no diagnostics @@ -335,19 +340,28 @@ fn lint_file( linter: &Linter, file_path: &Path, source_code: String, + config: LintConfig, fix: bool, ) -> Result<(ParsedSource, Vec<LintDiagnostic>), AnyError> { let specifier = specifier_from_file_path(file_path)?; let media_type = MediaType::from_specifier(&specifier); if fix { - lint_file_and_fix(linter, &specifier, media_type, source_code, file_path) + lint_file_and_fix( + linter, + &specifier, + media_type, + source_code, + file_path, + config, + ) } else { linter .lint_file(LintFileOptions { specifier, media_type, source_code, + config, }) .map_err(AnyError::from) } @@ -359,12 +373,14 @@ fn lint_file_and_fix( media_type: MediaType, source_code: String, file_path: &Path, + config: LintConfig, ) -> Result<(ParsedSource, Vec<LintDiagnostic>), deno_core::anyhow::Error> { // initial lint let (source, diagnostics) = linter.lint_file(LintFileOptions { specifier: specifier.clone(), media_type, source_code, + config: config.clone(), })?; // Try applying fixes repeatedly until the file has none left or @@ -379,6 +395,7 @@ fn lint_file_and_fix( specifier, media_type, linter, + config.clone(), source.text_info(), &diagnostics, )?; @@ -417,6 +434,7 @@ fn apply_lint_fixes_and_relint( specifier: &ModuleSpecifier, media_type: MediaType, linter: &Linter, + config: LintConfig, text_info: &SourceTextInfo, diagnostics: &[LintDiagnostic], ) -> Result<Option<(ParsedSource, Vec<LintDiagnostic>)>, AnyError> { @@ -428,6 +446,7 @@ fn apply_lint_fixes_and_relint( specifier: specifier.clone(), source_code: new_text, media_type, + config, }) .map(Some) .context( @@ -479,6 +498,7 @@ fn apply_lint_fixes( fn lint_stdin( file_path: &Path, lint_rules: Vec<&'static dyn LintRule>, + config: LintConfig, ) -> Result<(ParsedSource, Vec<LintDiagnostic>), AnyError> { let mut source_code = String::new(); if stdin().read_to_string(&mut source_code).is_err() { @@ -492,6 +512,7 @@ fn lint_stdin( specifier: specifier_from_file_path(file_path)?, source_code: source_code.clone(), media_type: MediaType::TypeScript, + config, }) .map_err(AnyError::from) } |