mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(vscode): report problem more accurately (#1681)
Closed https://github.com/oxc-project/oxc/issues/1674
This commit is contained in:
parent
8f296dfb7a
commit
ef08892027
1 changed files with 70 additions and 15 deletions
|
|
@ -19,7 +19,9 @@ use oxc_parser::Parser;
|
||||||
use oxc_semantic::SemanticBuilder;
|
use oxc_semantic::SemanticBuilder;
|
||||||
use oxc_span::{SourceType, VALID_EXTENSIONS};
|
use oxc_span::{SourceType, VALID_EXTENSIONS};
|
||||||
use ropey::Rope;
|
use ropey::Rope;
|
||||||
use tower_lsp::lsp_types::{self, Position, Range, Url};
|
use tower_lsp::lsp_types::{
|
||||||
|
self, DiagnosticRelatedInformation, DiagnosticSeverity, Position, Range, Url,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ErrorWithPosition {
|
struct ErrorWithPosition {
|
||||||
|
|
@ -40,7 +42,6 @@ struct LabeledSpanWithPosition {
|
||||||
impl ErrorWithPosition {
|
impl ErrorWithPosition {
|
||||||
pub fn new(error: Error, text: &str, fixed_content: Option<FixedContent>) -> Self {
|
pub fn new(error: Error, text: &str, fixed_content: Option<FixedContent>) -> Self {
|
||||||
let labels = error.labels().map_or(vec![], Iterator::collect);
|
let labels = error.labels().map_or(vec![], Iterator::collect);
|
||||||
|
|
||||||
let labels_with_pos: Vec<LabeledSpanWithPosition> = labels
|
let labels_with_pos: Vec<LabeledSpanWithPosition> = labels
|
||||||
.iter()
|
.iter()
|
||||||
.map(|labeled_span| LabeledSpanWithPosition {
|
.map(|labeled_span| LabeledSpanWithPosition {
|
||||||
|
|
@ -60,10 +61,8 @@ impl ErrorWithPosition {
|
||||||
fn to_lsp_diagnostic(&self, path: &PathBuf) -> lsp_types::Diagnostic {
|
fn to_lsp_diagnostic(&self, path: &PathBuf) -> lsp_types::Diagnostic {
|
||||||
let severity = match self.miette_err.severity() {
|
let severity = match self.miette_err.severity() {
|
||||||
Some(Severity::Error) => Some(lsp_types::DiagnosticSeverity::ERROR),
|
Some(Severity::Error) => Some(lsp_types::DiagnosticSeverity::ERROR),
|
||||||
Some(Severity::Warning) => Some(lsp_types::DiagnosticSeverity::WARNING),
|
_ => Some(lsp_types::DiagnosticSeverity::WARNING),
|
||||||
_ => Some(lsp_types::DiagnosticSeverity::INFORMATION),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let related_information = Some(
|
let related_information = Some(
|
||||||
self.labels_with_pos
|
self.labels_with_pos
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -85,6 +84,21 @@ impl ErrorWithPosition {
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
|
let range = related_information.as_ref().map_or(
|
||||||
|
Range { start: self.start_pos, end: self.end_pos },
|
||||||
|
|infos: &Vec<DiagnosticRelatedInformation>| {
|
||||||
|
let mut ret_range = Range {
|
||||||
|
start: Position { line: u32::MAX, character: u32::MAX },
|
||||||
|
end: Position { line: u32::MAX, character: u32::MAX },
|
||||||
|
};
|
||||||
|
for info in infos {
|
||||||
|
if cmp_range(&ret_range, &info.location.range) == std::cmp::Ordering::Greater {
|
||||||
|
ret_range = info.location.range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret_range
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let message = self.miette_err.help().map_or_else(
|
let message = self.miette_err.help().map_or_else(
|
||||||
|| self.miette_err.to_string(),
|
|| self.miette_err.to_string(),
|
||||||
|
|
@ -92,7 +106,7 @@ impl ErrorWithPosition {
|
||||||
);
|
);
|
||||||
|
|
||||||
lsp_types::Diagnostic {
|
lsp_types::Diagnostic {
|
||||||
range: Range { start: self.start_pos, end: self.end_pos },
|
range,
|
||||||
severity,
|
severity,
|
||||||
code: None,
|
code: None,
|
||||||
message,
|
message,
|
||||||
|
|
@ -117,7 +131,6 @@ pub struct DiagnosticReport {
|
||||||
pub diagnostic: lsp_types::Diagnostic,
|
pub diagnostic: lsp_types::Diagnostic,
|
||||||
pub fixed_content: Option<FixedContent>,
|
pub fixed_content: Option<FixedContent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ErrorReport {
|
struct ErrorReport {
|
||||||
pub error: Error,
|
pub error: Error,
|
||||||
|
|
@ -161,14 +174,49 @@ impl IsolatedLintHandler {
|
||||||
content: Option<String>,
|
content: Option<String>,
|
||||||
) -> Option<Vec<DiagnosticReport>> {
|
) -> Option<Vec<DiagnosticReport>> {
|
||||||
if Self::is_wanted_ext(path) {
|
if Self::is_wanted_ext(path) {
|
||||||
Some(
|
Some(Self::lint_path(&self.linter, path, Arc::clone(&self.plugin), content).map_or(
|
||||||
Self::lint_path(&self.linter, path, Arc::clone(&self.plugin), content).map_or(
|
vec![],
|
||||||
vec![],
|
|(p, errors)| {
|
||||||
|(p, errors)| {
|
let mut diagnostics: Vec<DiagnosticReport> =
|
||||||
errors.into_iter().map(|e| e.into_diagnostic_report(&p)).collect()
|
errors.into_iter().map(|e| e.into_diagnostic_report(&p)).collect();
|
||||||
},
|
// a diagnostics connected from related_info to original diagnostic
|
||||||
),
|
let mut inverted_diagnostics = vec![];
|
||||||
)
|
for d in &diagnostics {
|
||||||
|
let Some(ref related_info) = d.diagnostic.related_information else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let related_information = Some(vec![DiagnosticRelatedInformation {
|
||||||
|
location: lsp_types::Location {
|
||||||
|
uri: lsp_types::Url::from_file_path(path).unwrap(),
|
||||||
|
range: d.diagnostic.range,
|
||||||
|
},
|
||||||
|
message: "original diagnostic".to_string(),
|
||||||
|
}]);
|
||||||
|
for r in related_info {
|
||||||
|
if r.location.range == d.diagnostic.range {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
inverted_diagnostics.push(DiagnosticReport {
|
||||||
|
diagnostic: lsp_types::Diagnostic {
|
||||||
|
range: r.location.range,
|
||||||
|
severity: Some(DiagnosticSeverity::HINT),
|
||||||
|
code: None,
|
||||||
|
message: r.message.clone(),
|
||||||
|
source: Some("oxc".into()),
|
||||||
|
code_description: None,
|
||||||
|
related_information: related_information.clone(),
|
||||||
|
tags: None,
|
||||||
|
data: None,
|
||||||
|
},
|
||||||
|
fixed_content: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diagnostics.append(&mut inverted_diagnostics);
|
||||||
|
diagnostics
|
||||||
|
},
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -411,3 +459,10 @@ impl ServerLinter {
|
||||||
.run_single(&uri.to_file_path().unwrap(), content)
|
.run_single(&uri.to_file_path().unwrap(), content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmp_range(first: &Range, other: &Range) -> std::cmp::Ordering {
|
||||||
|
match first.start.cmp(&other.start) {
|
||||||
|
std::cmp::Ordering::Equal => first.end.cmp(&other.end),
|
||||||
|
o => o,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue