From fa9ed4e0ce633e51d1411951bf044719e6837457 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 13 Jun 2021 17:06:36 +0300 Subject: internal: refactor unresolved macro call diagnostic --- crates/ide/src/diagnostics.rs | 29 +-------- .../ide/src/diagnostics/unresolved_macro_call.rs | 72 ++++++++++++++++++++++ 2 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 crates/ide/src/diagnostics/unresolved_macro_call.rs (limited to 'crates/ide') diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 3d05dd093..1a4800832 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs @@ -7,6 +7,7 @@ mod unresolved_module; mod unresolved_extern_crate; mod unresolved_import; +mod unresolved_macro_call; mod missing_fields; mod fixes; @@ -16,9 +17,8 @@ mod unlinked_file; use std::cell::RefCell; use hir::{ - db::AstDatabase, diagnostics::{AnyDiagnostic, Diagnostic as _, DiagnosticCode, DiagnosticSinkBuilder}, - InFile, Semantics, + Semantics, }; use ide_assists::AssistResolveStrategy; use ide_db::{base_db::SourceDatabase, RootDatabase}; @@ -203,20 +203,6 @@ pub(crate) fn diagnostics( res.borrow_mut() .push(Diagnostic::hint(display_range, d.message()).with_code(Some(d.code()))); }) - .on::(|d| { - let last_path_segment = sema.db.parse_or_expand(d.file).and_then(|root| { - d.node - .to_node(&root) - .path() - .and_then(|it| it.segment()) - .and_then(|it| it.name_ref()) - .map(|it| InFile::new(d.file, SyntaxNodePtr::new(it.syntax()))) - }); - let diagnostics = last_path_segment.unwrap_or_else(|| d.display_source()); - let display_range = sema.diagnostics_display_range(diagnostics).range; - res.borrow_mut() - .push(Diagnostic::error(display_range, d.message()).with_code(Some(d.code()))); - }) .on::(|d| { let display_range = sema.diagnostics_display_range(d.display_source()).range; res.borrow_mut() @@ -259,6 +245,7 @@ pub(crate) fn diagnostics( AnyDiagnostic::UnresolvedModule(d) => unresolved_module::unresolved_module(&ctx, &d), AnyDiagnostic::UnresolvedExternCrate(d) => unresolved_extern_crate::unresolved_extern_crate(&ctx, &d), AnyDiagnostic::UnresolvedImport(d) => unresolved_import::unresolved_import(&ctx, &d), + AnyDiagnostic::UnresolvedMacroCall(d) => unresolved_macro_call::unresolved_macro_call(&ctx, &d), AnyDiagnostic::MissingFields(d) => missing_fields::missing_fields(&ctx, &d), }; if let Some(code) = d.code { @@ -480,16 +467,6 @@ mod tests { assert_eq!(expected, actual); } - #[test] - fn test_unresolved_macro_range() { - check_diagnostics( - r#" -foo::bar!(92); - //^^^ unresolved macro `foo::bar!` -"#, - ); - } - #[test] fn range_mapping_out_of_macros() { // FIXME: this is very wrong, but somewhat tricky to fix. diff --git a/crates/ide/src/diagnostics/unresolved_macro_call.rs b/crates/ide/src/diagnostics/unresolved_macro_call.rs new file mode 100644 index 000000000..a3af332a4 --- /dev/null +++ b/crates/ide/src/diagnostics/unresolved_macro_call.rs @@ -0,0 +1,72 @@ +use hir::{db::AstDatabase, InFile}; +use syntax::{AstNode, SyntaxNodePtr}; + +use crate::diagnostics::{Diagnostic, DiagnosticsContext}; + +// Diagnostic: unresolved-macro-call +// +// This diagnostic is triggered if rust-analyzer is unable to resolve the path +// to a macro in a macro invocation. +pub(super) fn unresolved_macro_call( + ctx: &DiagnosticsContext<'_>, + d: &hir::UnresolvedMacroCall, +) -> Diagnostic { + let last_path_segment = ctx.sema.db.parse_or_expand(d.macro_call.file_id).and_then(|root| { + d.macro_call + .value + .to_node(&root) + .path() + .and_then(|it| it.segment()) + .and_then(|it| it.name_ref()) + .map(|it| InFile::new(d.macro_call.file_id, SyntaxNodePtr::new(it.syntax()))) + }); + let diagnostics = last_path_segment.unwrap_or_else(|| d.macro_call.clone().map(|it| it.into())); + + Diagnostic::new( + "unresolved-macro-call", + format!("unresolved macro `{}!`", d.path), + ctx.sema.diagnostics_display_range(diagnostics).range, + ) + .experimental() +} + +#[cfg(test)] +mod tests { + use crate::diagnostics::tests::check_diagnostics; + + #[test] + fn test_unresolved_macro_range() { + check_diagnostics( + r#" +foo::bar!(92); + //^^^ unresolved macro `foo::bar!` +"#, + ); + } + + #[test] + fn unresolved_legacy_scope_macro() { + check_diagnostics( + r#" +macro_rules! m { () => {} } + +m!(); m2!(); + //^^ unresolved macro `self::m2!` +"#, + ); + } + + #[test] + fn unresolved_module_scope_macro() { + check_diagnostics( + r#" +mod mac { +#[macro_export] +macro_rules! m { () => {} } } + +self::m!(); self::m2!(); + //^^ unresolved macro `self::m2!` +"#, + ); + } +} -- cgit v1.2.3