Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 32 additions & 25 deletions crates/oxc_language_server/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,13 @@ impl LanguageServer for Backend {
continue;
}
let content = self.file_system.read().await.get(uri);
if let Some(diagnostics) = worker.run_diagnostic(uri, content.as_deref()).await
{
new_diagnostics.push((uri.clone(), diagnostics));
}
let diagnostics = worker.run_diagnostic(uri, content.as_deref()).await;
new_diagnostics.extend(diagnostics);
}
}

if !new_diagnostics.is_empty() {
self.publish_all_diagnostics(new_diagnostics).await;
self.publish_all_diagnostics(new_diagnostics, ConcurrentHashMap::default()).await;
}
}

Expand Down Expand Up @@ -353,7 +351,7 @@ impl LanguageServer for Backend {
}

if !new_diagnostics.is_empty() {
self.publish_all_diagnostics(new_diagnostics).await;
self.publish_all_diagnostics(new_diagnostics, ConcurrentHashMap::default()).await;
}

if !removing_registrations.is_empty()
Expand Down Expand Up @@ -401,7 +399,7 @@ impl LanguageServer for Backend {
}

if !new_diagnostics.is_empty() {
self.publish_all_diagnostics(new_diagnostics).await;
self.publish_all_diagnostics(new_diagnostics, ConcurrentHashMap::default()).await;
}

