[ty] Refactor auto-import symbol info

This just encapsulates the representation so that
we can make changes to it more easily.
This commit is contained in:
Andrew Gallant 2025-12-04 13:58:15 -05:00 committed by Andrew Gallant
parent fdcb5a7e73
commit 3c2cf49f60
2 changed files with 41 additions and 10 deletions

View File

@ -2,7 +2,10 @@ use ruff_db::files::File;
use ty_project::Db; use ty_project::Db;
use ty_python_semantic::{Module, ModuleName, all_modules, resolve_real_shadowable_module}; use ty_python_semantic::{Module, ModuleName, all_modules, resolve_real_shadowable_module};
use crate::symbols::{QueryPattern, SymbolInfo, symbols_for_file_global_only}; use crate::{
SymbolKind,
symbols::{QueryPattern, SymbolInfo, symbols_for_file_global_only},
};
/// Get all symbols matching the query string. /// Get all symbols matching the query string.
/// ///
@ -85,14 +88,43 @@ pub fn all_symbols<'db>(
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct AllSymbolInfo<'db> { pub struct AllSymbolInfo<'db> {
/// The symbol information. /// The symbol information.
pub symbol: SymbolInfo<'static>, symbol: SymbolInfo<'static>,
/// The module containing the symbol. /// The module containing the symbol.
pub module: Module<'db>, module: Module<'db>,
/// The file containing the symbol. /// The file containing the symbol.
/// ///
/// This `File` is guaranteed to be the same /// This `File` is guaranteed to be the same
/// as the `File` underlying `module`. /// as the `File` underlying `module`.
pub file: File, file: File,
}
impl<'db> AllSymbolInfo<'db> {
/// Returns the name of this symbol.
pub fn name(&self) -> &str {
&self.symbol.name
}
/// Returns the "kind" of this symbol.
///
/// The kind of a symbol in the context of auto-import is
/// determined on a best effort basis. It may be imprecise
/// in some cases, e.g., reporting a module as a variable.
pub fn kind(&self) -> SymbolKind {
self.symbol.kind
}
/// Returns the module this symbol is exported from.
pub fn module(&self) -> Module<'db> {
self.module
}
/// Returns the `File` corresponding to the module.
///
/// This is always equivalent to
/// `AllSymbolInfo::module().file().unwrap()`.
pub fn file(&self) -> File {
self.file
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -537,12 +537,11 @@ fn add_unimported_completions<'db>(
let members = importer.members_in_scope_at(scoped.node, scoped.node.start()); let members = importer.members_in_scope_at(scoped.node, scoped.node.start());
for symbol in all_symbols(db, file, &completions.query) { for symbol in all_symbols(db, file, &completions.query) {
if symbol.module.file(db) == Some(file) || symbol.module.is_known(db, KnownModule::Builtins) if symbol.file() == file || symbol.module().is_known(db, KnownModule::Builtins) {
{
continue; continue;
} }
let request = create_import_request(symbol.module.name(db), &symbol.symbol.name); let request = create_import_request(symbol.module().name(db), symbol.name());
// FIXME: `all_symbols` doesn't account for wildcard imports. // FIXME: `all_symbols` doesn't account for wildcard imports.
// Since we're looking at every module, this is probably // Since we're looking at every module, this is probably
// "fine," but it might mean that we import a symbol from the // "fine," but it might mean that we import a symbol from the
@ -551,11 +550,11 @@ fn add_unimported_completions<'db>(
// N.B. We use `add` here because `all_symbols` already // N.B. We use `add` here because `all_symbols` already
// takes our query into account. // takes our query into account.
completions.force_add(Completion { completions.force_add(Completion {
name: ast::name::Name::new(&symbol.symbol.name), name: ast::name::Name::new(symbol.name()),
insert: Some(import_action.symbol_text().into()), insert: Some(import_action.symbol_text().into()),
ty: None, ty: None,
kind: symbol.symbol.kind.to_completion_kind(), kind: symbol.kind().to_completion_kind(),
module_name: Some(symbol.module.name(db)), module_name: Some(symbol.module().name(db)),
import: import_action.import().cloned(), import: import_action.import().cloned(),
builtin: false, builtin: false,
// TODO: `is_type_check_only` requires inferring the type of the symbol // TODO: `is_type_check_only` requires inferring the type of the symbol