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
36 changes: 26 additions & 10 deletions crates/oxc_language_server/src/linter/server_linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;

use globset::Glob;
use ignore::gitignore::Gitignore;
use log::warn;
use log::{debug, warn};
use rustc_hash::{FxBuildHasher, FxHashMap};
use tower_lsp_server::lsp_types::Uri;

Expand All @@ -18,9 +18,9 @@ use crate::{ConcurrentHashMap, Options};

use super::config_walker::ConfigWalker;

#[derive(Clone)]
pub struct ServerLinter {
isolated_linter: Arc<IsolatedLintHandler>,
gitignore_glob: Vec<Gitignore>,
}

impl ServerLinter {
Expand Down Expand Up @@ -67,7 +67,7 @@ impl ServerLinter {
nested_configs
}

pub fn create_ignore_glob(root_uri: &Uri, oxlintrc: &Oxlintrc) -> Vec<Gitignore> {
fn create_ignore_glob(root_uri: &Uri, oxlintrc: &Oxlintrc) -> Vec<Gitignore> {
let mut builder = globset::GlobSetBuilder::new();
// Collecting all ignore files
builder.add(Glob::new("**/.eslintignore").unwrap());
Expand Down Expand Up @@ -119,7 +119,7 @@ impl ServerLinter {
root_uri: &Uri,
options: &Options,
nested_configs: &ConcurrentHashMap<PathBuf, ConfigStore>,
) -> (Self, Oxlintrc) {
) -> Self {
let root_path = root_uri.to_file_path().unwrap();
let relative_config_path = options.config_path.clone();
let oxlintrc = if relative_config_path.is_some() {
Expand Down Expand Up @@ -171,21 +171,37 @@ impl ServerLinter {
Linter::new(lint_options, config_store)
};

let server_linter = ServerLinter::new_with_linter(
let isolated_linter = IsolatedLintHandler::new(
linter,
IsolatedLintHandlerOptions { use_cross_module, root_path: root_path.to_path_buf() },
);

(server_linter, oxlintrc)
Self {
isolated_linter: Arc::new(isolated_linter),
gitignore_glob: Self::create_ignore_glob(root_uri, &oxlintrc),
}
}

fn new_with_linter(linter: Linter, options: IsolatedLintHandlerOptions) -> Self {
let isolated_linter = Arc::new(IsolatedLintHandler::new(linter, options));

Self { isolated_linter }
fn is_ignored(&self, uri: &Uri) -> bool {
for gitignore in &self.gitignore_glob {
if let Some(uri_path) = uri.to_file_path() {
if !uri_path.starts_with(gitignore.path()) {
continue;
}
if gitignore.matched_path_or_any_parents(&uri_path, uri_path.is_dir()).is_ignore() {
debug!("ignored: {uri:?}");
return true;
}
}
}
false
}

pub fn run_single(&self, uri: &Uri, content: Option<String>) -> Option<Vec<DiagnosticReport>> {
if self.is_ignored(uri) {
return None;
}

self.isolated_linter.run_single(uri, content)
}
}
Expand Down
34 changes: 5 additions & 29 deletions crates/oxc_language_server/src/worker.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{path::PathBuf, str::FromStr, vec};

use ignore::gitignore::Gitignore;
use log::{debug, info};
use oxc_linter::{ConfigStore, ConfigStoreBuilder, Oxlintrc};
use rustc_hash::FxBuildHasher;
Expand All @@ -24,7 +23,6 @@ pub struct WorkspaceWorker {
server_linter: RwLock<ServerLinter>,
diagnostics_report_map: RwLock<ConcurrentHashMap<String, Vec<DiagnosticReport>>>,
options: Mutex<Options>,
gitignore_glob: Mutex<Vec<Gitignore>>,
nested_configs: RwLock<ConcurrentHashMap<PathBuf, ConfigStore>>,
}

Expand All @@ -34,14 +32,12 @@ impl WorkspaceWorker {
root_uri_cell.set(root_uri.clone()).unwrap();

let nested_configs = ServerLinter::create_nested_configs(root_uri, &options);
let (server_linter, oxlintrc) =
ServerLinter::create_server_linter(root_uri, &options, &nested_configs);
let server_linter = ServerLinter::create_server_linter(root_uri, &options, &nested_configs);
Self {
root_uri: root_uri_cell,
server_linter: RwLock::new(server_linter),
diagnostics_report_map: RwLock::new(ConcurrentHashMap::default()),
options: Mutex::new(options),
gitignore_glob: Mutex::new(ServerLinter::create_ignore_glob(root_uri, &oxlintrc)),
nested_configs: RwLock::const_new(nested_configs),
}
}
Expand Down Expand Up @@ -71,10 +67,10 @@ impl WorkspaceWorker {
*self.nested_configs.write().await = nested_configs;
}

async fn refresh_linter_config(&self) {
async fn refresh_server_linter(&self) {
let options = self.options.lock().await;
let nested_configs = self.nested_configs.read().await;
let (server_linter, _) = ServerLinter::create_server_linter(
let server_linter = ServerLinter::create_server_linter(
self.root_uri.get().unwrap(),
&options,
&nested_configs,
Expand Down Expand Up @@ -114,10 +110,6 @@ impl WorkspaceWorker {
uri: &Uri,
content: Option<String>,
) -> Option<Vec<DiagnosticReport>> {
if self.is_ignored(uri).await {
return None;
}

self.server_linter.read().await.run_single(uri, content)
}

Expand Down Expand Up @@ -274,7 +266,7 @@ impl WorkspaceWorker {
}
}

self.refresh_linter_config().await;
self.refresh_server_linter().await;
Some(self.revalidate_diagnostics().await)
}

Expand All @@ -301,28 +293,12 @@ impl WorkspaceWorker {
}

if Self::needs_linter_restart(current_option, &changed_options) {
self.refresh_linter_config().await;
self.refresh_server_linter().await;
return Some(self.revalidate_diagnostics().await);
}

None
}

async fn is_ignored(&self, uri: &Uri) -> bool {
let gitignore_globs = &(*self.gitignore_glob.lock().await);
for gitignore in gitignore_globs {
if let Some(uri_path) = uri.to_file_path() {
if !uri_path.starts_with(gitignore.path()) {
continue;
}
if gitignore.matched_path_or_any_parents(&uri_path, uri_path.is_dir()).is_ignore() {
debug!("ignored: {uri:?}");
return true;
}
}
}
false
}
}

fn range_overlaps(a: Range, b: Range) -> bool {
Expand Down
Loading