mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Support cross-crate marks
This commit is contained in:
parent
437329d3f5
commit
19115e9fab
7 changed files with 37 additions and 4 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1068,6 +1068,7 @@ dependencies = [
|
||||||
"rayon",
|
"rayon",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"superslice",
|
"superslice",
|
||||||
|
"test_utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
|
@ -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(¯o_call) {
|
if let Some(macro_def) = sema.resolve_macro_call(¯o_call) {
|
||||||
return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
|
return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
9
crates/ra_ide_db/src/marks.rs
Normal file
9
crates/ra_ide_db/src/marks.rs
Normal 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
|
||||||
|
];
|
|
@ -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);
|
||||||
)*
|
)*
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue