Skip to content

Commit d24b74e

Browse files
committed
refactor(linter/language_server): oxc_linter::TsgoLinter::run_source returns Message (#14429)
1 parent e5b7fb2 commit d24b74e

File tree

2 files changed

+60
-63
lines changed

2 files changed

+60
-63
lines changed

crates/oxc_language_server/src/linter/tsgo_linter.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use std::{
33
sync::{Arc, OnceLock},
44
};
55

6+
use oxc_data_structures::rope::Rope;
67
use oxc_linter::{
78
ConfigStore, LINTABLE_EXTENSIONS, TsGoLintState, loader::LINT_PARTIAL_LOADER_EXTENSIONS,
8-
read_to_string,
9+
message_to_message_with_position, read_to_string,
910
};
1011
use rustc_hash::FxHashSet;
1112
use tower_lsp_server::{UriExt, lsp_types::Uri};
@@ -32,12 +33,20 @@ impl TsgoLinter {
3233
}
3334

3435
let source_text = content.or_else(|| read_to_string(&path).ok())?;
36+
let rope = Rope::from_str(&source_text);
3537

36-
let messages = self.state.lint_source(&Arc::from(path.as_os_str()), source_text).ok()?;
38+
// TODO: Avoid cloning the source text
39+
let messages =
40+
self.state.lint_source(&Arc::from(path.as_os_str()), source_text.clone()).ok()?;
3741

3842
let mut diagnostics: Vec<DiagnosticReport> = messages
39-
.iter()
40-
.map(|e| message_with_position_to_lsp_diagnostic_report(e, uri))
43+
.into_iter()
44+
.map(|e| {
45+
message_with_position_to_lsp_diagnostic_report(
46+
&message_to_message_with_position(e, &source_text, &rope),
47+
uri,
48+
)
49+
})
4150
.collect();
4251

4352
let mut inverted_diagnostics = generate_inverted_diagnostics(&diagnostics, uri);

crates/oxc_linter/src/tsgolint.rs

Lines changed: 47 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ use oxc_span::{SourceType, Span};
1515
use super::{AllowWarnDeny, ConfigStore, DisableDirectives, ResolvedLinterState, read_to_string};
1616

1717
#[cfg(feature = "language_server")]
18-
use crate::{
19-
fixer::{CompositeFix, Message, PossibleFixes},
20-
lsp::{MessageWithPosition, message_to_message_with_position},
21-
};
18+
use crate::fixer::{CompositeFix, Message, PossibleFixes};
2219

2320
/// State required to initialize the `tsgolint` linter.
2421
#[derive(Debug, Clone)]
@@ -294,9 +291,7 @@ impl TsGoLintState {
294291
&self,
295292
path: &Arc<OsStr>,
296293
source_text: String,
297-
) -> Result<Vec<MessageWithPosition<'_>>, String> {
298-
use oxc_data_structures::rope::Rope;
299-
294+
) -> Result<Vec<Message<'_>>, String> {
300295
let mut resolved_configs: FxHashMap<PathBuf, ResolvedLinterState> = FxHashMap::default();
301296

302297
let json_input = self.json_input(std::slice::from_ref(path), &mut resolved_configs);
@@ -336,65 +331,58 @@ impl TsGoLintState {
336331
// Stream diagnostics as they are emitted, rather than waiting for all output
337332
let stdout = child.stdout.take().expect("Failed to open tsgolint stdout");
338333

339-
let stdout_handler =
340-
std::thread::spawn(move || -> Result<Vec<MessageWithPosition<'_>>, String> {
341-
let msg_iter = TsGoLintMessageStream::new(stdout);
334+
let stdout_handler = std::thread::spawn(move || -> Result<Vec<Message<'_>>, String> {
335+
let msg_iter = TsGoLintMessageStream::new(stdout);
342336

343-
let mut result = vec![];
337+
let mut result = vec![];
344338

345-
for msg in msg_iter {
346-
match msg {
347-
Ok(TsGoLintMessage::Error(err)) => {
348-
return Err(err.error);
349-
}
350-
Ok(TsGoLintMessage::Diagnostic(tsgolint_diagnostic)) => {
351-
let path = tsgolint_diagnostic.file_path.clone();
352-
let Some(resolved_config) = resolved_configs.get(&path) else {
353-
// If we don't have a resolved config for this path, skip it. We should always
354-
// have a resolved config though, since we processed them already above.
355-
continue;
356-
};
357-
358-
let severity =
359-
resolved_config.rules.iter().find_map(|(rule, status)| {
360-
if rule.name() == tsgolint_diagnostic.rule {
361-
Some(*status)
362-
} else {
363-
None
364-
}
365-
});
366-
let Some(severity) = severity else {
367-
// If the severity is not found, we should not report the diagnostic
368-
continue;
369-
};
370-
371-
let mut message_with_position: MessageWithPosition<'_> =
372-
message_to_message_with_position(
373-
Message::from_tsgo_lint_diagnostic(
374-
tsgolint_diagnostic,
375-
&source_text,
376-
),
377-
&source_text,
378-
&Rope::from_str(&source_text),
379-
);
339+
for msg in msg_iter {
340+
match msg {
341+
Ok(TsGoLintMessage::Error(err)) => {
342+
return Err(err.error);
343+
}
344+
Ok(TsGoLintMessage::Diagnostic(tsgolint_diagnostic)) => {
345+
let path = tsgolint_diagnostic.file_path.clone();
346+
let Some(resolved_config) = resolved_configs.get(&path) else {
347+
// If we don't have a resolved config for this path, skip it. We should always
348+
// have a resolved config though, since we processed them already above.
349+
continue;
350+
};
380351

381-
message_with_position.severity = if severity == AllowWarnDeny::Deny
382-
{
383-
Severity::Error
384-
} else {
385-
Severity::Warning
386-
};
352+
let severity =
353+
resolved_config.rules.iter().find_map(|(rule, status)| {
354+
if rule.name() == tsgolint_diagnostic.rule {
355+
Some(*status)
356+
} else {
357+
None
358+
}
359+
});
360+
let Some(severity) = severity else {
361+
// If the severity is not found, we should not report the diagnostic
362+
continue;
363+
};
387364

388-
result.push(message_with_position);
389-
}
390-
Err(e) => {
391-
return Err(e);
392-
}
365+
let mut message = Message::from_tsgo_lint_diagnostic(
366+
tsgolint_diagnostic,
367+
&source_text,
368+
);
369+
370+
message.error.severity = if severity == AllowWarnDeny::Deny {
371+
Severity::Error
372+
} else {
373+
Severity::Warning
374+
};
375+
376+
result.push(message);
377+
}
378+
Err(e) => {
379+
return Err(e);
393380
}
394381
}
382+
}
395383

396-
Ok(result)
397-
});
384+
Ok(result)
385+
});
398386

399387
// Wait for process to complete and stdout processing to finish
400388
let exit_status = child.wait().expect("Failed to wait for tsgolint process");

0 commit comments

Comments
 (0)