mirror of
https://github.com/astral-sh/ruff
synced 2026-01-21 21:40:51 -05:00
[ty] Fix goto-declaration on the RHS of from module import submodule (#22042)
This commit is contained in:
@@ -1041,21 +1041,26 @@ mod resolve_definition {
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the target module file
|
||||
let module_file = {
|
||||
// Resolve the module being imported from (handles both relative and absolute imports)
|
||||
let Some(module_name) = ModuleName::from_import_statement(db, file, import_node).ok()
|
||||
else {
|
||||
return Vec::new();
|
||||
};
|
||||
let Some(resolved_module) = resolve_module(db, file, &module_name) else {
|
||||
return Vec::new();
|
||||
};
|
||||
resolved_module.file(db)
|
||||
// Resolve the module being imported from (handles both relative and absolute imports)
|
||||
let Some(module_name) = ModuleName::from_import_statement(db, file, import_node).ok()
|
||||
else {
|
||||
return Vec::new();
|
||||
};
|
||||
let Some(resolved_module) = resolve_module(db, file, &module_name) else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
// Resolve the target module file
|
||||
let module_file = resolved_module.file(db);
|
||||
|
||||
let Some(module_file) = module_file else {
|
||||
return Vec::new(); // Module resolution failed
|
||||
// No file means this is a namespace package, try to import the submodule
|
||||
return Vec::from_iter(resolve_from_import_submodule_definitions(
|
||||
db,
|
||||
file,
|
||||
symbol_name,
|
||||
module_name,
|
||||
));
|
||||
};
|
||||
|
||||
// Find the definition of this symbol in the imported module's global scope
|
||||
@@ -1064,22 +1069,38 @@ mod resolve_definition {
|
||||
|
||||
// Recursively resolve any import definitions found in the target module
|
||||
if definitions_in_module.is_empty() {
|
||||
// If we can't find the specific symbol, return empty list
|
||||
Vec::new()
|
||||
} else {
|
||||
let mut resolved_definitions = Vec::new();
|
||||
for def in definitions_in_module {
|
||||
let resolved = resolve_definition_recursive(
|
||||
db,
|
||||
def,
|
||||
visited,
|
||||
Some(symbol_name),
|
||||
alias_resolution,
|
||||
);
|
||||
resolved_definitions.extend(resolved);
|
||||
}
|
||||
resolved_definitions
|
||||
// This might be importing a submodule, try that
|
||||
return Vec::from_iter(resolve_from_import_submodule_definitions(
|
||||
db,
|
||||
file,
|
||||
symbol_name,
|
||||
module_name,
|
||||
));
|
||||
}
|
||||
|
||||
let mut resolved_definitions = Vec::new();
|
||||
for def in definitions_in_module {
|
||||
let resolved =
|
||||
resolve_definition_recursive(db, def, visited, Some(symbol_name), alias_resolution);
|
||||
resolved_definitions.extend(resolved);
|
||||
}
|
||||
resolved_definitions
|
||||
}
|
||||
|
||||
// Helper to resolve `from x.y import z` assuming `x.y.z` is a module.
|
||||
fn resolve_from_import_submodule_definitions<'db>(
|
||||
db: &'db dyn Db,
|
||||
file: File,
|
||||
symbol_name: &str,
|
||||
module_name: ModuleName,
|
||||
) -> Option<ResolvedDefinition<'db>> {
|
||||
let submodule_name = ModuleName::new(symbol_name)?;
|
||||
let mut full_submodule_name = module_name;
|
||||
full_submodule_name.extend(&submodule_name);
|
||||
let module = resolve_module(db, file, &full_submodule_name)?;
|
||||
let file = module.file(db)?;
|
||||
|
||||
Some(ResolvedDefinition::Module(file))
|
||||
}
|
||||
|
||||
/// Find definitions for a symbol name in a specific scope.
|
||||
|
||||
Reference in New Issue
Block a user