mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-29 11:07:54 +00:00
[ty] Support goto-definition on vendored typeshed stubs (#21020)
This is an alternative to #21012 that more narrowly handles this logic in the stub-mapping machinery rather than pervasively allowing us to identify cached files as typeshed stubs. Much of the logic is the same (pulling the logic out of ty_server so it can be reused). I don't have a good sense for if one approach is "better" or "worse" in terms of like, semantics and Weird Bugs that this can cause. This one is just "less spooky in its broad consequences" and "less muddying of separation of concerns" and puts the extra logic on a much colder path. I won't be surprised if one day the previous implementation needs to be revisited for its more sweeping effects but for now this is good. Fixes https://github.com/astral-sh/ty/issues/1054
This commit is contained in:
parent
9d1ffd605c
commit
2e13b13012
7 changed files with 83 additions and 22 deletions
|
|
@ -1138,8 +1138,10 @@ mod resolve_definition {
|
|||
}
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use ruff_db::files::{File, FileRange};
|
||||
use ruff_db::files::{File, FileRange, vendored_path_to_file};
|
||||
use ruff_db::parsed::{ParsedModuleRef, parsed_module};
|
||||
use ruff_db::system::SystemPath;
|
||||
use ruff_db::vendored::VendoredPathBuf;
|
||||
use ruff_python_ast as ast;
|
||||
use rustc_hash::FxHashSet;
|
||||
use tracing::trace;
|
||||
|
|
@ -1397,17 +1399,42 @@ mod resolve_definition {
|
|||
pub fn map_stub_definition<'db>(
|
||||
db: &'db dyn Db,
|
||||
def: &ResolvedDefinition<'db>,
|
||||
cached_vendored_typeshed: Option<&SystemPath>,
|
||||
) -> Option<Vec<ResolvedDefinition<'db>>> {
|
||||
trace!("Stub mapping definition...");
|
||||
// If the file isn't a stub, this is presumably the real definition
|
||||
let stub_file = def.file(db);
|
||||
trace!("Stub mapping definition in: {}", stub_file.path(db));
|
||||
if !stub_file.is_stub(db) {
|
||||
trace!("File isn't a stub, no stub mapping to do");
|
||||
return None;
|
||||
}
|
||||
|
||||
// We write vendored typeshed stubs to disk in the cache, and consequently "forget"
|
||||
// that they're typeshed when an IDE hands those paths back to us later. For most
|
||||
// purposes this seemingly doesn't matter at all, and avoids issues with someone
|
||||
// editing the cache by hand in their IDE and us getting confused about the contents
|
||||
// of the file (hello and welcome to anyone who has found Bigger Issues this causes).
|
||||
//
|
||||
// The major exception is in exactly stub-mapping, where we need to "remember" that
|
||||
// we're in typeshed to successfully stub-map to the Real Stdlib. So here we attempt
|
||||
// to do just that. The resulting file must not be used for anything other than
|
||||
// this module lookup, as the `ResolvedDefinition` we're handling isn't for that file.
|
||||
let mut stub_file_for_module_lookup = stub_file;
|
||||
if let Some(vendored_typeshed) = cached_vendored_typeshed
|
||||
&& let Some(stub_path) = stub_file.path(db).as_system_path()
|
||||
&& let Ok(rel_path) = stub_path.strip_prefix(vendored_typeshed)
|
||||
&& let Ok(typeshed_file) =
|
||||
vendored_path_to_file(db, VendoredPathBuf::from(rel_path.as_str()))
|
||||
{
|
||||
trace!(
|
||||
"Stub is cached vendored typeshed: {}",
|
||||
typeshed_file.path(db)
|
||||
);
|
||||
stub_file_for_module_lookup = typeshed_file;
|
||||
}
|
||||
|
||||
// It's definitely a stub, so now rerun module resolution but with stubs disabled.
|
||||
let stub_module = file_to_module(db, stub_file)?;
|
||||
let stub_module = file_to_module(db, stub_file_for_module_lookup)?;
|
||||
trace!("Found stub module: {}", stub_module.name(db));
|
||||
let real_module = resolve_real_module(db, stub_module.name(db))?;
|
||||
trace!("Found real module: {}", real_module.name(db));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue