Split CallPath into QualifiedName and UnqualifiedName (#10210)

## Summary

Charlie can probably explain this better than I but it turns out,
`CallPath` is used for two different things:

* To represent unqualified names like `version` where `version` can be a
local variable or imported (e.g. `from sys import version` where the
full qualified name is `sys.version`)
* To represent resolved, full qualified names

This PR splits `CallPath` into two types to make this destinction clear.

> Note: I haven't renamed all `call_path` variables to `qualified_name`
or `unqualified_name`. I can do that if that's welcomed but I first want
to get feedback on the approach and naming overall.

## Test Plan

`cargo test`
This commit is contained in:
Micha Reiser 2024-03-04 10:06:51 +01:00 committed by GitHub
parent ba4328226d
commit a6d892b1f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
181 changed files with 1692 additions and 1412 deletions

View file

@ -1,28 +1,28 @@
use rustc_hash::FxHashSet;
use ruff_python_ast as ast;
use ruff_python_ast::call_path::CallPath;
use ruff_python_ast::helpers::map_subscript;
use ruff_python_ast::name::QualifiedName;
use crate::{BindingId, SemanticModel};
/// Return `true` if any base class matches a [`CallPath`] predicate.
pub fn any_call_path(
/// Return `true` if any base class matches a [`QualifiedName`] predicate.
pub fn any_qualified_name(
class_def: &ast::StmtClassDef,
semantic: &SemanticModel,
func: &dyn Fn(CallPath) -> bool,
func: &dyn Fn(QualifiedName) -> bool,
) -> bool {
fn inner(
class_def: &ast::StmtClassDef,
semantic: &SemanticModel,
func: &dyn Fn(CallPath) -> bool,
func: &dyn Fn(QualifiedName) -> bool,
seen: &mut FxHashSet<BindingId>,
) -> bool {
class_def.bases().iter().any(|expr| {
// If the base class itself matches the pattern, then this does too.
// Ex) `class Foo(BaseModel): ...`
if semantic
.resolve_call_path(map_subscript(expr))
.resolve_qualified_name(map_subscript(expr))
.is_some_and(func)
{
return true;