mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Move the DiagnosticsWithFix trait on the ide level
This commit is contained in:
parent
9368619939
commit
29fbc8e021
7 changed files with 75 additions and 63 deletions
|
@ -1,8 +1,6 @@
|
|||
//! FIXME: write short doc here
|
||||
pub use hir_def::diagnostics::UnresolvedModule;
|
||||
pub use hir_expand::diagnostics::{
|
||||
Diagnostic, DiagnosticSink, DiagnosticSinkBuilder, DiagnosticWithFix,
|
||||
};
|
||||
pub use hir_expand::diagnostics::{Diagnostic, DiagnosticSink, DiagnosticSinkBuilder};
|
||||
pub use hir_ty::diagnostics::{
|
||||
MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, NoSuchField,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ use hir_def::{
|
|||
resolver::{self, HasResolver, Resolver},
|
||||
AsMacroCall, FunctionId, TraitId, VariantId,
|
||||
};
|
||||
use hir_expand::{diagnostics::DiagnosticWithFix, hygiene::Hygiene, name::AsName, ExpansionInfo};
|
||||
use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo};
|
||||
use hir_ty::associated_type_shorthand_candidates;
|
||||
use itertools::Itertools;
|
||||
use ra_db::{FileId, FileRange};
|
||||
|
@ -109,14 +109,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
|||
self.imp.parse(file_id)
|
||||
}
|
||||
|
||||
pub fn diagnostic_fix_source<T: DiagnosticWithFix + Diagnostic>(
|
||||
&self,
|
||||
d: &T,
|
||||
) -> Option<<T as DiagnosticWithFix>::AST> {
|
||||
let file_id = d.presentation().file_id;
|
||||
let root = self.db.parse_or_expand(file_id)?;
|
||||
self.imp.cache(root, file_id);
|
||||
d.fix_source(self.db.upcast())
|
||||
pub fn cache(&self, root_node: SyntaxNode, file_id: HirFileId) {
|
||||
self.imp.cache(root_node, file_id)
|
||||
}
|
||||
|
||||
pub fn expand(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::any::Any;
|
||||
|
||||
use hir_expand::diagnostics::{Diagnostic, DiagnosticWithFix};
|
||||
use hir_expand::diagnostics::Diagnostic;
|
||||
use ra_syntax::{ast, AstPtr, SyntaxNodePtr};
|
||||
|
||||
use hir_expand::{HirFileId, InFile};
|
||||
|
@ -25,11 +25,3 @@ impl Diagnostic for UnresolvedModule {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for UnresolvedModule {
|
||||
type AST = ast::Module;
|
||||
fn fix_source(&self, db: &dyn hir_expand::db::AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.decl.to_node(&root))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::{any::Any, fmt};
|
|||
|
||||
use ra_syntax::SyntaxNodePtr;
|
||||
|
||||
use crate::{db::AstDatabase, InFile};
|
||||
use crate::InFile;
|
||||
|
||||
pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static {
|
||||
fn message(&self) -> String;
|
||||
|
@ -29,11 +29,6 @@ pub trait Diagnostic: Any + Send + Sync + fmt::Debug + 'static {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait DiagnosticWithFix {
|
||||
type AST;
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST>;
|
||||
}
|
||||
|
||||
pub struct DiagnosticSink<'a> {
|
||||
callbacks: Vec<Box<dyn FnMut(&dyn Diagnostic) -> Result<(), ()> + 'a>>,
|
||||
filters: Vec<Box<dyn FnMut(&dyn Diagnostic) -> bool + 'a>>,
|
||||
|
|
|
@ -6,8 +6,8 @@ mod unsafe_check;
|
|||
use std::any::Any;
|
||||
|
||||
use hir_def::DefWithBodyId;
|
||||
use hir_expand::diagnostics::{Diagnostic, DiagnosticSink, DiagnosticWithFix};
|
||||
use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
|
||||
use hir_expand::diagnostics::{Diagnostic, DiagnosticSink};
|
||||
use hir_expand::{name::Name, HirFileId, InFile};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::{ast, AstPtr, SyntaxNodePtr};
|
||||
use stdx::format_to;
|
||||
|
@ -46,15 +46,6 @@ impl Diagnostic for NoSuchField {
|
|||
}
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for NoSuchField {
|
||||
type AST = ast::RecordExprField;
|
||||
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.field.to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MissingFields {
|
||||
pub file: HirFileId,
|
||||
|
@ -88,15 +79,6 @@ impl Diagnostic for MissingFields {
|
|||
}
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for MissingFields {
|
||||
type AST = ast::RecordExpr;
|
||||
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.field_list_parent.to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MissingPatFields {
|
||||
pub file: HirFileId,
|
||||
|
@ -163,15 +145,6 @@ impl Diagnostic for MissingOkInTailExpr {
|
|||
}
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for MissingOkInTailExpr {
|
||||
type AST = ast::Expr;
|
||||
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.expr.to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BreakOutsideOfLoop {
|
||||
pub file: HirFileId,
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
use std::cell::RefCell;
|
||||
|
||||
use hir::{
|
||||
db::AstDatabase,
|
||||
diagnostics::{Diagnostic as _, DiagnosticSinkBuilder},
|
||||
HasSource, HirDisplay, Semantics, VariantDef,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use ra_db::SourceDatabase;
|
||||
use ra_db::{SourceDatabase, Upcast};
|
||||
use ra_ide_db::RootDatabase;
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::{
|
||||
|
@ -23,6 +24,9 @@ use ra_text_edit::{TextEdit, TextEditBuilder};
|
|||
|
||||
use crate::{Diagnostic, FileId, FileSystemEdit, Fix, SourceFileEdit};
|
||||
|
||||
mod diagnostics_with_fix;
|
||||
use diagnostics_with_fix::DiagnosticWithFix;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Severity {
|
||||
Error,
|
||||
|
@ -62,8 +66,7 @@ pub(crate) fn diagnostics(
|
|||
}
|
||||
.into(),
|
||||
);
|
||||
let fix = sema
|
||||
.diagnostic_fix_source(d)
|
||||
let fix = diagnostic_fix_source(&sema, d)
|
||||
.map(|unresolved_module| unresolved_module.syntax().text_range())
|
||||
.map(|fix_range| (fix, fix_range));
|
||||
|
||||
|
@ -84,7 +87,7 @@ pub(crate) fn diagnostics(
|
|||
let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) {
|
||||
None
|
||||
} else {
|
||||
sema.diagnostic_fix_source(d)
|
||||
diagnostic_fix_source(&sema, d)
|
||||
.and_then(|record_expr| record_expr.record_expr_field_list())
|
||||
.map(|old_field_list| {
|
||||
let mut new_field_list = old_field_list.clone();
|
||||
|
@ -105,6 +108,7 @@ pub(crate) fn diagnostics(
|
|||
(
|
||||
Fix::new("Fill struct fields", SourceFileEdit { file_id, edit }.into()),
|
||||
sema.original_range(&old_field_list.syntax()).range,
|
||||
// old_field_list.syntax().text_range(),
|
||||
)
|
||||
})
|
||||
};
|
||||
|
@ -118,7 +122,7 @@ pub(crate) fn diagnostics(
|
|||
Some(())
|
||||
})
|
||||
.on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| {
|
||||
let fix = sema.diagnostic_fix_source(d).map(|tail_expr| {
|
||||
let fix = diagnostic_fix_source(&sema, d).map(|tail_expr| {
|
||||
let tail_expr_range = tail_expr.syntax().text_range();
|
||||
let edit =
|
||||
TextEdit::replace(tail_expr_range, format!("Ok({})", tail_expr.syntax()));
|
||||
|
@ -140,7 +144,7 @@ pub(crate) fn diagnostics(
|
|||
message: d.message(),
|
||||
severity: Severity::Error,
|
||||
fix: missing_struct_field_fix(&sema, file_id, d).and_then(|fix| {
|
||||
Some((fix, sema.diagnostic_fix_source(d)?.syntax().text_range()))
|
||||
Some((fix, diagnostic_fix_source(&sema, d)?.syntax().text_range()))
|
||||
}),
|
||||
});
|
||||
Some(())
|
||||
|
@ -164,12 +168,22 @@ pub(crate) fn diagnostics(
|
|||
res.into_inner()
|
||||
}
|
||||
|
||||
fn diagnostic_fix_source<T: DiagnosticWithFix + hir::diagnostics::Diagnostic>(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
d: &T,
|
||||
) -> Option<<T as DiagnosticWithFix>::AST> {
|
||||
let file_id = d.presentation().file_id;
|
||||
let root = sema.db.parse_or_expand(file_id)?;
|
||||
sema.cache(root, file_id);
|
||||
d.fix_source(sema.db.upcast())
|
||||
}
|
||||
|
||||
fn missing_struct_field_fix(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
usage_file_id: FileId,
|
||||
d: &hir::diagnostics::NoSuchField,
|
||||
) -> Option<Fix> {
|
||||
let record_expr_field = sema.diagnostic_fix_source(d)?;
|
||||
let record_expr_field = diagnostic_fix_source(&sema, d)?;
|
||||
|
||||
let record_lit = ast::RecordExpr::cast(record_expr_field.syntax().parent()?.parent()?)?;
|
||||
let def_id = sema.resolve_variant(record_lit)?;
|
||||
|
|
46
crates/ra_ide/src/diagnostics/diagnostics_with_fix.rs
Normal file
46
crates/ra_ide/src/diagnostics/diagnostics_with_fix.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use hir::{
|
||||
db::AstDatabase,
|
||||
diagnostics::{MissingFields, MissingOkInTailExpr, NoSuchField, UnresolvedModule},
|
||||
};
|
||||
use ra_syntax::ast;
|
||||
|
||||
// TODO kb
|
||||
pub trait DiagnosticWithFix {
|
||||
type AST;
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST>;
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for UnresolvedModule {
|
||||
type AST = ast::Module;
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.decl.to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for NoSuchField {
|
||||
type AST = ast::RecordExprField;
|
||||
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.field.to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for MissingFields {
|
||||
type AST = ast::RecordExpr;
|
||||
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.field_list_parent.to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl DiagnosticWithFix for MissingOkInTailExpr {
|
||||
type AST = ast::Expr;
|
||||
|
||||
fn fix_source(&self, db: &dyn AstDatabase) -> Option<Self::AST> {
|
||||
let root = db.parse_or_expand(self.file)?;
|
||||
Some(self.expr.to_node(&root))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue