ruff/crates/ruff_python_parser/tests/snapshots/valid_syntax@expressions__call.py.snap
Ibraheem Ahmed c9dff5c7d5
[ty] AST garbage collection (#18482)
## Summary

Garbage collect ASTs once we are done checking a given file. Queries
with a cross-file dependency on the AST will reparse the file on demand.
This reduces ty's peak memory usage by ~20-30%.

The primary change of this PR is adding a `node_index` field to every
AST node, that is assigned by the parser. `ParsedModule` can use this to
create a flat index of AST nodes any time the file is parsed (or
reparsed). This allows `AstNodeRef` to simply index into the current
instance of the `ParsedModule`, instead of storing a pointer directly.

The indices are somewhat hackily (using an atomic integer) assigned by
the `parsed_module` query instead of by the parser directly. Assigning
the indices in source-order in the (recursive) parser turns out to be
difficult, and collecting the nodes during semantic indexing is
impossible as `SemanticIndex` does not hold onto a specific
`ParsedModuleRef`, which the pointers in the flat AST are tied to. This
means that we have to do an extra AST traversal to assign and collect
the nodes into a flat index, but the small performance impact (~3% on
cold runs) seems worth it for the memory savings.

Part of https://github.com/astral-sh/ty/issues/214.
2025-06-13 08:40:11 -04:00

682 lines
31 KiB
Text

---
source: crates/ruff_python_parser/tests/fixtures.rs
input_file: crates/ruff_python_parser/resources/valid/expressions/call.py
---
## AST
```
Module(
ModModule {
node_index: AtomicNodeIndex(..),
range: 0..349,
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 114..120,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 114..120,
func: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 114..118,
id: Name("call"),
ctx: Load,
},
),
arguments: Arguments {
range: 118..120,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 121..132,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 121..132,
func: Attribute(
ExprAttribute {
node_index: AtomicNodeIndex(..),
range: 121..130,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 121..125,
id: Name("attr"),
ctx: Load,
},
),
attr: Identifier {
id: Name("expr"),
range: 126..130,
node_index: AtomicNodeIndex(..),
},
ctx: Load,
},
),
arguments: Arguments {
range: 130..132,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 133..150,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 133..150,
func: Subscript(
ExprSubscript {
node_index: AtomicNodeIndex(..),
range: 133..148,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 133..142,
id: Name("subscript"),
ctx: Load,
},
),
slice: Tuple(
ExprTuple {
node_index: AtomicNodeIndex(..),
range: 143..147,
elts: [
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 143..144,
value: Int(
1,
),
},
),
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 146..147,
value: Int(
2,
),
},
),
],
ctx: Load,
parenthesized: false,
},
),
ctx: Load,
},
),
arguments: Arguments {
range: 148..150,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 151..162,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 151..162,
func: Subscript(
ExprSubscript {
node_index: AtomicNodeIndex(..),
range: 151..160,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 151..156,
id: Name("slice"),
ctx: Load,
},
),
slice: Slice(
ExprSlice {
node_index: AtomicNodeIndex(..),
range: 157..159,
lower: None,
upper: Some(
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 158..159,
value: Int(
1,
),
},
),
),
step: None,
},
),
ctx: Load,
},
),
arguments: Arguments {
range: 160..162,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 163..174,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 163..174,
func: List(
ExprList {
node_index: AtomicNodeIndex(..),
range: 163..172,
elts: [
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 164..165,
value: Int(
1,
),
},
),
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 167..168,
value: Int(
2,
),
},
),
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 170..171,
value: Int(
3,
),
},
),
],
ctx: Load,
},
),
arguments: Arguments {
range: 172..174,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 175..186,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 175..186,
func: Tuple(
ExprTuple {
node_index: AtomicNodeIndex(..),
range: 175..184,
elts: [
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 176..177,
value: Int(
1,
),
},
),
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 179..180,
value: Int(
2,
),
},
),
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 182..183,
value: Int(
3,
),
},
),
],
ctx: Load,
parenthesized: true,
},
),
arguments: Arguments {
range: 184..186,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 187..206,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 187..206,
func: Generator(
ExprGenerator {
node_index: AtomicNodeIndex(..),
range: 187..204,
elt: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 188..189,
id: Name("x"),
ctx: Load,
},
),
generators: [
Comprehension {
range: 190..203,
node_index: AtomicNodeIndex(..),
target: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 194..195,
id: Name("x"),
ctx: Store,
},
),
iter: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 199..203,
id: Name("iter"),
ctx: Load,
},
),
ifs: [],
is_async: false,
},
],
parenthesized: true,
},
),
arguments: Arguments {
range: 204..206,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 207..218,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 207..218,
func: Set(
ExprSet {
node_index: AtomicNodeIndex(..),
range: 207..216,
elts: [
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 208..209,
value: Int(
1,
),
},
),
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 211..212,
value: Int(
2,
),
},
),
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 214..215,
value: Int(
3,
),
},
),
],
},
),
arguments: Arguments {
range: 216..218,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 219..233,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 219..233,
func: Dict(
ExprDict {
node_index: AtomicNodeIndex(..),
range: 219..231,
items: [
DictItem {
key: Some(
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 220..221,
value: Int(
1,
),
},
),
),
value: NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 223..224,
value: Int(
2,
),
},
),
},
DictItem {
key: Some(
NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 226..227,
value: Int(
3,
),
},
),
),
value: NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 229..230,
value: Int(
4,
),
},
),
},
],
},
),
arguments: Arguments {
range: 231..233,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 234..245,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 234..245,
func: Yield(
ExprYield {
node_index: AtomicNodeIndex(..),
range: 235..242,
value: Some(
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 241..242,
id: Name("x"),
ctx: Load,
},
),
),
},
),
arguments: Arguments {
range: 243..245,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 306..312,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 306..312,
func: BooleanLiteral(
ExprBooleanLiteral {
node_index: AtomicNodeIndex(..),
range: 306..310,
value: true,
},
),
arguments: Arguments {
range: 310..312,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 313..320,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 313..320,
func: BooleanLiteral(
ExprBooleanLiteral {
node_index: AtomicNodeIndex(..),
range: 313..318,
value: false,
},
),
arguments: Arguments {
range: 318..320,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 321..327,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 321..327,
func: NoneLiteral(
ExprNoneLiteral {
node_index: AtomicNodeIndex(..),
range: 321..325,
},
),
arguments: Arguments {
range: 325..327,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 328..338,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 328..338,
func: StringLiteral(
ExprStringLiteral {
node_index: AtomicNodeIndex(..),
range: 328..336,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 328..336,
node_index: AtomicNodeIndex(..),
value: "string",
flags: StringLiteralFlags {
quote_style: Double,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
arguments: Arguments {
range: 336..338,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 339..342,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 339..342,
func: NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 339..340,
value: Int(
1,
),
},
),
arguments: Arguments {
range: 340..342,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 343..348,
value: Call(
ExprCall {
node_index: AtomicNodeIndex(..),
range: 343..348,
func: NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 343..346,
value: Float(
1.0,
),
},
),
arguments: Arguments {
range: 346..348,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
},
),
},
),
],
},
)
```