if self.capabilities.get().is_some_and(|capabilities| capabilities.dynamic_watchers) {
Expand Down Expand Up @@ -504,9 +502,9 @@ impl LanguageServer for Backend {
return;
};

if let Some(diagnostics) = worker.run_diagnostic_on_save(&uri, params.text.as_deref()).await
{
self.client.publish_diagnostics(uri, diagnostics, None).await;
let diagnostics = worker.run_diagnostic_on_save(&uri, params.text.as_deref()).await;
if !diagnostics.is_empty() {
self.publish_all_diagnostics(diagnostics, ConcurrentHashMap::default()).await;
}
}
/// It will update the in-memory file content if the client supports dynamic formatting.
Expand All @@ -525,10 +523,11 @@ impl LanguageServer for Backend {
self.file_system.write().await.set(uri.clone(), content.clone());
}

if let Some(diagnostics) = worker.run_diagnostic_on_change(&uri, content.as_deref()).await {
self.client
.publish_diagnostics(uri, diagnostics, Some(params.text_document.version))
.await;
let diagnostics = worker.run_diagnostic_on_change(&uri, content.as_deref()).await;
if !diagnostics.is_empty() {
let version_map = ConcurrentHashMap::default();
version_map.pin().insert(uri.clone(), params.text_document.version);
self.publish_all_diagnostics(diagnostics, version_map).await;
}
}

Expand All @@ -547,10 +546,11 @@ impl LanguageServer for Backend {

self.file_system.write().await.set(uri.clone(), content.clone());

if let Some(diagnostics) = worker.run_diagnostic(&uri, Some(&content)).await {
self.client
.publish_diagnostics(uri, diagnostics, Some(params.text_document.version))
.await;
let diagnostics = worker.run_diagnostic(&uri, Some(&content)).await;
if !diagnostics.is_empty() {
let version_map = ConcurrentHashMap::default();
version_map.pin().insert(uri.clone(), params.text_document.version);
self.publish_all_diagnostics(diagnostics, version_map).await;
}
}

Expand Down Expand Up @@ -677,16 +677,23 @@ impl Backend {
}

async fn clear_diagnostics(&self, uris: Vec<Uri>) {
self.publish_all_diagnostics(uris.into_iter().map(|uri| (uri, vec![])).collect()).await;
self.publish_all_diagnostics(
uris.into_iter().map(|uri| (uri, vec![])).collect(),
ConcurrentHashMap::default(),
)
.await;
}

/// Publish diagnostics for all files.
async fn publish_all_diagnostics(&self, result: Vec<(Uri, Vec<Diagnostic>)>) {
join_all(
result
.into_iter()
.map(|(uri, diagnostics)| self.client.publish_diagnostics(uri, diagnostics, None)),
)
async fn publish_all_diagnostics(
&self,
result: Vec<(Uri, Vec<Diagnostic>)>,
version_map: ConcurrentHashMap<Uri, i32>,
) {
join_all(result.into_iter().map(|(uri, diagnostics)| {
let version = version_map.pin().get(&uri).copied();
self.client.publish_diagnostics(uri, diagnostics, version)
}))
.await;
}
}
36 changes: 16 additions & 20 deletions crates/oxc_language_server/src/linter/server_linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use oxc_linter::{
LintIgnoreMatcher, LintOptions, Oxlintrc,
};

use crate::linter::error_with_position::LinterCodeAction;
use crate::{
ConcurrentHashMap,
linter::{
Expand All @@ -29,10 +28,11 @@ use crate::{
},
commands::{FIX_ALL_COMMAND_ID, FixAllCommandArgs},
config_walker::ConfigWalker,
error_with_position::LinterCodeAction,
isolated_lint_handler::{IsolatedLintHandler, IsolatedLintHandlerOptions},
options::{LintOptions as LSPLintOptions, Run, UnusedDisableDirectives},
},
tool::{Tool, ToolBuilder, ToolRestartChanges, ToolShutdownChanges},
tool::{DiagnosticResult, Tool, ToolBuilder, ToolRestartChanges, ToolShutdownChanges},
utils::normalize_path,
};

Expand Down Expand Up @@ -491,34 +491,30 @@ impl Tool for ServerLinter {
}

/// Lint a file with the current linter
/// - If the file is not lintable or ignored, [`None`] is returned
/// - If the file is lintable, but no diagnostics are found, an empty vector is returned
fn run_diagnostic(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<Diagnostic>> {
self.run_file(uri, content)
/// - If the file is not lintable or ignored, an empty vector is returned
fn run_diagnostic(&self, uri: &Uri, content: Option<&str>) -> DiagnosticResult {
let Some(diagnostics) = self.run_file(uri, content) else {
return vec![];
};
vec![(uri.clone(), diagnostics)]
}

/// Lint a file with the current linter
/// - If the file is not lintable or ignored, [`None`] is returned
/// - If the linter is not set to `OnType`, [`None`] is returned
/// - If the file is lintable, but no diagnostics are found, an empty vector is returned
fn run_diagnostic_on_change(
&self,
uri: &Uri,
content: Option<&str>,
) -> Option<Vec<Diagnostic>> {
/// - If the file is not lintable or ignored, an empty vector is returned
/// - If the linter is not set to `OnType`, an empty vector is returned
fn run_diagnostic_on_change(&self, uri: &Uri, content: Option<&str>) -> DiagnosticResult {
if self.run != Run::OnType {
return None;
return vec![];
}
self.run_diagnostic(uri, content)
}

/// Lint a file with the current linter
/// - If the file is not lintable or ignored, [`None`] is returned
/// - If the linter is not set to `OnSave`, [`None`] is returned
/// - If the file is lintable, but no diagnostics are found, an empty vector is returned
fn run_diagnostic_on_save(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<Diagnostic>> {
/// - If the file is not lintable or ignored, an empty vector is returned
/// - If the linter is not set to `OnSave`, an empty vector is returned
fn run_diagnostic_on_save(&self, uri: &Uri, content: Option<&str>) -> DiagnosticResult {
if self.run != Run::OnSave {
return None;
return vec![];
}
self.run_diagnostic(uri, content)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
source: crates/oxc_language_server/src/linter/tester.rs
---
##########
file: fixtures/linter/cross_module/debugger.ts
Linted file: fixtures/linter/cross_module/debugger.ts
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/cross_module/debugger.ts

code: "eslint(no-debugger)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html"
Expand All @@ -16,6 +17,7 @@ related_information[0].location.range: Range { start: Position { line: 1, charac
severity: Some(Warning)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Remove the debugger statement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
source: crates/oxc_language_server/src/linter/tester.rs
---
##########
file: fixtures/linter/cross_module/dep-a.ts
Linted file: fixtures/linter/cross_module/dep-a.ts
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/cross_module/dep-a.ts

code: "eslint-plugin-import(no-cycle)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/import/no-cycle.html"
Expand All @@ -16,6 +17,7 @@ related_information[0].location.range: Range { start: Position { line: 1, charac
severity: Some(Error)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Disable no-cycle for this line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
source: crates/oxc_language_server/src/linter/tester.rs
---
##########
file: fixtures/linter/cross_module_extended_config/dep-a.ts
Linted file: fixtures/linter/cross_module_extended_config/dep-a.ts
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/cross_module_extended_config/dep-a.ts

code: "eslint-plugin-import(no-cycle)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/import/no-cycle.html"
Expand All @@ -16,6 +17,7 @@ related_information[0].location.range: Range { start: Position { line: 1, charac
severity: Some(Error)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Disable no-cycle for this line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
source: crates/oxc_language_server/src/linter/tester.rs
---
##########
file: fixtures/linter/cross_module_nested_config/dep-a.ts
Linted file: fixtures/linter/cross_module_nested_config/dep-a.ts
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/cross_module_nested_config/dep-a.ts

########### Code Actions/Commands

##########
file: fixtures/linter/cross_module_nested_config/folder/folder-dep-a.ts
Linted file: fixtures/linter/cross_module_nested_config/folder/folder-dep-a.ts
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/cross_module_nested_config/folder/folder-dep-a.ts

code: "eslint-plugin-import(no-cycle)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/import/no-cycle.html"
Expand All @@ -23,6 +25,7 @@ related_information[0].location.range: Range { start: Position { line: 1, charac
severity: Some(Error)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Disable no-cycle for this line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
source: crates/oxc_language_server/src/linter/tester.rs
---
##########
file: fixtures/linter/deny_no_console/hello_world.js
Linted file: fixtures/linter/deny_no_console/hello_world.js
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/deny_no_console/hello_world.js

code: "eslint(no-console)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-console.html"
Expand All @@ -16,6 +17,7 @@ related_information[0].location.range: Range { start: Position { line: 0, charac
severity: Some(Error)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Disable no-console for this line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
source: crates/oxc_language_server/src/linter/tester.rs
---
##########
file: fixtures/linter/frameworks/astro/debugger.astro
Linted file: fixtures/linter/frameworks/astro/debugger.astro
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/frameworks/astro/debugger.astro

code: "eslint(no-debugger)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html"
Expand Down Expand Up @@ -49,6 +50,7 @@ related_information[0].location.range: Range { start: Position { line: 18, chara
severity: Some(Warning)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Remove the debugger statement
Expand Down Expand Up @@ -267,9 +269,10 @@ TextEdit: TextEdit {


##########
file: fixtures/linter/frameworks/vue/debugger.vue
Linted file: fixtures/linter/frameworks/vue/debugger.vue
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/frameworks/vue/debugger.vue

code: "eslint(no-debugger)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html"
Expand All @@ -292,6 +295,7 @@ related_information[0].location.range: Range { start: Position { line: 8, charac
severity: Some(Warning)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Remove the debugger statement
Expand Down Expand Up @@ -402,9 +406,10 @@ TextEdit: TextEdit {


##########
file: fixtures/linter/frameworks/svelte/debugger.svelte
Linted file: fixtures/linter/frameworks/svelte/debugger.svelte
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/frameworks/svelte/debugger.svelte

code: "eslint(no-unassigned-vars)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unassigned-vars.html"
Expand Down Expand Up @@ -438,6 +443,7 @@ related_information[0].location.range: Range { start: Position { line: 1, charac
severity: Some(Warning)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Disable no-unassigned-vars for this line
Expand Down Expand Up @@ -566,9 +572,10 @@ TextEdit: TextEdit {


##########
file: fixtures/linter/frameworks/nextjs/[[..rest]]/debugger.ts
Linted file: fixtures/linter/frameworks/nextjs/[[..rest]]/debugger.ts
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/frameworks/nextjs/%5B%5B..rest%5D%5D/debugger.ts

code: "eslint(no-debugger)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html"
Expand All @@ -580,6 +587,7 @@ related_information[0].location.range: Range { start: Position { line: 0, charac
severity: Some(Warning)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Remove the debugger statement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
source: crates/oxc_language_server/src/linter/tester.rs
---
##########
file: fixtures/linter/ignore_patterns/ignored-file.ts
Linted file: fixtures/linter/ignore_patterns/ignored-file.ts
----------
File is ignored
No diagnostics / Files are ignored
##########
file: fixtures/linter/ignore_patterns/another_config/not-ignored-file.ts
Linted file: fixtures/linter/ignore_patterns/another_config/not-ignored-file.ts
----------
########## Diagnostic Reports
File URI: file://<variable>/fixtures/linter/ignore_patterns/another_config/not-ignored-file.ts

code: "eslint(no-debugger)"
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html"
Expand All @@ -20,6 +21,7 @@ related_information[0].location.range: Range { start: Position { line: 0, charac
severity: Some(Error)
source: Some("oxc")
tags: None

########### Code Actions/Commands
CodeAction:
Title: Remove the debugger statement
Expand Down
Loading
Loading