Skip to content

Commit 9c5b63f

Browse files
committed
refactor(oxlint/lsp): accept multiple files inside LintRunner
1 parent 73da317 commit 9c5b63f

File tree

3 files changed

+48
-31
lines changed

3 files changed

+48
-31
lines changed

crates/oxc_language_server/src/linter/isolated_lint_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl IsolatedLintHandler {
125125

126126
let mut messages: Vec<DiagnosticReport> = self
127127
.runner
128-
.run_source(&Arc::from(path.as_os_str()), &fs)
128+
.run_source(&[Arc::from(path.as_os_str())], &fs)
129129
.into_iter()
130130
.map(|message| message_to_lsp_diagnostic(message, uri, source_text, rope))
131131
.collect();

crates/oxc_linter/src/lint_runner.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,25 +235,25 @@ impl LintRunner {
235235
/// Returns an error if type-aware linting fails.
236236
pub fn run_source(
237237
&self,
238-
file: &Arc<OsStr>,
238+
files: &[Arc<OsStr>],
239239
file_system: &(dyn crate::RuntimeFileSystem + Sync + Send),
240240
) -> Vec<Message> {
241-
let mut messages = self.lint_service.run_source(file_system, vec![Arc::clone(file)]);
241+
let mut messages = self.lint_service.run_source(file_system, files.to_owned());
242242

243243
if let Some(type_aware_linter) = &self.type_aware_linter {
244-
let tsgo_messages =
245-
match type_aware_linter.lint_source(file, file_system, self.directives_store.map())
246-
{
247-
Ok(msgs) => msgs,
248-
Err(err) => {
249-
vec![Message::new(
250-
OxcDiagnostic::warn(format!(
251-
"Failed to run type-aware linting: `{err}`",
252-
)),
253-
PossibleFixes::None,
254-
)]
255-
}
256-
};
244+
let tsgo_messages = match type_aware_linter.lint_source(
245+
files,
246+
file_system,
247+
self.directives_store.map(),
248+
) {
249+
Ok(msgs) => msgs,
250+
Err(err) => {
251+
vec![Message::new(
252+
OxcDiagnostic::warn(format!("Failed to run type-aware linting: `{err}`",)),
253+
PossibleFixes::None,
254+
)]
255+
}
256+
};
257257
messages.extend(tsgo_messages);
258258
}
259259

crates/oxc_linter/src/tsgolint.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -320,29 +320,37 @@ impl TsGoLintState {
320320
/// A human-readable error message indicating why the linting failed.
321321
pub fn lint_source(
322322
&self,
323-
path: &Arc<OsStr>,
323+
paths: &[Arc<OsStr>],
324324
file_system: &(dyn crate::RuntimeFileSystem + Sync + Send),
325325
disable_directives_map: Arc<Mutex<FxHashMap<PathBuf, DisableDirectives>>>,
326326
) -> Result<Vec<Message>, String> {
327+
if paths.is_empty() {
328+
return Ok(vec![]);
329+
}
330+
327331
let mut resolved_configs: FxHashMap<PathBuf, ResolvedLinterState> = FxHashMap::default();
328-
let mut source_overrides = FxHashMap::default();
332+
let mut source_overrides: FxHashMap<String, String> = FxHashMap::default();
329333
let allocator = Allocator::default();
330-
let Ok(source_text) = file_system.read_to_arena_str(Path::new(path.as_ref()), &allocator)
331-
else {
332-
return Err(format!("Failed to read source text for file: {}", path.to_string_lossy()));
333-
};
334334

335-
// Clone source_text to own it for the spawned thread
336-
let source_text_owned = source_text.to_string();
337-
source_overrides.insert(path.to_string_lossy().to_string(), source_text_owned.clone());
335+
// Read all sources into overrides
336+
for path in paths {
337+
let path_ref = Path::new(path.as_ref());
338+
let Ok(source_text) = file_system.read_to_arena_str(path_ref, &allocator) else {
339+
return Err(format!(
340+
"Failed to read source text for file: {}",
341+
path.to_string_lossy()
342+
));
343+
};
344+
source_overrides.insert(path.to_string_lossy().to_string(), source_text.to_string());
345+
}
338346

339-
let json_input = self.json_input(
340-
std::slice::from_ref(path),
341-
Some(source_overrides),
342-
&mut resolved_configs,
343-
);
347+
let json_input =
348+
self.json_input(paths, Some(source_overrides.clone()), &mut resolved_configs);
349+
350+
// Get the file name of the first path for internal diagnostic filtering
344351
let path_file_name =
345-
Path::new(path.as_ref()).file_name().unwrap_or_default().to_os_string();
352+
Path::new(paths[0].as_ref()).file_name().unwrap_or_default().to_os_string();
353+
346354
let mut child = self.spawn_tsgolint(&json_input)?;
347355
let handler = std::thread::spawn(move || {
348356
let stdout = child.stdout.take().expect("Failed to open tsgolint stdout");
@@ -390,6 +398,15 @@ impl TsGoLintState {
390398
continue;
391399
}
392400

401+
// Use the corresponding source override text
402+
let Some(source_text_owned) = source_overrides
403+
.get(&path.to_string_lossy().to_string())
404+
.cloned()
405+
else {
406+
// should never happen, because we populated source_overrides above
407+
continue;
408+
};
409+
393410
let mut message = Message::from_tsgo_lint_diagnostic(
394411
tsgolint_diagnostic,
395412
&source_text_owned,

0 commit comments

Comments
 (0)