mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-22 20:53:37 +00:00
Diagnostic paths attempt to use VSCode's path join behavior before defaulting to Rust's path join behavior.
This commit is contained in:
parent
32491c0978
commit
60841f4276
@ -1,6 +1,9 @@
|
||||
//! This module provides the functionality needed to convert diagnostics from
|
||||
//! `cargo check` json format to the LSP diagnostic format.
|
||||
use std::{collections::HashMap, path::Path};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use flycheck::{DiagnosticLevel, DiagnosticSpan};
|
||||
use stdx::format_to;
|
||||
@ -42,7 +45,7 @@ fn is_dummy_macro_file(file_name: &str) -> bool {
|
||||
|
||||
/// Converts a Rust span to a LSP location
|
||||
fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location {
|
||||
let file_name = workspace_root.join(&span.file_name);
|
||||
let file_name = resolve_path(workspace_root, &span.file_name);
|
||||
let uri = url_from_abs_path(&file_name);
|
||||
|
||||
// FIXME: this doesn't handle UTF16 offsets correctly
|
||||
@ -61,7 +64,7 @@ fn location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location
|
||||
fn primary_location(workspace_root: &Path, span: &DiagnosticSpan) -> lsp_types::Location {
|
||||
let span_stack = std::iter::successors(Some(span), |span| Some(&span.expansion.as_ref()?.span));
|
||||
for span in span_stack.clone() {
|
||||
let abs_path = workspace_root.join(&span.file_name);
|
||||
let abs_path = resolve_path(workspace_root, &span.file_name);
|
||||
if !is_dummy_macro_file(&span.file_name) && abs_path.starts_with(workspace_root) {
|
||||
return location(workspace_root, span);
|
||||
}
|
||||
@ -84,6 +87,30 @@ fn diagnostic_related_information(
|
||||
Some(lsp_types::DiagnosticRelatedInformation { location, message })
|
||||
}
|
||||
|
||||
/// Resolves paths mimicking VSCode's behavior when `file_name` starts
|
||||
/// with the root directory component, which does not discard the base
|
||||
/// path. If this relative path exists, use it, otherwise fall back
|
||||
/// to the existing Rust behavior of path joining.
|
||||
fn resolve_path(workspace_root: &Path, file_name: &str) -> PathBuf {
|
||||
let file_name = Path::new(file_name);
|
||||
|
||||
// Test path with VSCode's path join behavior.
|
||||
let vscode_path = {
|
||||
let mut result = PathBuf::from(workspace_root);
|
||||
result.extend(file_name.components().skip_while(|component| match component {
|
||||
std::path::Component::RootDir => true,
|
||||
_ => false,
|
||||
}));
|
||||
result
|
||||
};
|
||||
if vscode_path.exists() {
|
||||
return vscode_path;
|
||||
}
|
||||
|
||||
// Default to Rust's path join behavior.
|
||||
workspace_root.join(file_name)
|
||||
}
|
||||
|
||||
struct SubDiagnostic {
|
||||
related: lsp_types::DiagnosticRelatedInformation,
|
||||
suggested_fix: Option<lsp_ext::CodeAction>,
|
||||
|
Loading…
Reference in New Issue
Block a user