From 29fbc8e02180aac1f4d7819a9626206aa64028a0 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 11 Aug 2020 00:37:23 +0300 Subject: Move the DiagnosticsWithFix trait on the ide level --- crates/ra_hir/src/diagnostics.rs | 4 +- crates/ra_hir/src/semantics.rs | 12 ++---- crates/ra_hir_def/src/diagnostics.rs | 10 +---- crates/ra_hir_expand/src/diagnostics.rs | 7 +--- crates/ra_hir_ty/src/diagnostics.rs | 31 +-------------- crates/ra_ide/src/diagnostics.rs | 28 +++++++++---- .../ra_ide/src/diagnostics/diagnostics_with_fix.rs | 46 ++++++++++++++++++++++ 7 files changed, 75 insertions(+), 63 deletions(-) create mode 100644 crates/ra_ide/src/diagnostics/diagnostics_with_fix.rs (limited to 'crates') diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index 564f6a5db..363164b9b 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs @@ -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, }; diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index c5bc2baff..e9f7a033c 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs @@ -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( - &self, - d: &T, - ) -> Option<::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 { diff --git a/crates/ra_hir_def/src/diagnostics.rs b/crates/ra_hir_def/src/diagnostics.rs index 033be683c..9435c7254 100644 --- a/crates/ra_hir_def/src/diagnostics.rs +++ b/crates/ra_hir_def/src/diagnostics.rs @@ -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 { - let root = db.parse_or_expand(self.file)?; - Some(self.decl.to_node(&root)) - } -} diff --git a/crates/ra_hir_expand/src/diagnostics.rs b/crates/ra_hir_expand/src/diagnostics.rs index 62a09a73a..8358c488b 100644 --- a/crates/ra_hir_expand/src/diagnostics.rs +++ b/crates/ra_hir_expand/src/diagnostics.rs @@ -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; -} - pub struct DiagnosticSink<'a> { callbacks: Vec Result<(), ()> + 'a>>, filters: Vec bool + 'a>>, diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index b34ba5bfc..24435e8a7 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs @@ -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 { - 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 { - 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 { - let root = db.parse_or_expand(self.file)?; - Some(self.expr.to_node(&root)) - } -} - #[derive(Debug)] pub struct BreakOutsideOfLoop { pub file: HirFileId, diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index 043ce357b..ca1a7c1aa 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs @@ -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::(|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( + sema: &Semantics, + d: &T, +) -> Option<::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, usage_file_id: FileId, d: &hir::diagnostics::NoSuchField, ) -> Option { - 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)?; diff --git a/crates/ra_ide/src/diagnostics/diagnostics_with_fix.rs b/crates/ra_ide/src/diagnostics/diagnostics_with_fix.rs new file mode 100644 index 000000000..8578a90ec --- /dev/null +++ b/crates/ra_ide/src/diagnostics/diagnostics_with_fix.rs @@ -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; +} + +impl DiagnosticWithFix for UnresolvedModule { + type AST = ast::Module; + fn fix_source(&self, db: &dyn AstDatabase) -> Option { + 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 { + 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 { + 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 { + let root = db.parse_or_expand(self.file)?; + Some(self.expr.to_node(&root)) + } +} -- cgit v1.2.3