summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--cli/Cargo.toml2
-rw-r--r--cli/args/mod.rs21
-rw-r--r--cli/lsp/analysis.rs4
-rw-r--r--cli/lsp/config.rs28
-rw-r--r--cli/lsp/diagnostics.rs26
-rw-r--r--cli/tools/lint/mod.rs31
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)
}