Support cross-crate marks

This commit is contained in:
Aleksey Kladov 2020-03-04 11:38:55 +01:00
parent 437329d3f5
commit 19115e9fab
7 changed files with 37 additions and 4 deletions

1
Cargo.lock generated
View file

@ -1068,6 +1068,7 @@ dependencies = [
"rayon", "rayon",
"rustc-hash", "rustc-hash",
"superslice", "superslice",
"test_utils",
] ]
[[package]] [[package]]

View file

@ -96,7 +96,7 @@ pub(crate) fn reference_definition(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use test_utils::assert_eq_text; use test_utils::{assert_eq_text, covers};
use crate::mock_analysis::analysis_and_position; use crate::mock_analysis::analysis_and_position;
@ -208,6 +208,7 @@ mod tests {
#[test] #[test]
fn goto_def_for_macros() { fn goto_def_for_macros() {
covers!(ra_ide_db::goto_def_for_macros);
check_goto( check_goto(
" "
//- /lib.rs //- /lib.rs
@ -224,6 +225,7 @@ mod tests {
#[test] #[test]
fn goto_def_for_macros_from_other_crates() { fn goto_def_for_macros_from_other_crates() {
covers!(ra_ide_db::goto_def_for_macros);
check_goto( check_goto(
" "
//- /lib.rs //- /lib.rs
@ -335,6 +337,7 @@ mod tests {
#[test] #[test]
fn goto_def_for_methods() { fn goto_def_for_methods() {
covers!(ra_ide_db::goto_def_for_methods);
check_goto( check_goto(
" "
//- /lib.rs //- /lib.rs
@ -354,6 +357,7 @@ mod tests {
#[test] #[test]
fn goto_def_for_fields() { fn goto_def_for_fields() {
covers!(ra_ide_db::goto_def_for_fields);
check_goto( check_goto(
" "
//- /lib.rs //- /lib.rs
@ -372,6 +376,7 @@ mod tests {
#[test] #[test]
fn goto_def_for_record_fields() { fn goto_def_for_record_fields() {
covers!(ra_ide_db::goto_def_for_record_fields);
check_goto( check_goto(
" "
//- /lib.rs //- /lib.rs
@ -784,6 +789,7 @@ mod tests {
#[test] #[test]
fn goto_def_for_field_init_shorthand() { fn goto_def_for_field_init_shorthand() {
covers!(ra_ide_db::goto_def_for_field_init_shorthand);
check_goto( check_goto(
" "
//- /lib.rs //- /lib.rs

View file

@ -21,6 +21,7 @@ ra_syntax = { path = "../ra_syntax" }
ra_text_edit = { path = "../ra_text_edit" } ra_text_edit = { path = "../ra_text_edit" }
ra_db = { path = "../ra_db" } ra_db = { path = "../ra_db" }
ra_prof = { path = "../ra_prof" } ra_prof = { path = "../ra_prof" }
test_utils = { path = "../test_utils" }
# ra_ide should depend only on the top-level `hir` package. if you need # ra_ide should depend only on the top-level `hir` package. if you need
# something from some `hir_xxx` subpackage, reexport the API via `hir`. # something from some `hir_xxx` subpackage, reexport the API via `hir`.

View file

@ -14,6 +14,7 @@ use ra_syntax::{
ast::{self, AstNode, VisibilityOwner}, ast::{self, AstNode, VisibilityOwner},
match_ast, match_ast,
}; };
use test_utils::tested_by;
use crate::RootDatabase; use crate::RootDatabase;
@ -217,18 +218,22 @@ pub fn classify_name_ref(
let parent = name_ref.syntax().parent()?; let parent = name_ref.syntax().parent()?;
if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
tested_by!(goto_def_for_methods; force);
if let Some(func) = sema.resolve_method_call(&method_call) { if let Some(func) = sema.resolve_method_call(&method_call) {
return Some(NameRefClass::Definition(Definition::ModuleDef(func.into()))); return Some(NameRefClass::Definition(Definition::ModuleDef(func.into())));
} }
} }
if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
tested_by!(goto_def_for_fields; force);
if let Some(field) = sema.resolve_field(&field_expr) { if let Some(field) = sema.resolve_field(&field_expr) {
return Some(NameRefClass::Definition(Definition::StructField(field))); return Some(NameRefClass::Definition(Definition::StructField(field)));
} }
} }
if let Some(record_field) = ast::RecordField::cast(parent.clone()) { if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
tested_by!(goto_def_for_record_fields; force);
tested_by!(goto_def_for_field_init_shorthand; force);
if let Some((field, local)) = sema.resolve_record_field(&record_field) { if let Some((field, local)) = sema.resolve_record_field(&record_field) {
let field = Definition::StructField(field); let field = Definition::StructField(field);
let res = match local { let res = match local {
@ -240,6 +245,7 @@ pub fn classify_name_ref(
} }
if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
tested_by!(goto_def_for_macros; force);
if let Some(macro_def) = sema.resolve_macro_call(&macro_call) { if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
return Some(NameRefClass::Definition(Definition::Macro(macro_def))); return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
} }

View file

@ -2,6 +2,7 @@
//! //!
//! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search. //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.
pub mod marks;
pub mod line_index; pub mod line_index;
pub mod line_index_utils; pub mod line_index_utils;
pub mod feature_flags; pub mod feature_flags;

View file

@ -0,0 +1,9 @@
//! See test_utils/src/marks.rs
test_utils::marks![
goto_def_for_macros
goto_def_for_methods
goto_def_for_fields
goto_def_for_record_fields
goto_def_for_field_init_shorthand
];

View file

@ -30,6 +30,12 @@ use std::sync::atomic::{AtomicUsize, Ordering};
#[macro_export] #[macro_export]
macro_rules! tested_by { macro_rules! tested_by {
($ident:ident; force) => {{
{
// sic! use call-site crate
crate::marks::$ident.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
}
}};
($ident:ident) => {{ ($ident:ident) => {{
#[cfg(test)] #[cfg(test)]
{ {
@ -41,9 +47,12 @@ macro_rules! tested_by {
#[macro_export] #[macro_export]
macro_rules! covers { macro_rules! covers {
// sic! use call-site crate
($ident:ident) => { ($ident:ident) => {
// sic! use call-site crate $crate::covers!(crate::$ident)
let _checker = $crate::marks::MarkChecker::new(&crate::marks::$ident); };
($krate:ident :: $ident:ident) => {
let _checker = $crate::marks::MarkChecker::new(&$krate::marks::$ident);
}; };
} }
@ -52,7 +61,7 @@ macro_rules! marks {
($($ident:ident)*) => { ($($ident:ident)*) => {
$( $(
#[allow(bad_style)] #[allow(bad_style)]
pub(crate) static $ident: std::sync::atomic::AtomicUsize = pub static $ident: std::sync::atomic::AtomicUsize =
std::sync::atomic::AtomicUsize::new(0); std::sync::atomic::AtomicUsize::new(0);
)* )*
}; };