Auto generate ast expression nodes (#16285)

## Summary

Part of https://github.com/astral-sh/ruff/issues/15655

- Auto generate AST nodes using definitions in `ast.toml`. I added
attributes similar to
[`Field`](https://github.com/python/cpython/blob/main/Parser/asdl.py#L67)
in ASDL to hold field information

## Test Plan

Nothing outside the `ruff_python_ast` package should change.

---------

Co-authored-by: Douglas Creager <dcreager@dcreager.net>
This commit is contained in:
Shaygan Hooshyari 2025-03-05 14:25:55 +01:00 committed by GitHub
parent cc324abcc2
commit 23fd4927ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 719 additions and 360 deletions

View file

@ -3,7 +3,8 @@ use std::fmt::{Debug, Display, Formatter, Write};
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use crate::{nodes, Expr};
use crate::generated::ExprName;
use crate::Expr;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@ -387,16 +388,14 @@ impl<'a> UnqualifiedName<'a> {
let attr1 = match expr {
Expr::Attribute(attr1) => attr1,
// Ex) `foo`
Expr::Name(nodes::ExprName { id, .. }) => {
return Some(Self::from_slice(&[id.as_str()]))
}
Expr::Name(ExprName { id, .. }) => return Some(Self::from_slice(&[id.as_str()])),
_ => return None,
};
let attr2 = match attr1.value.as_ref() {
Expr::Attribute(attr2) => attr2,
// Ex) `foo.bar`
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
return Some(Self::from_slice(&[id.as_str(), attr1.attr.as_str()]))
}
_ => return None,
@ -405,7 +404,7 @@ impl<'a> UnqualifiedName<'a> {
let attr3 = match attr2.value.as_ref() {
Expr::Attribute(attr3) => attr3,
// Ex) `foo.bar.baz`
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
return Some(Self::from_slice(&[
id.as_str(),
attr2.attr.as_str(),
@ -418,7 +417,7 @@ impl<'a> UnqualifiedName<'a> {
let attr4 = match attr3.value.as_ref() {
Expr::Attribute(attr4) => attr4,
// Ex) `foo.bar.baz.bop`
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
return Some(Self::from_slice(&[
id.as_str(),
attr3.attr.as_str(),
@ -432,7 +431,7 @@ impl<'a> UnqualifiedName<'a> {
let attr5 = match attr4.value.as_ref() {
Expr::Attribute(attr5) => attr5,
// Ex) `foo.bar.baz.bop.bap`
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
return Some(Self::from_slice(&[
id.as_str(),
attr4.attr.as_str(),
@ -447,7 +446,7 @@ impl<'a> UnqualifiedName<'a> {
let attr6 = match attr5.value.as_ref() {
Expr::Attribute(attr6) => attr6,
// Ex) `foo.bar.baz.bop.bap.bab`
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
return Some(Self::from_slice(&[
id.as_str(),
attr5.attr.as_str(),
@ -463,7 +462,7 @@ impl<'a> UnqualifiedName<'a> {
let attr7 = match attr6.value.as_ref() {
Expr::Attribute(attr7) => attr7,
// Ex) `foo.bar.baz.bop.bap.bab.bob`
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
return Some(Self::from_slice(&[
id.as_str(),
attr6.attr.as_str(),
@ -480,7 +479,7 @@ impl<'a> UnqualifiedName<'a> {
let attr8 = match attr7.value.as_ref() {
Expr::Attribute(attr8) => attr8,
// Ex) `foo.bar.baz.bop.bap.bab.bob.bib`
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
return Some(Self(SegmentsVec::from([
id.as_str(),
attr7.attr.as_str(),
@ -505,7 +504,7 @@ impl<'a> UnqualifiedName<'a> {
segments.push(attr.attr.as_str());
&*attr.value
}
Expr::Name(nodes::ExprName { id, .. }) => {
Expr::Name(ExprName { id, .. }) => {
segments.push(id.as_str());
break;
}