mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Custom ranges for missing fields
This commit is contained in:
parent
26e102a567
commit
21e5224484
@ -36,8 +36,9 @@ pub trait AstDiagnostic {
|
|||||||
|
|
||||||
impl dyn Diagnostic {
|
impl dyn Diagnostic {
|
||||||
pub fn syntax_node(&self, db: &impl AstDatabase) -> SyntaxNode {
|
pub fn syntax_node(&self, db: &impl AstDatabase) -> SyntaxNode {
|
||||||
let node = db.parse_or_expand(self.source().file_id).unwrap();
|
let source = self.source();
|
||||||
self.source().value.to_node(&node)
|
let node = db.parse_or_expand(source.file_id).unwrap();
|
||||||
|
source.value.to_node(&node)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn downcast_ref<D: Diagnostic>(&self) -> Option<&D> {
|
pub fn downcast_ref<D: Diagnostic>(&self) -> Option<&D> {
|
||||||
|
@ -9,7 +9,7 @@ use hir_def::DefWithBodyId;
|
|||||||
use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
|
use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
|
||||||
use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
|
use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
|
use ra_syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
|
|
||||||
use crate::db::HirDatabase;
|
use crate::db::HirDatabase;
|
||||||
@ -61,6 +61,17 @@ pub struct MissingFields {
|
|||||||
pub file: HirFileId,
|
pub file: HirFileId,
|
||||||
pub field_list: AstPtr<ast::RecordExprFieldList>,
|
pub field_list: AstPtr<ast::RecordExprFieldList>,
|
||||||
pub missed_fields: Vec<Name>,
|
pub missed_fields: Vec<Name>,
|
||||||
|
pub list_parent_path: Option<AstPtr<ast::Path>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MissingFields {
|
||||||
|
fn root(&self, db: &dyn AstDatabase) -> SyntaxNode {
|
||||||
|
db.parse_or_expand(self.file).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_parent_ast(&self, db: &dyn AstDatabase) -> Option<ast::Path> {
|
||||||
|
self.list_parent_path.as_ref().map(|path| path.to_node(&self.root(db)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Diagnostic for MissingFields {
|
impl Diagnostic for MissingFields {
|
||||||
@ -83,9 +94,7 @@ impl AstDiagnostic for MissingFields {
|
|||||||
type AST = ast::RecordExprFieldList;
|
type AST = ast::RecordExprFieldList;
|
||||||
|
|
||||||
fn ast(&self, db: &dyn AstDatabase) -> Self::AST {
|
fn ast(&self, db: &dyn AstDatabase) -> Self::AST {
|
||||||
let root = db.parse_or_expand(self.source().file_id).unwrap();
|
self.field_list.to_node(&self.root(db))
|
||||||
let node = self.source().value.to_node(&root);
|
|
||||||
ast::RecordExprFieldList::cast(node).unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,6 +327,41 @@ mod tests {
|
|||||||
assert_eq!(annotations, actual);
|
assert_eq!(annotations, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn structure_name_highlighted_for_missing_fields() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
struct Beefy {
|
||||||
|
one: i32,
|
||||||
|
two: i32,
|
||||||
|
three: i32,
|
||||||
|
four: i32,
|
||||||
|
five: i32,
|
||||||
|
six: i32,
|
||||||
|
seven: i32,
|
||||||
|
eight: i32,
|
||||||
|
nine: i32,
|
||||||
|
ten: i32,
|
||||||
|
}
|
||||||
|
fn baz() {
|
||||||
|
let zz = Beefy {
|
||||||
|
//^^^^^... Missing structure fields:
|
||||||
|
// | - seven
|
||||||
|
one: (),
|
||||||
|
two: (),
|
||||||
|
three: (),
|
||||||
|
four: (),
|
||||||
|
five: (),
|
||||||
|
six: (),
|
||||||
|
eight: (),
|
||||||
|
nine: (),
|
||||||
|
ten: (),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn no_such_field_diagnostics() {
|
fn no_such_field_diagnostics() {
|
||||||
check_diagnostics(
|
check_diagnostics(
|
||||||
|
@ -111,6 +111,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
|||||||
file: source_ptr.file_id,
|
file: source_ptr.file_id,
|
||||||
field_list: AstPtr::new(&field_list),
|
field_list: AstPtr::new(&field_list),
|
||||||
missed_fields,
|
missed_fields,
|
||||||
|
list_parent_path: record_lit.path().map(|path| AstPtr::new(&path)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,8 +100,10 @@ pub(crate) fn diagnostics(
|
|||||||
};
|
};
|
||||||
|
|
||||||
res.borrow_mut().push(Diagnostic {
|
res.borrow_mut().push(Diagnostic {
|
||||||
// TODO kb use a smaller range here
|
range: d
|
||||||
range,
|
.list_parent_ast(db)
|
||||||
|
.map(|path| path.syntax().text_range())
|
||||||
|
.unwrap_or(range),
|
||||||
message: d.message(),
|
message: d.message(),
|
||||||
severity: Severity::Error,
|
severity: Severity::Error,
|
||||||
fix,
|
fix,
|
||||||
|
Loading…
Reference in New Issue
Block a user