mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 02:29:44 +00:00
Merge pull request #19861 from vremyavnikuda/docs/find-all-refs-constructor-search
Some checks are pending
metrics / generate_final_metrics (push) Blocked by required conditions
metrics / build_metrics (push) Waiting to run
metrics / other_metrics (diesel-1.4.8) (push) Blocked by required conditions
metrics / other_metrics (hyper-0.14.18) (push) Blocked by required conditions
metrics / other_metrics (ripgrep-13.0.0) (push) Blocked by required conditions
metrics / other_metrics (self) (push) Blocked by required conditions
metrics / other_metrics (webrender-2022) (push) Blocked by required conditions
rustdoc / rustdoc (push) Waiting to run
Some checks are pending
metrics / generate_final_metrics (push) Blocked by required conditions
metrics / build_metrics (push) Waiting to run
metrics / other_metrics (diesel-1.4.8) (push) Blocked by required conditions
metrics / other_metrics (hyper-0.14.18) (push) Blocked by required conditions
metrics / other_metrics (ripgrep-13.0.0) (push) Blocked by required conditions
metrics / other_metrics (self) (push) Blocked by required conditions
metrics / other_metrics (webrender-2022) (push) Blocked by required conditions
rustdoc / rustdoc (push) Waiting to run
docs: add documentation for find_all_refs constructor search
This commit is contained in:
commit
e65dddaf59
2 changed files with 88 additions and 3 deletions
|
|
@ -514,7 +514,6 @@ impl Analysis {
|
|||
self.with_db(|db| goto_type_definition::goto_type_definition(db, position))
|
||||
}
|
||||
|
||||
/// Finds all usages of the reference at point.
|
||||
pub fn find_all_refs(
|
||||
&self,
|
||||
position: FilePosition,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,14 @@
|
|||
//! for text occurrences of the identifier. If there's an `ast::NameRef`
|
||||
//! at the index that the match starts at and its tree parent is
|
||||
//! resolved to the search element definition, we get a reference.
|
||||
//!
|
||||
//! Special handling for constructors/initializations:
|
||||
//! When searching for references to a struct/enum/variant, if the cursor is positioned on:
|
||||
//! - `{` after a struct/enum/variant definition
|
||||
//! - `(` for tuple structs/variants
|
||||
//! - `;` for unit structs
|
||||
//! - The type name in a struct/enum/variant definition
|
||||
//! Then only constructor/initialization usages will be shown, filtering out other references.
|
||||
|
||||
use hir::{PathResolution, Semantics};
|
||||
use ide_db::{
|
||||
|
|
@ -28,27 +36,76 @@ use syntax::{
|
|||
|
||||
use crate::{FilePosition, HighlightedRange, NavigationTarget, TryToNav, highlight_related};
|
||||
|
||||
/// Result of a reference search operation.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReferenceSearchResult {
|
||||
/// Information about the declaration site of the searched item.
|
||||
/// For ADTs (structs/enums), this points to the type definition.
|
||||
/// May be None for primitives or items without clear declaration sites.
|
||||
pub declaration: Option<Declaration>,
|
||||
/// All references found, grouped by file.
|
||||
/// For ADTs when searching from a constructor position (e.g. on '{', '(', ';'),
|
||||
/// this only includes constructor/initialization usages.
|
||||
/// The map key is the file ID, and the value is a vector of (range, category) pairs.
|
||||
/// - range: The text range of the reference in the file
|
||||
/// - category: Metadata about how the reference is used (read/write/etc)
|
||||
pub references: IntMap<FileId, Vec<(TextRange, ReferenceCategory)>>,
|
||||
}
|
||||
|
||||
/// Information about the declaration site of a searched item.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Declaration {
|
||||
/// Navigation information to jump to the declaration
|
||||
pub nav: NavigationTarget,
|
||||
/// Whether the declared item is mutable (relevant for variables)
|
||||
pub is_mut: bool,
|
||||
}
|
||||
|
||||
// Feature: Find All References
|
||||
//
|
||||
// Shows all references of the item at the cursor location
|
||||
// Shows all references of the item at the cursor location. This includes:
|
||||
// - Direct references to variables, functions, types, etc.
|
||||
// - Constructor/initialization references when cursor is on struct/enum definition tokens
|
||||
// - References in patterns and type contexts
|
||||
// - References through dereferencing and borrowing
|
||||
// - References in macro expansions
|
||||
//
|
||||
// Special handling for constructors:
|
||||
// - When the cursor is on `{`, `(`, or `;` in a struct/enum definition
|
||||
// - When the cursor is on the type name in a struct/enum definition
|
||||
// These cases will show only constructor/initialization usages of the type
|
||||
//
|
||||
// | Editor | Shortcut |
|
||||
// |---------|----------|
|
||||
// | VS Code | <kbd>Shift+Alt+F12</kbd> |
|
||||
//
|
||||
// 
|
||||
|
||||
/// Find all references to the item at the given position.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `sema` - Semantic analysis context
|
||||
/// * `position` - Position in the file where to look for the item
|
||||
/// * `search_scope` - Optional scope to limit the search (e.g. current crate only)
|
||||
///
|
||||
/// # Returns
|
||||
/// Returns `None` if no valid item is found at the position.
|
||||
/// Otherwise returns a vector of `ReferenceSearchResult`, usually with one element.
|
||||
/// Multiple results can occur in case of ambiguity or when searching for trait items.
|
||||
///
|
||||
/// # Special cases
|
||||
/// - Control flow keywords (break, continue, etc): Shows all related jump points
|
||||
/// - Constructor search: When on struct/enum definition tokens (`{`, `(`, `;`), shows only initialization sites
|
||||
/// - Format string arguments: Shows template parameter usages
|
||||
/// - Lifetime parameters: Shows lifetime constraint usages
|
||||
///
|
||||
/// # Constructor search
|
||||
/// When the cursor is on specific tokens in a struct/enum definition:
|
||||
/// - `{` after struct/enum/variant: Shows record literal initializations
|
||||
/// - `(` after tuple struct/variant: Shows tuple literal initializations
|
||||
/// - `;` after unit struct: Shows unit literal initializations
|
||||
/// - Type name in definition: Shows all initialization usages
|
||||
/// In these cases, other kinds of references (like type references) are filtered out.
|
||||
pub(crate) fn find_all_refs(
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
position: FilePosition,
|
||||
|
|
@ -219,7 +276,19 @@ fn retain_adt_literal_usages(
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `Some` if the cursor is at a position for an item to search for all its constructor/literal usages
|
||||
/// Returns `Some` if the cursor is at a position where we should search for constructor/initialization usages.
|
||||
/// This is used to implement the special constructor search behavior when the cursor is on specific tokens
|
||||
/// in a struct/enum/variant definition.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `Some(name)` if the cursor is on:
|
||||
/// - `{` after a struct/enum/variant definition
|
||||
/// - `(` for tuple structs/variants
|
||||
/// - `;` for unit structs
|
||||
/// - The type name in a struct/enum/variant definition
|
||||
/// - `None` otherwise
|
||||
///
|
||||
/// The returned name is the name of the type whose constructor usages should be searched for.
|
||||
fn name_for_constructor_search(syntax: &SyntaxNode, position: FilePosition) -> Option<ast::Name> {
|
||||
let token = syntax.token_at_offset(position.offset).right_biased()?;
|
||||
let token_parent = token.parent()?;
|
||||
|
|
@ -257,6 +326,16 @@ fn name_for_constructor_search(syntax: &SyntaxNode, position: FilePosition) -> O
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks if a name reference is part of an enum variant literal expression.
|
||||
/// Used to filter references when searching for enum variant constructors.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `sema` - Semantic analysis context
|
||||
/// * `enum_` - The enum type to check against
|
||||
/// * `name_ref` - The name reference to check
|
||||
///
|
||||
/// # Returns
|
||||
/// `true` if the name reference is used as part of constructing a variant of the given enum.
|
||||
fn is_enum_lit_name_ref(
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
enum_: hir::Enum,
|
||||
|
|
@ -284,12 +363,19 @@ fn is_enum_lit_name_ref(
|
|||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Checks if a path ends with the given name reference.
|
||||
/// Helper function for checking constructor usage patterns.
|
||||
fn path_ends_with(path: Option<ast::Path>, name_ref: &ast::NameRef) -> bool {
|
||||
path.and_then(|path| path.segment())
|
||||
.and_then(|segment| segment.name_ref())
|
||||
.map_or(false, |segment| segment == *name_ref)
|
||||
}
|
||||
|
||||
/// Checks if a name reference is used in a literal (constructor) context.
|
||||
/// Used to filter references when searching for struct/variant constructors.
|
||||
///
|
||||
/// # Returns
|
||||
/// `true` if the name reference is used as part of a struct/variant literal expression.
|
||||
fn is_lit_name_ref(name_ref: &ast::NameRef) -> bool {
|
||||
name_ref.syntax().ancestors().find_map(|ancestor| {
|
||||
match_ast! {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue