mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-10 10:22:14 +00:00
[ty] Add infrastructure for AST garbage collection (#18445)
## Summary https://github.com/astral-sh/ty/issues/214 will require a couple invasive changes that I would like to get merged even before garbage collection is fully implemented (to avoid rebasing): - `ParsedModule` can no longer be dereferenced directly. Instead you need to load a `ParsedModuleRef` to access the AST, which requires a reference to the salsa database (as it may require re-parsing the AST if it was collected). - `AstNodeRef` can only be dereferenced with the `node` method, which takes a reference to the `ParsedModuleRef`. This allows us to encode the fact that ASTs do not live as long as the database and may be collected as soon a given instance of a `ParsedModuleRef` is dropped. There are a number of places where we currently merge the `'db` and `'ast` lifetimes, so this requires giving some types/functions two separate lifetime parameters.
This commit is contained in:
parent
55100209c7
commit
8531f4b3ca
33 changed files with 886 additions and 689 deletions
|
@ -1,4 +1,5 @@
|
|||
use ruff_db::files::File;
|
||||
use ruff_db::parsed::ParsedModuleRef;
|
||||
use ruff_python_ast::{self as ast, AnyNodeRef};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
|
||||
|
@ -37,9 +38,9 @@ pub(crate) struct Unpack<'db> {
|
|||
/// The target expression that is being unpacked. For example, in `(a, b) = (1, 2)`, the target
|
||||
/// expression is `(a, b)`.
|
||||
#[no_eq]
|
||||
#[returns(deref)]
|
||||
#[tracked]
|
||||
pub(crate) target: AstNodeRef<ast::Expr>,
|
||||
#[returns(ref)]
|
||||
pub(crate) _target: AstNodeRef<ast::Expr>,
|
||||
|
||||
/// The ingredient representing the value expression of the unpacking. For example, in
|
||||
/// `(a, b) = (1, 2)`, the value expression is `(1, 2)`.
|
||||
|
@ -49,6 +50,14 @@ pub(crate) struct Unpack<'db> {
|
|||
}
|
||||
|
||||
impl<'db> Unpack<'db> {
|
||||
pub(crate) fn target<'ast>(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
parsed: &'ast ParsedModuleRef,
|
||||
) -> &'ast ast::Expr {
|
||||
self._target(db).node(parsed)
|
||||
}
|
||||
|
||||
/// Returns the scope in which the unpack value expression belongs.
|
||||
///
|
||||
/// The scope in which the target and value expression belongs to are usually the same
|
||||
|
@ -65,8 +74,8 @@ impl<'db> Unpack<'db> {
|
|||
}
|
||||
|
||||
/// Returns the range of the unpack target expression.
|
||||
pub(crate) fn range(self, db: &'db dyn Db) -> TextRange {
|
||||
self.target(db).range()
|
||||
pub(crate) fn range(self, db: &'db dyn Db, module: &ParsedModuleRef) -> TextRange {
|
||||
self.target(db, module).range()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,15 +103,20 @@ impl<'db> UnpackValue<'db> {
|
|||
self,
|
||||
db: &'db dyn Db,
|
||||
scope: ScopeId<'db>,
|
||||
module: &ParsedModuleRef,
|
||||
) -> ScopedExpressionId {
|
||||
self.expression()
|
||||
.node_ref(db)
|
||||
.node_ref(db, module)
|
||||
.scoped_expression_id(db, scope)
|
||||
}
|
||||
|
||||
/// Returns the expression as an [`AnyNodeRef`].
|
||||
pub(crate) fn as_any_node_ref(self, db: &'db dyn Db) -> AnyNodeRef<'db> {
|
||||
self.expression().node_ref(db).into()
|
||||
pub(crate) fn as_any_node_ref<'ast>(
|
||||
self,
|
||||
db: &'db dyn Db,
|
||||
module: &'ast ParsedModuleRef,
|
||||
) -> AnyNodeRef<'ast> {
|
||||
self.expression().node_ref(db, module).into()
|
||||
}
|
||||
|
||||
pub(crate) const fn kind(self) -> UnpackKind {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue