mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-18 17:40:37 +00:00
[ty] Add completions for from module import <CURSOR>
(#18830)
There were two main challenges in this PR.
The first was mostly just figuring out how to get the symbols
corresponding to `module`. It turns out that we do this in a couple
of places in ty already, but through different means. In one approach,
we use [`exported_names`]. In another approach, we get a `Type`
corresponding to the module. We take the latter approach here, which is
consistent with how we do completions elsewhere. (I looked into
factoring this logic out into its own function, but it ended up being
pretty constrained. e.g., There's only one other place where we want to
go from `ast::StmtImportFrom` to a module `Type`, and that code also
wants the module name.)
The second challenge was recognizing the `from module import <CURSOR>`
pattern in the code. I initially started with some fixed token patterns
to get a proof of concept working. But I ended up switching to mini
state machine over tokens. I looked at the parser for `StmtImportFrom`
to determine what kinds of tokens we can expect.
[`exported_names`]:
23a3b6ef23/crates/ty_python_semantic/src/semantic_index/re_exports.rs (L47)
This commit is contained in:
parent
9e9c4fe17b
commit
a77db3da3f
2 changed files with 342 additions and 0 deletions
|
@ -41,6 +41,31 @@ impl<'db> SemanticModel<'db> {
|
|||
resolve_module(self.db, module_name)
|
||||
}
|
||||
|
||||
/// Returns completions for symbols available in a `from module import <CURSOR>` context.
|
||||
pub fn import_completions(
|
||||
&self,
|
||||
import: &ast::StmtImportFrom,
|
||||
_name: Option<usize>,
|
||||
) -> Vec<Name> {
|
||||
let module_name = match ModuleName::from_import_statement(self.db, self.file, import) {
|
||||
Ok(module_name) => module_name,
|
||||
Err(err) => {
|
||||
tracing::debug!(
|
||||
"Could not extract module name from `{module:?}` with level {level}: {err:?}",
|
||||
module = import.module,
|
||||
level = import.level,
|
||||
);
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
let Some(module) = resolve_module(self.db, &module_name) else {
|
||||
tracing::debug!("Could not resolve module from `{module_name:?}`");
|
||||
return vec![];
|
||||
};
|
||||
let ty = Type::module_literal(self.db, self.file, &module);
|
||||
crate::types::all_members(self.db, ty).into_iter().collect()
|
||||
}
|
||||
|
||||
/// Returns completions for symbols available in a `object.<CURSOR>` context.
|
||||
pub fn attribute_completions(&self, node: &ast::ExprAttribute) -> Vec<Name> {
|
||||
let ty = node.value.inferred_type(self);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue