diff options
Diffstat (limited to 'cli/lsp')
-rw-r--r-- | cli/lsp/analysis.rs | 66 | ||||
-rw-r--r-- | cli/lsp/config.rs | 45 | ||||
-rw-r--r-- | cli/lsp/diagnostics.rs | 63 | ||||
-rw-r--r-- | cli/lsp/resolver.rs | 8 |
4 files changed, 99 insertions, 83 deletions
diff --git a/cli/lsp/analysis.rs b/cli/lsp/analysis.rs index a6a69cbf0..97730ac7e 100644 --- a/cli/lsp/analysis.rs +++ b/cli/lsp/analysis.rs @@ -8,8 +8,8 @@ use super::resolver::LspResolver; use super::tsc; use crate::args::jsr_url; -use crate::tools::lint::create_linter; -use deno_lint::linter::LintConfig; +use crate::tools::lint::CliLinter; +use deno_lint::diagnostic::LintDiagnosticRange; use deno_runtime::fs_util::specifier_to_file_path; use deno_ast::SourceRange; @@ -23,8 +23,6 @@ use deno_core::serde::Serialize; use deno_core::serde_json; use deno_core::serde_json::json; use deno_core::ModuleSpecifier; -use deno_lint::diagnostic::LintDiagnostic; -use deno_lint::rules::LintRule; use deno_runtime::deno_node::NpmResolver; use deno_runtime::deno_node::PathClean; use deno_semver::jsr::JsrPackageNvReference; @@ -149,8 +147,10 @@ impl Reference { } } -fn as_lsp_range_from_diagnostic(diagnostic: &LintDiagnostic) -> Range { - as_lsp_range(diagnostic.range, &diagnostic.text_info) +fn as_lsp_range_from_lint_diagnostic( + diagnostic_range: &LintDiagnosticRange, +) -> Range { + as_lsp_range(diagnostic_range.range, &diagnostic_range.text_info) } fn as_lsp_range( @@ -173,37 +173,39 @@ fn as_lsp_range( pub fn get_lint_references( parsed_source: &deno_ast::ParsedSource, - lint_rules: Vec<&'static dyn LintRule>, - lint_config: LintConfig, + linter: &CliLinter, ) -> Result<Vec<Reference>, AnyError> { - let linter = create_linter(lint_rules); - let lint_diagnostics = linter.lint_with_ast(parsed_source, lint_config); + let lint_diagnostics = linter.lint_with_ast(parsed_source); Ok( lint_diagnostics .into_iter() - .map(|d| Reference { - range: as_lsp_range_from_diagnostic(&d), - category: Category::Lint { - message: d.message, - code: d.code, - hint: d.hint, - quick_fixes: d - .fixes - .into_iter() - .map(|f| DataQuickFix { - description: f.description.to_string(), - changes: f - .changes - .into_iter() - .map(|change| DataQuickFixChange { - range: as_lsp_range(change.range, &d.text_info), - new_text: change.new_text.to_string(), - }) - .collect(), - }) - .collect(), - }, + .filter_map(|d| { + let range = d.range.as_ref()?; + Some(Reference { + range: as_lsp_range_from_lint_diagnostic(range), + category: Category::Lint { + message: d.details.message, + code: d.details.code.to_string(), + hint: d.details.hint, + quick_fixes: d + .details + .fixes + .into_iter() + .map(|f| DataQuickFix { + description: f.description.to_string(), + changes: f + .changes + .into_iter() + .map(|change| DataQuickFixChange { + range: as_lsp_range(change.range, &range.text_info), + new_text: change.new_text.to_string(), + }) + .collect(), + }) + .collect(), + }, + }) }) .collect(), ) diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index ec5430e8a..8a44c26dd 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -52,12 +52,16 @@ use crate::args::discover_npmrc_from_workspace; use crate::args::has_flag_env_var; use crate::args::CliLockfile; use crate::args::ConfigFile; +use crate::args::LintFlags; +use crate::args::LintOptions; use crate::args::DENO_FUTURE; use crate::cache::FastInsecureHasher; use crate::file_fetcher::FileFetcher; use crate::lsp::logging::lsp_warn; -use crate::tools::lint::get_configured_rules; -use crate::tools::lint::ConfiguredRules; +use crate::resolver::SloppyImportsResolver; +use crate::tools::lint::CliLinter; +use crate::tools::lint::CliLinterOptions; +use crate::tools::lint::LintRuleProvider; use crate::util::fs::canonicalize_path_maybe_not_exists; pub const SETTINGS_SECTION: &str = "deno"; @@ -1116,8 +1120,7 @@ pub struct ConfigData { pub lint_config: Arc<LintConfig>, pub test_config: Arc<TestConfig>, pub exclude_files: Arc<PathOrPatternSet>, - pub deno_lint_config: DenoLintConfig, - pub lint_rules: Arc<ConfiguredRules>, + pub linter: Arc<CliLinter>, pub ts_config: Arc<LspTsConfig>, pub byonm: bool, pub node_modules_dir: Option<PathBuf>, @@ -1125,6 +1128,7 @@ pub struct ConfigData { pub lockfile: Option<Arc<CliLockfile>>, pub npmrc: Option<Arc<ResolvedNpmRc>>, pub resolver: Arc<WorkspaceResolver>, + pub sloppy_imports_resolver: Option<Arc<SloppyImportsResolver>>, pub import_map_from_settings: Option<ModuleSpecifier>, watched_files: HashMap<ModuleSpecifier, ConfigWatchedFileType>, } @@ -1310,10 +1314,7 @@ impl ConfigData { LintConfig::new_with_base(default_file_pattern_base.clone()) }), ); - let lint_rules = Arc::new(get_configured_rules( - lint_config.options.rules.clone(), - member_dir.maybe_deno_json().map(|c| c.as_ref()), - )); + let test_config = Arc::new( member_dir .to_test_config(FilePatterns::new_with_base(member_dir.dir_path())) @@ -1532,16 +1533,38 @@ impl ConfigData { .join("\n") ); } + let unstable_sloppy_imports = std::env::var("DENO_UNSTABLE_SLOPPY_IMPORTS") + .is_ok() + || member_dir.workspace.has_unstable("sloppy-imports"); + let sloppy_imports_resolver = unstable_sloppy_imports.then(|| { + Arc::new(SloppyImportsResolver::new_without_stat_cache(Arc::new( + deno_runtime::deno_fs::RealFs, + ))) + }); + let resolver = Arc::new(resolver); + let lint_rule_provider = LintRuleProvider::new( + sloppy_imports_resolver.clone(), + Some(resolver.clone()), + ); + let linter = Arc::new(CliLinter::new(CliLinterOptions { + configured_rules: lint_rule_provider.resolve_lint_rules( + LintOptions::resolve((*lint_config).clone(), &LintFlags::default()) + .rules, + member_dir.maybe_deno_json().map(|c| c.as_ref()), + ), + fix: false, + deno_lint_config, + })); ConfigData { scope, member_dir, - resolver: Arc::new(resolver), + resolver, + sloppy_imports_resolver, fmt_config, lint_config, test_config, - deno_lint_config, - lint_rules, + linter, exclude_files, ts_config: Arc::new(ts_config), byonm, diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs index 899dc9681..ed92c400f 100644 --- a/cli/lsp/diagnostics.rs +++ b/cli/lsp/diagnostics.rs @@ -20,6 +20,9 @@ use crate::graph_util::enhanced_resolution_error_message; use crate::lsp::lsp_custom::DiagnosticBatchNotificationParams; use crate::resolver::SloppyImportsResolution; use crate::resolver::SloppyImportsResolver; +use crate::tools::lint::CliLinter; +use crate::tools::lint::CliLinterOptions; +use crate::tools::lint::LintRuleProvider; use crate::util::path::to_percent_decoded_str; use deno_ast::MediaType; @@ -40,8 +43,6 @@ use deno_graph::source::ResolveError; use deno_graph::Resolution; use deno_graph::ResolutionError; use deno_graph::SpecifierError; -use deno_lint::linter::LintConfig as DenoLintConfig; -use deno_lint::rules::LintRule; use deno_runtime::deno_fs; use deno_runtime::deno_node; use deno_runtime::tokio_util::create_basic_runtime; @@ -817,25 +818,25 @@ fn generate_lint_diagnostics( continue; } let version = document.maybe_lsp_version(); - let (lint_config, deno_lint_config, lint_rules) = config + let (lint_config, linter) = config .tree .scope_for_specifier(specifier) .and_then(|s| config_data_by_scope.get(s)) - .map(|d| { - ( - d.lint_config.clone(), - d.deno_lint_config.clone(), - d.lint_rules.clone(), - ) - }) + .map(|d| (d.lint_config.clone(), d.linter.clone())) .unwrap_or_else(|| { ( Arc::new(LintConfig::new_with_base(PathBuf::from("/"))), - DenoLintConfig { - default_jsx_factory: None, - default_jsx_fragment_factory: None, - }, - Arc::default(), + Arc::new(CliLinter::new(CliLinterOptions { + configured_rules: { + let lint_rule_provider = LintRuleProvider::new(None, None); + lint_rule_provider.resolve_lint_rules(Default::default(), None) + }, + fix: false, + deno_lint_config: deno_lint::linter::LintConfig { + default_jsx_factory: None, + default_jsx_fragment_factory: None, + }, + })), ) }); diagnostics_vec.push(DiagnosticRecord { @@ -845,8 +846,7 @@ fn generate_lint_diagnostics( diagnostics: generate_document_lint_diagnostics( &document, &lint_config, - deno_lint_config, - lint_rules.rules.clone(), + &linter, ), }, }); @@ -857,19 +857,16 @@ fn generate_lint_diagnostics( fn generate_document_lint_diagnostics( document: &Document, lint_config: &LintConfig, - deno_lint_config: DenoLintConfig, - lint_rules: Vec<&'static dyn LintRule>, + linter: &CliLinter, ) -> Vec<lsp::Diagnostic> { if !lint_config.files.matches_specifier(document.specifier()) { return Vec::new(); } match document.maybe_parsed_source() { Some(Ok(parsed_source)) => { - if let Ok(references) = analysis::get_lint_references( - parsed_source, - lint_rules, - deno_lint_config, - ) { + if let Ok(references) = + analysis::get_lint_references(parsed_source, linter) + { references .into_iter() .map(|r| r.to_diagnostic()) @@ -1237,16 +1234,14 @@ impl DenoDiagnostic { pub fn to_lsp_diagnostic(&self, range: &lsp::Range) -> lsp::Diagnostic { fn no_local_message( specifier: &ModuleSpecifier, - sloppy_resolution: SloppyImportsResolution, + maybe_sloppy_resolution: Option<&SloppyImportsResolution>, ) -> String { let mut message = format!( "Unable to load a local module: {}\n", to_percent_decoded_str(specifier.as_ref()) ); - if let Some(additional_message) = - sloppy_resolution.as_suggestion_message() - { - message.push_str(&additional_message); + if let Some(res) = maybe_sloppy_resolution { + message.push_str(&res.as_suggestion_message()); message.push('.'); } else { message.push_str("Please check the file path."); @@ -1263,15 +1258,15 @@ impl DenoDiagnostic { Self::NoCacheJsr(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Uncached or missing jsr package: {}", pkg_req), Some(json!({ "specifier": specifier }))), Self::NoCacheNpm(pkg_req, specifier) => (lsp::DiagnosticSeverity::ERROR, format!("Uncached or missing npm package: {}", pkg_req), Some(json!({ "specifier": specifier }))), Self::NoLocal(specifier) => { - let sloppy_resolution = SloppyImportsResolver::new(Arc::new(deno_fs::RealFs)).resolve(specifier, ResolutionMode::Execution); - let data = sloppy_resolution.as_lsp_quick_fix_message().map(|message| { + let maybe_sloppy_resolution = SloppyImportsResolver::new(Arc::new(deno_fs::RealFs)).resolve(specifier, ResolutionMode::Execution); + let data = maybe_sloppy_resolution.as_ref().map(|res| { json!({ "specifier": specifier, - "to": sloppy_resolution.as_specifier(), - "message": message, + "to": res.as_specifier(), + "message": res.as_quick_fix_message(), }) }); - (lsp::DiagnosticSeverity::ERROR, no_local_message(specifier, sloppy_resolution), data) + (lsp::DiagnosticSeverity::ERROR, no_local_message(specifier, maybe_sloppy_resolution.as_ref()), data) }, Self::Redirect { from, to} => (lsp::DiagnosticSeverity::INFORMATION, format!("The import of \"{from}\" was redirected to \"{to}\"."), Some(json!({ "specifier": from, "redirect": to }))), Self::ResolutionError(err) => { diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 7758bbd7c..bdfd5fd3e 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -21,7 +21,6 @@ use crate::resolver::CjsResolutionStore; use crate::resolver::CliGraphResolver; use crate::resolver::CliGraphResolverOptions; use crate::resolver::CliNodeResolver; -use crate::resolver::SloppyImportsResolver; use crate::resolver::WorkerCliNpmGraphResolver; use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBarStyle; @@ -514,8 +513,6 @@ fn create_graph_resolver( node_resolver: Option<&Arc<CliNodeResolver>>, ) -> Arc<CliGraphResolver> { let workspace = config_data.map(|d| &d.member_dir.workspace); - let unstable_sloppy_imports = - workspace.is_some_and(|dir| dir.has_unstable("sloppy-imports")); Arc::new(CliGraphResolver::new(CliGraphResolverOptions { node_resolver: node_resolver.cloned(), npm_resolver: npm_resolver.cloned(), @@ -536,9 +533,8 @@ fn create_graph_resolver( maybe_vendor_dir: config_data.and_then(|d| d.vendor_dir.as_ref()), bare_node_builtins_enabled: workspace .is_some_and(|workspace| workspace.has_unstable("bare-node-builtins")), - sloppy_imports_resolver: unstable_sloppy_imports.then(|| { - SloppyImportsResolver::new_without_stat_cache(Arc::new(deno_fs::RealFs)) - }), + sloppy_imports_resolver: config_data + .and_then(|d| d.sloppy_imports_resolver.clone()), })) } |