Skip to content
This repository was archived by the owner on Jul 27, 2023. It is now read-only.

Commit 5f241e8

Browse files
committed
Add Decorator node (#7)
1 parent 8fd4d4f commit 5f241e8

15 files changed

+2369
-2122
lines changed

ast-pyo3/src/gen/to_py_ast.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,14 @@ impl<R> PyNode for ast::TypeParamTypeVarTuple<R> {
984984
}
985985
}
986986

987+
impl<R> PyNode for ast::Decorator<R> {
988+
#[inline]
989+
fn py_type_cache() -> &'static OnceCell<(Py<PyAny>, Py<PyAny>)> {
990+
static PY_TYPE: OnceCell<(Py<PyAny>, Py<PyAny>)> = OnceCell::new();
991+
&PY_TYPE
992+
}
993+
}
994+
987995
impl ToPyAst for ast::ExprContext {
988996
#[inline]
989997
fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> {
@@ -2736,6 +2744,23 @@ impl ToPyAst for ast::TypeParamTypeVarTuple<TextRange> {
27362744
}
27372745
}
27382746

2747+
2748+
impl ToPyAst for ast::Decorator<TextRange> {
2749+
#[inline]
2750+
fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> {
2751+
let cache = Self::py_type_cache().get().unwrap();
2752+
2753+
let Self {
2754+
expression,
2755+
range: _range,
2756+
} = self;
2757+
2758+
let instance = Py::<PyAny>::as_ref(&cache.0, py).call1((expression.to_py_ast(py)?,))?;
2759+
2760+
Ok(instance)
2761+
}
2762+
}
2763+
27392764
impl ToPyAst for ast::Mod<SourceRange> {
27402765
#[inline]
27412766
fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> {
@@ -4954,7 +4979,7 @@ impl ToPyAst for ast::TypeParamTypeVarTuple<SourceRange> {
49544979

49554980
let Self {
49564981
name,
4957-
range: _range,
4982+
range: _range
49584983
} = self;
49594984

49604985
let instance = Py::<PyAny>::as_ref(&cache.0, py).call1((name.to_py_ast(py)?,))?;
@@ -4966,6 +4991,21 @@ impl ToPyAst for ast::TypeParamTypeVarTuple<SourceRange> {
49664991
instance.setattr(cache.end_lineno.as_ref(py), end.row.get())?;
49674992
instance.setattr(cache.end_col_offset.as_ref(py), end.column.get())?;
49684993
}
4994+
Ok(instance)
4995+
}
4996+
}
4997+
4998+
impl ToPyAst for ast::Decorator<SourceRange> {
4999+
#[inline]
5000+
fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> {
5001+
let cache = Self::py_type_cache().get().unwrap();
5002+
5003+
let Self {
5004+
expression,
5005+
range: _range,
5006+
} = self;
5007+
5008+
let instance = Py::<PyAny>::as_ref(&cache.0, py).call1((expression.to_py_ast(py)?,))?;
49695009

49705010
Ok(instance)
49715011
}
@@ -5096,5 +5136,6 @@ fn init_types(py: Python) -> PyResult<()> {
50965136
cache_py_type::<ast::TypeParamTypeVar>(ast_module)?;
50975137
cache_py_type::<ast::TypeParamParamSpec>(ast_module)?;
50985138
cache_py_type::<ast::TypeParamTypeVarTuple>(ast_module)?;
5139+
cache_py_type::<ast::Decorator>(ast_module)?;
50995140
Ok(())
51005141
}

ast-pyo3/src/gen/wrapper_located.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4082,6 +4082,22 @@ impl ToPyObject for TypeParam {
40824082
Py::new(py, initializer).unwrap().into_py(py)
40834083
}
40844084
}
4085+
#[pyclass(module="rustpython_ast.located", name="_decorator", extends=super::Ast, frozen)]
4086+
#[derive(Clone, Debug)]
4087+
pub struct Decorator(pub &'static ast::Decorator<SourceRange>);
4088+
4089+
impl From<&'static ast::Decorator<SourceRange>> for Decorator {
4090+
fn from(node: &'static ast::Decorator<SourceRange>) -> Self {
4091+
Decorator(node)
4092+
}
4093+
}
4094+
4095+
impl ToPyObject for Decorator {
4096+
fn to_object(&self, py: Python) -> PyObject {
4097+
let initializer = PyClassInitializer::from(Ast).add_subclass(self.clone());
4098+
Py::new(py, initializer).unwrap().into_py(py)
4099+
}
4100+
}
40854101

40864102
impl ToPyWrapper for ast::TypeParam<SourceRange> {
40874103
#[inline]
@@ -4119,6 +4135,12 @@ impl ToPyWrapper for ast::TypeParamTypeVar<SourceRange> {
41194135
Ok(TypeParamTypeVar(self).to_object(py))
41204136
}
41214137
}
4138+
impl ToPyWrapper for ast::Decorator<SourceRange> {
4139+
#[inline]
4140+
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
4141+
Ok(Decorator(self).to_object(py))
4142+
}
4143+
}
41224144

41234145
#[pymethods]
41244146
impl TypeParamTypeVar {
@@ -4203,6 +4225,21 @@ impl TypeParamTypeVarTuple {
42034225
fn get_name(&self, py: Python) -> PyResult<PyObject> {
42044226
self.0.name.to_py_wrapper(py)
42054227
}
4228+
4229+
#[getter]
4230+
#[inline]
4231+
fn get_expression(&self, py: Python) -> PyResult<PyObject> {
4232+
self.0.expression.to_py_wrapper(py)
4233+
}
4234+
}
4235+
4236+
#[pymethods]
4237+
impl Decorator {
4238+
#[getter]
4239+
#[inline]
4240+
fn get_expression(&self, py: Python) -> PyResult<PyObject> {
4241+
self.0.expression.to_py_wrapper(py)
4242+
}
42064243
}
42074244

42084245
impl ToPyWrapper for ast::ExprContext {
@@ -4626,5 +4663,6 @@ pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> {
46264663
super::init_type::<TypeParamTypeVar, ast::TypeParamTypeVar>(py, m)?;
46274664
super::init_type::<TypeParamParamSpec, ast::TypeParamParamSpec>(py, m)?;
46284665
super::init_type::<TypeParamTypeVarTuple, ast::TypeParamTypeVarTuple>(py, m)?;
4666+
super::init_type::<Decorator, ast::Decorator>(py, m)?;
46294667
Ok(())
46304668
}

ast-pyo3/src/gen/wrapper_ranged.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4078,7 +4078,22 @@ impl TypeParam {
40784078
}
40794079
impl ToPyObject for TypeParam {
40804080
fn to_object(&self, py: Python) -> PyObject {
4081-
let initializer = Self::new();
4081+
let initializer = Self::new();Py::new(py, initializer).unwrap().into_py(py)
4082+
}
4083+
}
4084+
#[pyclass(module="rustpython_ast.ranged", name="_decorator", extends=super::Ast, frozen)]
4085+
#[derive(Clone, Debug)]
4086+
pub struct Decorator(pub &'static ast::Decorator<TextRange>);
4087+
4088+
impl From<&'static ast::Decorator<TextRange>> for Decorator {
4089+
fn from(node: &'static ast::Decorator<TextRange>) -> Self {
4090+
Decorator(node)
4091+
}
4092+
}
4093+
4094+
impl ToPyObject for Decorator {
4095+
fn to_object(&self, py: Python) -> PyObject {
4096+
let initializer = PyClassInitializer::from(Ast).add_subclass(self.clone());
40824097
Py::new(py, initializer).unwrap().into_py(py)
40834098
}
40844099
}
@@ -4120,6 +4135,13 @@ impl ToPyWrapper for ast::TypeParamTypeVar<TextRange> {
41204135
}
41214136
}
41224137

4138+
impl ToPyWrapper for ast::Decorator<TextRange> {
4139+
#[inline]
4140+
fn to_py_wrapper(&'static self, py: Python) -> PyResult<Py<PyAny>> {
4141+
Ok(Decorator(self).to_object(py))
4142+
}
4143+
}
4144+
41234145
#[pymethods]
41244146
impl TypeParamTypeVar {
41254147
#[getter]
@@ -4203,6 +4225,21 @@ impl TypeParamTypeVarTuple {
42034225
fn get_name(&self, py: Python) -> PyResult<PyObject> {
42044226
self.0.name.to_py_wrapper(py)
42054227
}
4228+
4229+
#[getter]
4230+
#[inline]
4231+
fn get_expression(&self, py: Python) -> PyResult<PyObject> {
4232+
self.0.expression.to_py_wrapper(py)
4233+
}
4234+
}
4235+
4236+
#[pymethods]
4237+
impl Decorator {
4238+
#[getter]
4239+
#[inline]
4240+
fn get_expression(&self, py: Python) -> PyResult<PyObject> {
4241+
self.0.expression.to_py_wrapper(py)
4242+
}
42064243
}
42074244

42084245
pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> {
@@ -4330,5 +4367,6 @@ pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> {
43304367
super::init_type::<TypeParamTypeVar, ast::TypeParamTypeVar>(py, m)?;
43314368
super::init_type::<TypeParamParamSpec, ast::TypeParamParamSpec>(py, m)?;
43324369
super::init_type::<TypeParamTypeVarTuple, ast::TypeParamTypeVarTuple>(py, m)?;
4370+
super::init_type::<Decorator, ast::Decorator>(py, m)?;
43334371
Ok(())
43344372
}

ast/Python.asdl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- ASDL's 4 builtin types are:
2-
-- identifier, int, string, constant
2+
-- identifier, int, string, constant, decorator
33

44
module Python
55
{
@@ -9,18 +9,18 @@ module Python
99
| FunctionType(expr* argtypes, expr returns)
1010

1111
stmt = FunctionDef(identifier name, arguments args,
12-
stmt* body, expr* decorator_list, expr? returns,
12+
stmt* body, decorator* decorator_list, expr? returns,
1313
string? type_comment, type_param* type_params)
1414
| AsyncFunctionDef(identifier name, arguments args,
15-
stmt* body, expr* decorator_list, expr? returns,
15+
stmt* body, decorator* decorator_list, expr? returns,
1616
string? type_comment, type_param* type_params)
1717

1818
| ClassDef(identifier name,
1919
expr* bases,
2020
keyword* keywords,
2121
stmt* body,
22-
expr* decorator_list,
2322
type_param* type_params)
23+
decorator* decorator_list)
2424
| Return(expr? value)
2525

2626
| Delete(expr* targets)
@@ -149,4 +149,6 @@ module Python
149149
| ParamSpec(identifier name)
150150
| TypeVarTuple(identifier name)
151151
attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
152+
153+
decorator = (expr expression)
152154
}

ast/src/gen/fold.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,12 @@ pub trait Fold<U> {
537537
) -> Result<TypeParamTypeVarTuple<Self::TargetU>, Self::Error> {
538538
fold_type_param_type_var_tuple(self, node)
539539
}
540+
fn fold_decorator(
541+
&mut self,
542+
node: Decorator<U>,
543+
) -> Result<Decorator<Self::TargetU>, Self::Error> {
544+
fold_decorator(self, node)
545+
}
540546
fn fold_arg_with_default(
541547
&mut self,
542548
node: ArgWithDefault<U>,
@@ -2864,14 +2870,14 @@ pub fn fold_type_ignore_type_ignore<U, F: Fold<U> + ?Sized>(
28642870
Ok(TypeIgnoreTypeIgnore { lineno, tag, range })
28652871
}
28662872
impl<T, U> Foldable<T, U> for TypeParam<T> {
2867-
type Mapped = TypeParam<U>;
2868-
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
2873+
type Mapped = TypeParam<U>;fn fold<F: Fold<T, TargetU = U> + ?Sized>(
28692874
self,
28702875
folder: &mut F,
28712876
) -> Result<Self::Mapped, F::Error> {
28722877
folder.fold_type_param(self)
28732878
}
28742879
}
2880+
28752881
pub fn fold_type_param<U, F: Fold<U> + ?Sized>(
28762882
#[allow(unused)] folder: &mut F,
28772883
node: TypeParam<U>,
@@ -2944,6 +2950,27 @@ pub fn fold_type_param_type_var_tuple<U, F: Fold<U> + ?Sized>(
29442950
let range = folder.map_user(range, context)?;
29452951
Ok(TypeParamTypeVarTuple { name, range })
29462952
}
2953+
2954+
impl<T, U> Foldable<T, U> for Decorator<T> {
2955+
type Mapped = Decorator<U>;
2956+
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
2957+
self,
2958+
folder: &mut F,
2959+
) -> Result<Self::Mapped, F::Error> {
2960+
folder.fold_decorator(self)
2961+
}
2962+
}
2963+
pub fn fold_decorator<U, F: Fold<U> + ?Sized>(
2964+
#[allow(unused)] folder: &mut F,
2965+
node: Decorator<U>,
2966+
) -> Result<Decorator<F::TargetU>, F::Error> {
2967+
let Decorator { expression, range } = node;
2968+
let context = folder.will_map_user_cfg(&range);
2969+
let expression = Foldable::fold(expression, folder)?;
2970+
let range = folder.map_user_cfg(range, context)?;
2971+
Ok(Decorator { expression, range })
2972+
}
2973+
29472974
impl<T, U> Foldable<T, U> for ArgWithDefault<T> {
29482975
type Mapped = ArgWithDefault<U>;
29492976
fn fold<F: Fold<T, TargetU = U> + ?Sized>(
@@ -2953,6 +2980,7 @@ impl<T, U> Foldable<T, U> for ArgWithDefault<T> {
29532980
folder.fold_arg_with_default(self)
29542981
}
29552982
}
2983+
29562984
pub fn fold_arg_with_default<U, F: Fold<U> + ?Sized>(
29572985
#[allow(unused)] folder: &mut F,
29582986
node: ArgWithDefault<U>,

ast/src/gen/generic.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ pub enum Ast<R = TextRange> {
2323
Pattern(Pattern<R>),
2424
TypeIgnore(TypeIgnore<R>),
2525
TypeParam(TypeParam<R>),
26+
Decorator(Decorator<R>),
2627
}
28+
2729
impl<R> Node for Ast<R> {
2830
const NAME: &'static str = "AST";
2931
const FIELD_NAMES: &'static [&'static str] = &[];
@@ -143,6 +145,12 @@ impl<R> From<TypeParam<R>> for Ast<R> {
143145
}
144146
}
145147

148+
impl<R> From<Decorator<R>> for Ast<R> {
149+
fn from(node: Decorator<R>) -> Self {
150+
Ast::Decorator(node)
151+
}
152+
}
153+
146154
/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
147155
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
148156
pub enum Mod<R = TextRange> {
@@ -315,7 +323,7 @@ pub struct StmtFunctionDef<R = TextRange> {
315323
pub name: Identifier,
316324
pub args: Box<Arguments<R>>,
317325
pub body: Vec<Stmt<R>>,
318-
pub decorator_list: Vec<Expr<R>>,
326+
pub decorator_list: Vec<Decorator<R>>,
319327
pub returns: Option<Box<Expr<R>>>,
320328
pub type_comment: Option<String>,
321329
pub type_params: Vec<TypeParam<R>>,
@@ -351,7 +359,7 @@ pub struct StmtAsyncFunctionDef<R = TextRange> {
351359
pub name: Identifier,
352360
pub args: Box<Arguments<R>>,
353361
pub body: Vec<Stmt<R>>,
354-
pub decorator_list: Vec<Expr<R>>,
362+
pub decorator_list: Vec<Decorator<R>>,
355363
pub returns: Option<Box<Expr<R>>>,
356364
pub type_comment: Option<String>,
357365
pub type_params: Vec<TypeParam<R>>,
@@ -388,8 +396,8 @@ pub struct StmtClassDef<R = TextRange> {
388396
pub bases: Vec<Expr<R>>,
389397
pub keywords: Vec<Keyword<R>>,
390398
pub body: Vec<Stmt<R>>,
391-
pub decorator_list: Vec<Expr<R>>,
392399
pub type_params: Vec<TypeParam<R>>,
400+
pub decorator_list: Vec<Decorator<R>>,
393401
}
394402

395403
impl<R> Node for StmtClassDef<R> {
@@ -3197,6 +3205,18 @@ impl<R> Node for TypeParam<R> {
31973205
const FIELD_NAMES: &'static [&'static str] = &[];
31983206
}
31993207

3208+
/// See also [decorator](https://docs.python.org/3/library/ast.html#ast.decorator)
3209+
#[derive(Clone, Debug, PartialEq)]
3210+
pub struct Decorator<R = TextRange> {
3211+
pub range: OptionalRange<R>,
3212+
pub expression: Expr<R>,
3213+
}
3214+
3215+
impl<R> Node for Decorator<R> {
3216+
const NAME: &'static str = "decorator";
3217+
const FIELD_NAMES: &'static [&'static str] = &["expression"];
3218+
}
3219+
32003220
/// An alternative type of AST `arguments`. This is parser-friendly and human-friendly definition of function arguments.
32013221
/// This form also has advantage to implement pre-order traverse.
32023222
/// `defaults` and `kw_defaults` fields are removed and the default values are placed under each `arg_with_default` typed argument.

0 commit comments

Comments
 (0)