Skip to content

Commit 3d47159

Browse files
committed
refactor(language_server): use IsolatedLintHandlerFileSystem (#10830)
1 parent 47b946d commit 3d47159

File tree

4 files changed

+38
-34
lines changed

4 files changed

+38
-34
lines changed

crates/oxc_language_server/src/linter/isolated_lint_handler.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use tower_lsp_server::{
1111
};
1212

1313
use oxc_allocator::Allocator;
14+
use oxc_linter::RuntimeFileSystem;
1415
use oxc_linter::{
1516
LINTABLE_EXTENSIONS, LintService, LintServiceOptions, Linter, MessageWithPosition,
1617
loader::Loader, read_to_string,
@@ -32,6 +33,31 @@ pub struct IsolatedLintHandler {
3233
options: IsolatedLintHandlerOptions,
3334
}
3435

36+
pub struct IsolatedLintHandlerFileSystem {
37+
path_to_lint: PathBuf,
38+
source_text: String,
39+
}
40+
41+
impl IsolatedLintHandlerFileSystem {
42+
pub fn new(path_to_lint: PathBuf, source_text: String) -> Self {
43+
Self { path_to_lint, source_text }
44+
}
45+
}
46+
47+
impl RuntimeFileSystem for IsolatedLintHandlerFileSystem {
48+
fn read_to_string(&self, path: &Path) -> Result<String, std::io::Error> {
49+
if path == self.path_to_lint {
50+
return Ok(self.source_text.clone());
51+
}
52+
53+
read_to_string(path)
54+
}
55+
56+
fn write_file(&self, _path: &Path, _content: String) -> Result<(), std::io::Error> {
57+
panic!("writing file should not be allowed in Language Server");
58+
}
59+
}
60+
3561
impl IsolatedLintHandler {
3662
pub fn new(linter: Linter, options: IsolatedLintHandlerOptions) -> Self {
3763
Self { linter, options }
@@ -112,9 +138,11 @@ impl IsolatedLintHandler {
112138
)
113139
.with_cross_module(self.options.use_cross_module);
114140
// ToDo: do not clone the linter
115-
let path_arc = Arc::from(path.as_os_str());
116-
let mut lint_service = LintService::new(self.linter.clone(), lint_service_options);
117-
let result = lint_service.run_source(allocator, &path_arc, &source_text);
141+
let mut lint_service =
142+
LintService::new(self.linter.clone(), lint_service_options).with_file_system(Box::new(
143+
IsolatedLintHandlerFileSystem::new(path.to_path_buf(), source_text),
144+
));
145+
let result = lint_service.run_source(allocator);
118146

119147
Some(result)
120148
}

crates/oxc_linter/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub use crate::{
4343
options::LintOptions,
4444
options::{AllowWarnDeny, InvalidFilterKind, LintFilter, LintFilterKind},
4545
rule::{RuleCategory, RuleFixMeta, RuleMeta, RuleWithSeverity},
46-
service::{LintService, LintServiceOptions},
46+
service::{LintService, LintServiceOptions, RuntimeFileSystem},
4747
utils::read_to_string,
4848
};
4949
use crate::{

crates/oxc_linter/src/service/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,8 @@ impl LintService {
9898
pub fn run_source<'a>(
9999
&mut self,
100100
allocator: &'a oxc_allocator::Allocator,
101-
path: &Arc<OsStr>,
102-
source_text: &str,
103101
) -> Vec<crate::MessageWithPosition<'a>> {
104-
self.runtime.run_source(allocator, path, source_text)
102+
self.runtime.run_source(allocator)
105103
}
106104

107105
/// For tests

crates/oxc_linter/src/service/runtime.rs

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ pub struct Runtime {
4646
resolver: Option<Resolver>,
4747

4848
pub(super) file_system: Box<dyn RuntimeFileSystem + Sync + Send>,
49-
50-
// The language server uses more up to date source_text provided by `workspace/didChange` request.
51-
// This is required to support `run: "onType"` configuration
52-
#[cfg(feature = "language_server")]
53-
source_text_cache: FxHashMap<Arc<OsStr>, String>,
5449
}
5550

5651
/// Output of `Runtime::process_path`
@@ -179,8 +174,6 @@ impl Runtime {
179174
linter,
180175
resolver,
181176
file_system: Box::new(OsFileSystem),
182-
#[cfg(feature = "language_server")]
183-
source_text_cache: FxHashMap::default(),
184177
}
185178
}
186179

@@ -230,13 +223,6 @@ impl Runtime {
230223
}
231224
let source_type = source_type.unwrap_or_default();
232225

233-
// The language server uses more up to date source_text provided by `workspace/didChange` request.
234-
// This is required to support `run: "onType"` configuration
235-
#[cfg(feature = "language_server")]
236-
if let Some(source_text) = self.source_text_cache.get(path.as_os_str()) {
237-
return Some(Ok((source_type, source_text.clone())));
238-
}
239-
240226
let file_result = self.file_system.read_to_string(path).map_err(|e| {
241227
Error::new(OxcDiagnostic::error(format!(
242228
"Failed to open file {path:?} with error \"{e}\""
@@ -563,22 +549,14 @@ impl Runtime {
563549
pub(super) fn run_source<'a>(
564550
&mut self,
565551
allocator: &'a oxc_allocator::Allocator,
566-
path: &Arc<OsStr>,
567-
source_text: &str,
568552
) -> Vec<MessageWithPosition<'a>> {
569553
use std::sync::Mutex;
570554

571-
// the language server can have more up to date source_text then the filesystem
572-
#[cfg(feature = "language_server")]
573-
{
574-
self.source_text_cache.insert(Arc::clone(path), source_text.to_owned());
575-
}
576-
577555
let messages = Mutex::new(Vec::<MessageWithPosition<'a>>::new());
578556
let (sender, _receiver) = mpsc::channel();
579557
rayon::scope(|scope| {
580558
self.resolve_modules(scope, true, &sender, |me, mut module| {
581-
module.content.with_dependent_mut(|_owner, dependent| {
559+
module.content.with_dependent_mut(|owner, dependent| {
582560
assert_eq!(module.section_module_records.len(), dependent.len());
583561

584562
for (record_result, section) in
@@ -609,13 +587,13 @@ impl Runtime {
609587
let offset = labeled_span.offset() as u32;
610588
let start_position = offset_to_position(
611589
offset + section.source.start,
612-
source_text,
590+
&owner.source_text,
613591
);
614592
let end_position = offset_to_position(
615593
offset
616594
+ section.source.start
617595
+ labeled_span.len() as u32,
618-
source_text,
596+
&owner.source_text,
619597
);
620598
let message = labeled_span
621599
.label()
@@ -642,11 +620,11 @@ impl Runtime {
642620
span: SpanPositionMessage::new(
643621
offset_to_position(
644622
section.source.start + fix.span.start,
645-
source_text,
623+
&owner.source_text,
646624
),
647625
offset_to_position(
648626
section.source.start + fix.span.end,
649-
source_text,
627+
&owner.source_text,
650628
),
651629
)
652630
.with_message(

0 commit comments

Comments
 (0)