mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-10 12:26:56 +00:00

Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
CI / cargo shear (push) Blocked by required conditions
## Summary This PR partially solves https://github.com/astral-sh/ty/issues/164 (derived from #17643). Currently, the definitions we manage are limited to those for simple name (symbol) targets, but we expand this to track definitions for attribute and subscript targets as well. This was originally planned as part of the work in #17643, but the changes are significant, so I made it a separate PR. After merging this PR, I will reflect this changes in #17643. There is still some incomplete work remaining, but the basic features have been implemented, so I am publishing it as a draft PR. Here is the TODO list (there may be more to come): * [x] Complete rewrite and refactoring of documentation (removing `Symbol` and replacing it with `Place`) * [x] More thorough testing * [x] Consolidation of duplicated code (maybe we can consolidate the handling related to name, attribute, and subscript) This PR replaces the current `Symbol` API with the `Place` API, which is a concept that includes attributes and subscripts (the term is borrowed from Rust). ## Test Plan `mdtest/narrow/assignment.md` is added. --------- Co-authored-by: David Peter <sharkdp@users.noreply.github.com> Co-authored-by: Carl Meyer <carl@astral.sh>
68 lines
2.4 KiB
Rust
68 lines
2.4 KiB
Rust
use crate::ast_node_ref::AstNodeRef;
|
|
use crate::db::Db;
|
|
use crate::semantic_index::place::{FileScopeId, ScopeId};
|
|
use ruff_db::files::File;
|
|
use ruff_python_ast as ast;
|
|
use salsa;
|
|
|
|
/// Whether or not this expression should be inferred as a normal expression or
|
|
/// a type expression. For example, in `self.x: <annotation> = <value>`, the
|
|
/// `<annotation>` is inferred as a type expression, while `<value>` is inferred
|
|
/// as a normal expression.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub(crate) enum ExpressionKind {
|
|
Normal,
|
|
TypeExpression,
|
|
}
|
|
|
|
/// An independently type-inferable expression.
|
|
///
|
|
/// Includes constraint expressions (e.g. if tests) and the RHS of an unpacking assignment.
|
|
///
|
|
/// ## Module-local type
|
|
/// This type should not be used as part of any cross-module API because
|
|
/// it holds a reference to the AST node. Range-offset changes
|
|
/// then propagate through all usages, and deserialization requires
|
|
/// reparsing the entire module.
|
|
///
|
|
/// E.g. don't use this type in:
|
|
///
|
|
/// * a return type of a cross-module query
|
|
/// * a field of a type that is a return type of a cross-module query
|
|
/// * an argument of a cross-module query
|
|
#[salsa::tracked(debug)]
|
|
pub(crate) struct Expression<'db> {
|
|
/// The file in which the expression occurs.
|
|
pub(crate) file: File,
|
|
|
|
/// The scope in which the expression occurs.
|
|
pub(crate) file_scope: FileScopeId,
|
|
|
|
/// The expression node.
|
|
#[no_eq]
|
|
#[tracked]
|
|
#[returns(deref)]
|
|
pub(crate) node_ref: AstNodeRef<ast::Expr>,
|
|
|
|
/// An assignment statement, if this expression is immediately used as the rhs of that
|
|
/// assignment.
|
|
///
|
|
/// (Note that this is the _immediately_ containing assignment — if a complex expression is
|
|
/// assigned to some target, only the outermost expression node has this set. The inner
|
|
/// expressions are used to build up the assignment result, and are not "immediately assigned"
|
|
/// to the target, and so have `None` for this field.)
|
|
#[no_eq]
|
|
#[tracked]
|
|
pub(crate) assigned_to: Option<AstNodeRef<ast::StmtAssign>>,
|
|
|
|
/// Should this expression be inferred as a normal expression or a type expression?
|
|
pub(crate) kind: ExpressionKind,
|
|
|
|
count: countme::Count<Expression<'static>>,
|
|
}
|
|
|
|
impl<'db> Expression<'db> {
|
|
pub(crate) fn scope(self, db: &'db dyn Db) -> ScopeId<'db> {
|
|
self.file_scope(db).to_scope_id(db, self.file(db))
|
|
}
|
|
}
|