mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 21:34:57 +00:00
[ty] Add naive implementation of completions for unimported symbols
This re-works the `all_symbols` based added previously to work across all modules available, and not just what is directly in the workspace. Note that we always pass an empty string as a query, which makes the results always empty. We'll fix this in a subsequent commit.
This commit is contained in:
parent
78db56e362
commit
8e52027a88
9 changed files with 121 additions and 34 deletions
|
@ -11,8 +11,8 @@ use crate::suppression::{INVALID_IGNORE_COMMENT, UNKNOWN_RULE, UNUSED_IGNORE_COM
|
|||
pub use db::Db;
|
||||
pub use module_name::ModuleName;
|
||||
pub use module_resolver::{
|
||||
Module, SearchPath, SearchPathValidationError, SearchPaths, list_modules, resolve_module,
|
||||
resolve_real_module, system_module_search_paths,
|
||||
Module, SearchPath, SearchPathValidationError, SearchPaths, all_modules, list_modules,
|
||||
resolve_module, resolve_real_module, system_module_search_paths,
|
||||
};
|
||||
pub use program::{
|
||||
Program, ProgramSettings, PythonVersionFileSource, PythonVersionSource,
|
||||
|
|
|
@ -12,6 +12,20 @@ use super::resolver::{
|
|||
ModuleResolveMode, ResolverContext, is_non_shadowable, resolve_file_module, search_paths,
|
||||
};
|
||||
|
||||
/// List all available modules, including all sub-modules, sorted in lexicographic order.
|
||||
pub fn all_modules(db: &dyn Db) -> Vec<Module<'_>> {
|
||||
let mut modules = list_modules(db);
|
||||
let mut stack = modules.clone();
|
||||
while let Some(module) = stack.pop() {
|
||||
for &submodule in module.all_submodules(db) {
|
||||
modules.push(submodule);
|
||||
stack.push(submodule);
|
||||
}
|
||||
}
|
||||
modules.sort_by_key(|module| module.name(db));
|
||||
modules
|
||||
}
|
||||
|
||||
/// List all available top-level modules.
|
||||
#[salsa::tracked]
|
||||
pub fn list_modules(db: &dyn Db) -> Vec<Module<'_>> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::iter::FusedIterator;
|
||||
|
||||
pub use list::list_modules;
|
||||
pub use list::{all_modules, list_modules};
|
||||
pub(crate) use module::KnownModule;
|
||||
pub use module::Module;
|
||||
pub use path::{SearchPath, SearchPathValidationError};
|
||||
|
|
|
@ -50,7 +50,8 @@ impl<'db> SemanticModel<'db> {
|
|||
let ty = Type::module_literal(self.db, self.file, module);
|
||||
Completion {
|
||||
name: Name::new(module.name(self.db).as_str()),
|
||||
ty,
|
||||
ty: Some(ty),
|
||||
kind: None,
|
||||
builtin,
|
||||
}
|
||||
})
|
||||
|
@ -162,7 +163,12 @@ impl<'db> SemanticModel<'db> {
|
|||
|
||||
let mut completions = vec![];
|
||||
for crate::types::Member { name, ty } in crate::types::all_members(self.db, ty) {
|
||||
completions.push(Completion { name, ty, builtin });
|
||||
completions.push(Completion {
|
||||
name,
|
||||
ty: Some(ty),
|
||||
kind: None,
|
||||
builtin,
|
||||
});
|
||||
}
|
||||
completions.extend(self.submodule_completions(&module));
|
||||
completions
|
||||
|
@ -177,7 +183,8 @@ impl<'db> SemanticModel<'db> {
|
|||
let ty = Type::module_literal(self.db, self.file, *submodule);
|
||||
completions.push(Completion {
|
||||
name: Name::new(submodule.name(self.db).as_str()),
|
||||
ty,
|
||||
ty: Some(ty),
|
||||
kind: None,
|
||||
builtin,
|
||||
});
|
||||
}
|
||||
|
@ -191,7 +198,8 @@ impl<'db> SemanticModel<'db> {
|
|||
.into_iter()
|
||||
.map(|member| Completion {
|
||||
name: member.name,
|
||||
ty: member.ty,
|
||||
ty: Some(member.ty),
|
||||
kind: None,
|
||||
builtin: false,
|
||||
})
|
||||
.collect()
|
||||
|
@ -227,7 +235,8 @@ impl<'db> SemanticModel<'db> {
|
|||
all_declarations_and_bindings(self.db, file_scope.to_scope_id(self.db, self.file))
|
||||
.map(|member| Completion {
|
||||
name: member.name,
|
||||
ty: member.ty,
|
||||
ty: Some(member.ty),
|
||||
kind: None,
|
||||
builtin: false,
|
||||
}),
|
||||
);
|
||||
|
@ -277,8 +286,22 @@ impl NameKind {
|
|||
pub struct Completion<'db> {
|
||||
/// The label shown to the user for this suggestion.
|
||||
pub name: Name,
|
||||
/// The type of this completion.
|
||||
pub ty: Type<'db>,
|
||||
/// The type of this completion, if available.
|
||||
///
|
||||
/// Generally speaking, this is always available
|
||||
/// *unless* this was a completion corresponding to
|
||||
/// an unimported symbol. In that case, computing the
|
||||
/// type of all such symbols could be quite expensive.
|
||||
pub ty: Option<Type<'db>>,
|
||||
/// The "kind" of this completion.
|
||||
///
|
||||
/// When this is set, it takes priority over any kind
|
||||
/// inferred from `ty`.
|
||||
///
|
||||
/// Usually this is set when `ty` is `None`, since it
|
||||
/// may be cheaper to compute at scale. (e.g., For
|
||||
/// unimported symbol completions.)
|
||||
pub kind: Option<CompletionKind>,
|
||||
/// Whether this suggestion came from builtins or not.
|
||||
///
|
||||
/// At time of writing (2025-06-26), this information
|
||||
|
@ -336,7 +359,7 @@ impl<'db> Completion<'db> {
|
|||
Type::TypeAlias(alias) => imp(db, alias.value_type(db))?,
|
||||
})
|
||||
}
|
||||
imp(db, self.ty)
|
||||
self.kind.or_else(|| self.ty.and_then(|ty| imp(db, ty)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue