diff --git a/ast-pyo3/src/gen/to_py_ast.rs b/ast-pyo3/src/gen/to_py_ast.rs index c3288f28..8c8ea3ec 100644 --- a/ast-pyo3/src/gen/to_py_ast.rs +++ b/ast-pyo3/src/gen/to_py_ast.rs @@ -96,6 +96,14 @@ impl PyNode for ast::StmtAssign { } } +impl PyNode for ast::StmtTypeAlias { + #[inline] + fn py_type_cache() -> &'static OnceCell<(Py, Py)> { + static PY_TYPE: OnceCell<(Py, Py)> = OnceCell::new(); + &PY_TYPE + } +} + impl PyNode for ast::StmtAugAssign { #[inline] fn py_type_cache() -> &'static OnceCell<(Py, Py)> { @@ -944,6 +952,38 @@ impl PyNode for ast::TypeIgnoreTypeIgnore { } } +impl PyNode for ast::TypeParam { + #[inline] + fn py_type_cache() -> &'static OnceCell<(Py, Py)> { + static PY_TYPE: OnceCell<(Py, Py)> = OnceCell::new(); + &PY_TYPE + } +} + +impl PyNode for ast::TypeParamTypeVar { + #[inline] + fn py_type_cache() -> &'static OnceCell<(Py, Py)> { + static PY_TYPE: OnceCell<(Py, Py)> = OnceCell::new(); + &PY_TYPE + } +} + +impl PyNode for ast::TypeParamParamSpec { + #[inline] + fn py_type_cache() -> &'static OnceCell<(Py, Py)> { + static PY_TYPE: OnceCell<(Py, Py)> = OnceCell::new(); + &PY_TYPE + } +} + +impl PyNode for ast::TypeParamTypeVarTuple { + #[inline] + fn py_type_cache() -> &'static OnceCell<(Py, Py)> { + static PY_TYPE: OnceCell<(Py, Py)> = OnceCell::new(); + &PY_TYPE + } +} + impl ToPyAst for ast::ExprContext { #[inline] fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { @@ -1112,6 +1152,7 @@ impl ToPyAst for ast::Stmt { ast::Stmt::Return(cons) => cons.to_py_ast(py)?, ast::Stmt::Delete(cons) => cons.to_py_ast(py)?, ast::Stmt::Assign(cons) => cons.to_py_ast(py)?, + ast::Stmt::TypeAlias(cons) => cons.to_py_ast(py)?, ast::Stmt::AugAssign(cons) => cons.to_py_ast(py)?, ast::Stmt::AnnAssign(cons) => cons.to_py_ast(py)?, ast::Stmt::For(cons) => cons.to_py_ast(py)?, @@ -1150,6 +1191,7 @@ impl ToPyAst for ast::StmtFunctionDef { decorator_list, returns, type_comment, + type_params, range: _range, } = self; @@ -1160,6 +1202,7 @@ impl ToPyAst for ast::StmtFunctionDef { decorator_list.to_py_ast(py)?, returns.to_py_ast(py)?, type_comment.to_py_ast(py)?, + type_params.to_py_ast(py)?, ))?; Ok(instance) @@ -1178,6 +1221,7 @@ impl ToPyAst for ast::StmtAsyncFunctionDef { decorator_list, returns, type_comment, + type_params, range: _range, } = self; @@ -1188,6 +1232,7 @@ impl ToPyAst for ast::StmtAsyncFunctionDef { decorator_list.to_py_ast(py)?, returns.to_py_ast(py)?, type_comment.to_py_ast(py)?, + type_params.to_py_ast(py)?, ))?; Ok(instance) @@ -1205,6 +1250,7 @@ impl ToPyAst for ast::StmtClassDef { keywords, body, decorator_list, + type_params, range: _range, } = self; @@ -1214,6 +1260,7 @@ impl ToPyAst for ast::StmtClassDef { keywords.to_py_ast(py)?, body.to_py_ast(py)?, decorator_list.to_py_ast(py)?, + type_params.to_py_ast(py)?, ))?; Ok(instance) @@ -1274,6 +1321,28 @@ impl ToPyAst for ast::StmtAssign { } } +impl ToPyAst for ast::StmtTypeAlias { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + type_params, + value, + range: _range, + } = self; + + let instance = Py::::as_ref(&cache.0, py).call1(( + name.to_py_ast(py)?, + type_params.to_py_ast(py)?, + value.to_py_ast(py)?, + ))?; + + Ok(instance) + } +} + impl ToPyAst for ast::StmtAugAssign { #[inline] fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { @@ -2605,6 +2674,68 @@ impl ToPyAst for ast::TypeIgnoreTypeIgnore { } } +impl ToPyAst for ast::TypeParam { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let instance = match &self { + ast::TypeParam::TypeVar(cons) => cons.to_py_ast(py)?, + ast::TypeParam::ParamSpec(cons) => cons.to_py_ast(py)?, + ast::TypeParam::TypeVarTuple(cons) => cons.to_py_ast(py)?, + }; + Ok(instance) + } +} + +impl ToPyAst for ast::TypeParamTypeVar { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + bound, + range: _range, + } = self; + + let instance = + Py::::as_ref(&cache.0, py).call1((name.to_py_ast(py)?, bound.to_py_ast(py)?))?; + + Ok(instance) + } +} + +impl ToPyAst for ast::TypeParamParamSpec { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + range: _range, + } = self; + + let instance = Py::::as_ref(&cache.0, py).call1((name.to_py_ast(py)?,))?; + + Ok(instance) + } +} + +impl ToPyAst for ast::TypeParamTypeVarTuple { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + range: _range, + } = self; + + let instance = Py::::as_ref(&cache.0, py).call1((name.to_py_ast(py)?,))?; + + Ok(instance) + } +} + impl ToPyAst for ast::Mod { #[inline] fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { @@ -2696,6 +2827,7 @@ impl ToPyAst for ast::Stmt { ast::Stmt::Return(cons) => cons.to_py_ast(py)?, ast::Stmt::Delete(cons) => cons.to_py_ast(py)?, ast::Stmt::Assign(cons) => cons.to_py_ast(py)?, + ast::Stmt::TypeAlias(cons) => cons.to_py_ast(py)?, ast::Stmt::AugAssign(cons) => cons.to_py_ast(py)?, ast::Stmt::AnnAssign(cons) => cons.to_py_ast(py)?, ast::Stmt::For(cons) => cons.to_py_ast(py)?, @@ -2734,6 +2866,7 @@ impl ToPyAst for ast::StmtFunctionDef { decorator_list, returns, type_comment, + type_params, range: _range, } = self; @@ -2744,6 +2877,7 @@ impl ToPyAst for ast::StmtFunctionDef { decorator_list.to_py_ast(py)?, returns.to_py_ast(py)?, type_comment.to_py_ast(py)?, + type_params.to_py_ast(py)?, ))?; let cache = ast_cache(); @@ -2770,6 +2904,7 @@ impl ToPyAst for ast::StmtAsyncFunctionDef { decorator_list, returns, type_comment, + type_params, range: _range, } = self; @@ -2780,6 +2915,7 @@ impl ToPyAst for ast::StmtAsyncFunctionDef { decorator_list.to_py_ast(py)?, returns.to_py_ast(py)?, type_comment.to_py_ast(py)?, + type_params.to_py_ast(py)?, ))?; let cache = ast_cache(); @@ -2805,6 +2941,7 @@ impl ToPyAst for ast::StmtClassDef { keywords, body, decorator_list, + type_params, range: _range, } = self; @@ -2814,6 +2951,7 @@ impl ToPyAst for ast::StmtClassDef { keywords.to_py_ast(py)?, body.to_py_ast(py)?, decorator_list.to_py_ast(py)?, + type_params.to_py_ast(py)?, ))?; let cache = ast_cache(); @@ -2906,6 +3044,36 @@ impl ToPyAst for ast::StmtAssign { } } +impl ToPyAst for ast::StmtTypeAlias { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + type_params, + value, + range: _range, + } = self; + + let instance = Py::::as_ref(&cache.0, py).call1(( + name.to_py_ast(py)?, + type_params.to_py_ast(py)?, + value.to_py_ast(py)?, + ))?; + + let cache = ast_cache(); + instance.setattr(cache.lineno.as_ref(py), _range.start.row.get())?; + instance.setattr(cache.col_offset.as_ref(py), _range.start.column.get())?; + if let Some(end) = _range.end { + instance.setattr(cache.end_lineno.as_ref(py), end.row.get())?; + instance.setattr(cache.end_col_offset.as_ref(py), end.column.get())?; + } + + Ok(instance) + } +} + impl ToPyAst for ast::StmtAugAssign { #[inline] fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { @@ -4717,6 +4885,92 @@ impl ToPyAst for ast::TypeIgnoreTypeIgnore { } } +impl ToPyAst for ast::TypeParam { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let instance = match &self { + ast::TypeParam::TypeVar(cons) => cons.to_py_ast(py)?, + ast::TypeParam::ParamSpec(cons) => cons.to_py_ast(py)?, + ast::TypeParam::TypeVarTuple(cons) => cons.to_py_ast(py)?, + }; + Ok(instance) + } +} + +impl ToPyAst for ast::TypeParamTypeVar { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + bound, + range: _range, + } = self; + + let instance = + Py::::as_ref(&cache.0, py).call1((name.to_py_ast(py)?, bound.to_py_ast(py)?))?; + + let cache = ast_cache(); + instance.setattr(cache.lineno.as_ref(py), _range.start.row.get())?; + instance.setattr(cache.col_offset.as_ref(py), _range.start.column.get())?; + if let Some(end) = _range.end { + instance.setattr(cache.end_lineno.as_ref(py), end.row.get())?; + instance.setattr(cache.end_col_offset.as_ref(py), end.column.get())?; + } + + Ok(instance) + } +} + +impl ToPyAst for ast::TypeParamParamSpec { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + range: _range, + } = self; + + let instance = Py::::as_ref(&cache.0, py).call1((name.to_py_ast(py)?,))?; + + let cache = ast_cache(); + instance.setattr(cache.lineno.as_ref(py), _range.start.row.get())?; + instance.setattr(cache.col_offset.as_ref(py), _range.start.column.get())?; + if let Some(end) = _range.end { + instance.setattr(cache.end_lineno.as_ref(py), end.row.get())?; + instance.setattr(cache.end_col_offset.as_ref(py), end.column.get())?; + } + + Ok(instance) + } +} + +impl ToPyAst for ast::TypeParamTypeVarTuple { + #[inline] + fn to_py_ast<'py>(&self, py: Python<'py>) -> PyResult<&'py PyAny> { + let cache = Self::py_type_cache().get().unwrap(); + + let Self { + name, + range: _range, + } = self; + + let instance = Py::::as_ref(&cache.0, py).call1((name.to_py_ast(py)?,))?; + + let cache = ast_cache(); + instance.setattr(cache.lineno.as_ref(py), _range.start.row.get())?; + instance.setattr(cache.col_offset.as_ref(py), _range.start.column.get())?; + if let Some(end) = _range.end { + instance.setattr(cache.end_lineno.as_ref(py), end.row.get())?; + instance.setattr(cache.end_col_offset.as_ref(py), end.column.get())?; + } + + Ok(instance) + } +} + fn init_types(py: Python) -> PyResult<()> { let ast_module = PyModule::import(py, "_ast")?; cache_py_type::(ast_module)?; @@ -4731,6 +4985,7 @@ fn init_types(py: Python) -> PyResult<()> { cache_py_type::(ast_module)?; cache_py_type::(ast_module)?; cache_py_type::(ast_module)?; + cache_py_type::(ast_module)?; cache_py_type::(ast_module)?; cache_py_type::(ast_module)?; cache_py_type::(ast_module)?; @@ -4837,5 +5092,9 @@ fn init_types(py: Python) -> PyResult<()> { cache_py_type::(ast_module)?; cache_py_type::(ast_module)?; cache_py_type::(ast_module)?; + cache_py_type::(ast_module)?; + cache_py_type::(ast_module)?; + cache_py_type::(ast_module)?; + cache_py_type::(ast_module)?; Ok(()) } diff --git a/ast-pyo3/src/gen/wrapper_located.rs b/ast-pyo3/src/gen/wrapper_located.rs index 0aebc63a..b6d56dd7 100644 --- a/ast-pyo3/src/gen/wrapper_located.rs +++ b/ast-pyo3/src/gen/wrapper_located.rs @@ -222,6 +222,7 @@ impl ToPyWrapper for ast::Stmt { Self::Return(cons) => cons.to_py_wrapper(py), Self::Delete(cons) => cons.to_py_wrapper(py), Self::Assign(cons) => cons.to_py_wrapper(py), + Self::TypeAlias(cons) => cons.to_py_wrapper(py), Self::AugAssign(cons) => cons.to_py_wrapper(py), Self::AnnAssign(cons) => cons.to_py_wrapper(py), Self::For(cons) => cons.to_py_wrapper(py), @@ -310,6 +311,12 @@ impl StmtFunctionDef { fn get_type_comment(&self, py: Python) -> PyResult { self.0.type_comment.to_py_wrapper(py) } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } } #[pyclass(module="rustpython_ast.located", name="_AsyncFunctionDef", extends=Stmt, frozen)] @@ -375,6 +382,12 @@ impl StmtAsyncFunctionDef { fn get_type_comment(&self, py: Python) -> PyResult { self.0.type_comment.to_py_wrapper(py) } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } } #[pyclass(module="rustpython_ast.located", name="_ClassDef", extends=Stmt, frozen)] @@ -434,6 +447,12 @@ impl StmtClassDef { fn get_decorator_list(&self, py: Python) -> PyResult { self.0.decorator_list.to_py_wrapper(py) } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } } #[pyclass(module="rustpython_ast.located", name="_Return", extends=Stmt, frozen)] @@ -553,6 +572,53 @@ impl StmtAssign { } } +#[pyclass(module="rustpython_ast.located", name="_TypeAlias", extends=Stmt, frozen)] +#[derive(Clone, Debug)] +pub struct StmtTypeAlias(pub &'static ast::StmtTypeAlias); + +impl From<&'static ast::StmtTypeAlias> for StmtTypeAlias { + fn from(node: &'static ast::StmtTypeAlias) -> Self { + StmtTypeAlias(node) + } +} + +impl ToPyObject for StmtTypeAlias { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(Stmt) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::StmtTypeAlias { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(StmtTypeAlias(self).to_object(py)) + } +} + +#[pymethods] +impl StmtTypeAlias { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } + + #[getter] + #[inline] + fn get_value(&self, py: Python) -> PyResult { + self.0.value.to_py_wrapper(py) + } +} + #[pyclass(module="rustpython_ast.located", name="_AugAssign", extends=Stmt, frozen)] #[derive(Clone, Debug)] pub struct StmtAugAssign(pub &'static ast::StmtAugAssign); @@ -3993,6 +4059,152 @@ impl TypeIgnoreTypeIgnore { } } +#[pyclass(module="rustpython_ast.located", name="_type_param", extends=super::Ast, frozen, subclass)] +#[derive(Clone, Debug)] +pub struct TypeParam; + +impl From<&'static ast::TypeParam> for TypeParam { + fn from(_node: &'static ast::TypeParam) -> Self { + TypeParam + } +} + +#[pymethods] +impl TypeParam { + #[new] + fn new() -> PyClassInitializer { + PyClassInitializer::from(Ast).add_subclass(Self) + } +} +impl ToPyObject for TypeParam { + fn to_object(&self, py: Python) -> PyObject { + let initializer = Self::new(); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParam { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + match &self { + Self::TypeVar(cons) => cons.to_py_wrapper(py), + Self::ParamSpec(cons) => cons.to_py_wrapper(py), + Self::TypeVarTuple(cons) => cons.to_py_wrapper(py), + } + } +} + +#[pyclass(module="rustpython_ast.located", name="_TypeVar", extends=TypeParam, frozen)] +#[derive(Clone, Debug)] +pub struct TypeParamTypeVar(pub &'static ast::TypeParamTypeVar); + +impl From<&'static ast::TypeParamTypeVar> for TypeParamTypeVar { + fn from(node: &'static ast::TypeParamTypeVar) -> Self { + TypeParamTypeVar(node) + } +} + +impl ToPyObject for TypeParamTypeVar { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(TypeParam) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParamTypeVar { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(TypeParamTypeVar(self).to_object(py)) + } +} + +#[pymethods] +impl TypeParamTypeVar { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } + + #[getter] + #[inline] + fn get_bound(&self, py: Python) -> PyResult { + self.0.bound.to_py_wrapper(py) + } +} + +#[pyclass(module="rustpython_ast.located", name="_ParamSpec", extends=TypeParam, frozen)] +#[derive(Clone, Debug)] +pub struct TypeParamParamSpec(pub &'static ast::TypeParamParamSpec); + +impl From<&'static ast::TypeParamParamSpec> for TypeParamParamSpec { + fn from(node: &'static ast::TypeParamParamSpec) -> Self { + TypeParamParamSpec(node) + } +} + +impl ToPyObject for TypeParamParamSpec { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(TypeParam) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParamParamSpec { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(TypeParamParamSpec(self).to_object(py)) + } +} + +#[pymethods] +impl TypeParamParamSpec { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } +} + +#[pyclass(module="rustpython_ast.located", name="_TypeVarTuple", extends=TypeParam, frozen)] +#[derive(Clone, Debug)] +pub struct TypeParamTypeVarTuple(pub &'static ast::TypeParamTypeVarTuple); + +impl From<&'static ast::TypeParamTypeVarTuple> for TypeParamTypeVarTuple { + fn from(node: &'static ast::TypeParamTypeVarTuple) -> Self { + TypeParamTypeVarTuple(node) + } +} + +impl ToPyObject for TypeParamTypeVarTuple { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(TypeParam) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParamTypeVarTuple { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(TypeParamTypeVarTuple(self).to_object(py)) + } +} + +#[pymethods] +impl TypeParamTypeVarTuple { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } +} + impl ToPyWrapper for ast::ExprContext { #[inline] fn to_py_wrapper(&self, py: Python) -> PyResult> { @@ -4303,6 +4515,7 @@ pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> { super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; + super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; @@ -4409,5 +4622,9 @@ pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> { super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; + super::init_type::(py, m)?; + super::init_type::(py, m)?; + super::init_type::(py, m)?; + super::init_type::(py, m)?; Ok(()) } diff --git a/ast-pyo3/src/gen/wrapper_ranged.rs b/ast-pyo3/src/gen/wrapper_ranged.rs index 8a405c2a..53416ad2 100644 --- a/ast-pyo3/src/gen/wrapper_ranged.rs +++ b/ast-pyo3/src/gen/wrapper_ranged.rs @@ -222,6 +222,7 @@ impl ToPyWrapper for ast::Stmt { Self::Return(cons) => cons.to_py_wrapper(py), Self::Delete(cons) => cons.to_py_wrapper(py), Self::Assign(cons) => cons.to_py_wrapper(py), + Self::TypeAlias(cons) => cons.to_py_wrapper(py), Self::AugAssign(cons) => cons.to_py_wrapper(py), Self::AnnAssign(cons) => cons.to_py_wrapper(py), Self::For(cons) => cons.to_py_wrapper(py), @@ -310,6 +311,12 @@ impl StmtFunctionDef { fn get_type_comment(&self, py: Python) -> PyResult { self.0.type_comment.to_py_wrapper(py) } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } } #[pyclass(module="rustpython_ast.ranged", name="_AsyncFunctionDef", extends=Stmt, frozen)] @@ -375,6 +382,12 @@ impl StmtAsyncFunctionDef { fn get_type_comment(&self, py: Python) -> PyResult { self.0.type_comment.to_py_wrapper(py) } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } } #[pyclass(module="rustpython_ast.ranged", name="_ClassDef", extends=Stmt, frozen)] @@ -434,6 +447,12 @@ impl StmtClassDef { fn get_decorator_list(&self, py: Python) -> PyResult { self.0.decorator_list.to_py_wrapper(py) } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } } #[pyclass(module="rustpython_ast.ranged", name="_Return", extends=Stmt, frozen)] @@ -553,6 +572,53 @@ impl StmtAssign { } } +#[pyclass(module="rustpython_ast.ranged", name="_TypeAlias", extends=Stmt, frozen)] +#[derive(Clone, Debug)] +pub struct StmtTypeAlias(pub &'static ast::StmtTypeAlias); + +impl From<&'static ast::StmtTypeAlias> for StmtTypeAlias { + fn from(node: &'static ast::StmtTypeAlias) -> Self { + StmtTypeAlias(node) + } +} + +impl ToPyObject for StmtTypeAlias { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(Stmt) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::StmtTypeAlias { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(StmtTypeAlias(self).to_object(py)) + } +} + +#[pymethods] +impl StmtTypeAlias { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } + + #[getter] + #[inline] + fn get_type_params(&self, py: Python) -> PyResult { + self.0.type_params.to_py_wrapper(py) + } + + #[getter] + #[inline] + fn get_value(&self, py: Python) -> PyResult { + self.0.value.to_py_wrapper(py) + } +} + #[pyclass(module="rustpython_ast.ranged", name="_AugAssign", extends=Stmt, frozen)] #[derive(Clone, Debug)] pub struct StmtAugAssign(pub &'static ast::StmtAugAssign); @@ -3993,6 +4059,152 @@ impl TypeIgnoreTypeIgnore { } } +#[pyclass(module="rustpython_ast.ranged", name="_type_param", extends=super::Ast, frozen, subclass)] +#[derive(Clone, Debug)] +pub struct TypeParam; + +impl From<&'static ast::TypeParam> for TypeParam { + fn from(_node: &'static ast::TypeParam) -> Self { + TypeParam + } +} + +#[pymethods] +impl TypeParam { + #[new] + fn new() -> PyClassInitializer { + PyClassInitializer::from(Ast).add_subclass(Self) + } +} +impl ToPyObject for TypeParam { + fn to_object(&self, py: Python) -> PyObject { + let initializer = Self::new(); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParam { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + match &self { + Self::TypeVar(cons) => cons.to_py_wrapper(py), + Self::ParamSpec(cons) => cons.to_py_wrapper(py), + Self::TypeVarTuple(cons) => cons.to_py_wrapper(py), + } + } +} + +#[pyclass(module="rustpython_ast.ranged", name="_TypeVar", extends=TypeParam, frozen)] +#[derive(Clone, Debug)] +pub struct TypeParamTypeVar(pub &'static ast::TypeParamTypeVar); + +impl From<&'static ast::TypeParamTypeVar> for TypeParamTypeVar { + fn from(node: &'static ast::TypeParamTypeVar) -> Self { + TypeParamTypeVar(node) + } +} + +impl ToPyObject for TypeParamTypeVar { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(TypeParam) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParamTypeVar { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(TypeParamTypeVar(self).to_object(py)) + } +} + +#[pymethods] +impl TypeParamTypeVar { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } + + #[getter] + #[inline] + fn get_bound(&self, py: Python) -> PyResult { + self.0.bound.to_py_wrapper(py) + } +} + +#[pyclass(module="rustpython_ast.ranged", name="_ParamSpec", extends=TypeParam, frozen)] +#[derive(Clone, Debug)] +pub struct TypeParamParamSpec(pub &'static ast::TypeParamParamSpec); + +impl From<&'static ast::TypeParamParamSpec> for TypeParamParamSpec { + fn from(node: &'static ast::TypeParamParamSpec) -> Self { + TypeParamParamSpec(node) + } +} + +impl ToPyObject for TypeParamParamSpec { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(TypeParam) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParamParamSpec { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(TypeParamParamSpec(self).to_object(py)) + } +} + +#[pymethods] +impl TypeParamParamSpec { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } +} + +#[pyclass(module="rustpython_ast.ranged", name="_TypeVarTuple", extends=TypeParam, frozen)] +#[derive(Clone, Debug)] +pub struct TypeParamTypeVarTuple(pub &'static ast::TypeParamTypeVarTuple); + +impl From<&'static ast::TypeParamTypeVarTuple> for TypeParamTypeVarTuple { + fn from(node: &'static ast::TypeParamTypeVarTuple) -> Self { + TypeParamTypeVarTuple(node) + } +} + +impl ToPyObject for TypeParamTypeVarTuple { + fn to_object(&self, py: Python) -> PyObject { + let initializer = PyClassInitializer::from(Ast) + .add_subclass(TypeParam) + .add_subclass(self.clone()); + Py::new(py, initializer).unwrap().into_py(py) + } +} + +impl ToPyWrapper for ast::TypeParamTypeVarTuple { + #[inline] + fn to_py_wrapper(&'static self, py: Python) -> PyResult> { + Ok(TypeParamTypeVarTuple(self).to_object(py)) + } +} + +#[pymethods] +impl TypeParamTypeVarTuple { + #[getter] + #[inline] + fn get_name(&self, py: Python) -> PyResult { + self.0.name.to_py_wrapper(py) + } +} + pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> { super::init_module(py, m)?; super::init_type::(py, m)?; @@ -4007,6 +4219,7 @@ pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> { super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; + super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; @@ -4113,5 +4326,9 @@ pub fn add_to_module(py: Python, m: &PyModule) -> PyResult<()> { super::init_type::(py, m)?; super::init_type::(py, m)?; super::init_type::(py, m)?; + super::init_type::(py, m)?; + super::init_type::(py, m)?; + super::init_type::(py, m)?; + super::init_type::(py, m)?; Ok(()) } diff --git a/ast/Python.asdl b/ast/Python.asdl index e9423a7c..0d154867 100644 --- a/ast/Python.asdl +++ b/ast/Python.asdl @@ -10,20 +10,22 @@ module Python stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, - string? type_comment) + string? type_comment, type_param* type_params) | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, - string? type_comment) + string? type_comment, type_param* type_params) | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, - expr* decorator_list) + expr* decorator_list, + type_param* type_params) | Return(expr? value) | Delete(expr* targets) | Assign(expr* targets, expr value, string? type_comment) + | TypeAlias(expr name, type_param* type_params, expr value) | AugAssign(expr target, operator op, expr value) -- 'simple' indicates that we annotate simple name without parens | AnnAssign(expr target, expr annotation, expr? value, int simple) @@ -142,4 +144,9 @@ module Python attributes (int lineno, int col_offset, int end_lineno, int end_col_offset) type_ignore = TypeIgnore(int lineno, string tag) + + type_param = TypeVar(identifier name, expr? bound) + | ParamSpec(identifier name) + | TypeVarTuple(identifier name) + attributes (int lineno, int col_offset, int end_lineno, int end_col_offset) } diff --git a/ast/src/gen/fold.rs b/ast/src/gen/fold.rs index 5fe48e90..b133b891 100644 --- a/ast/src/gen/fold.rs +++ b/ast/src/gen/fold.rs @@ -108,6 +108,12 @@ pub trait Fold { ) -> Result, Self::Error> { fold_stmt_assign(self, node) } + fn fold_stmt_type_alias( + &mut self, + node: StmtTypeAlias, + ) -> Result, Self::Error> { + fold_stmt_type_alias(self, node) + } fn fold_stmt_aug_assign( &mut self, node: StmtAugAssign, @@ -507,6 +513,30 @@ pub trait Fold { ) -> Result, Self::Error> { fold_type_ignore_type_ignore(self, node) } + fn fold_type_param( + &mut self, + node: TypeParam, + ) -> Result, Self::Error> { + fold_type_param(self, node) + } + fn fold_type_param_type_var( + &mut self, + node: TypeParamTypeVar, + ) -> Result, Self::Error> { + fold_type_param_type_var(self, node) + } + fn fold_type_param_param_spec( + &mut self, + node: TypeParamParamSpec, + ) -> Result, Self::Error> { + fold_type_param_param_spec(self, node) + } + fn fold_type_param_type_var_tuple( + &mut self, + node: TypeParamTypeVarTuple, + ) -> Result, Self::Error> { + fold_type_param_type_var_tuple(self, node) + } fn fold_arg_with_default( &mut self, node: ArgWithDefault, @@ -653,6 +683,7 @@ pub fn fold_stmt + ?Sized>( Stmt::Return(cons) => Stmt::Return(Foldable::fold(cons, folder)?), Stmt::Delete(cons) => Stmt::Delete(Foldable::fold(cons, folder)?), Stmt::Assign(cons) => Stmt::Assign(Foldable::fold(cons, folder)?), + Stmt::TypeAlias(cons) => Stmt::TypeAlias(Foldable::fold(cons, folder)?), Stmt::AugAssign(cons) => Stmt::AugAssign(Foldable::fold(cons, folder)?), Stmt::AnnAssign(cons) => Stmt::AnnAssign(Foldable::fold(cons, folder)?), Stmt::For(cons) => Stmt::For(Foldable::fold(cons, folder)?), @@ -697,6 +728,7 @@ pub fn fold_stmt_function_def + ?Sized>( decorator_list, returns, type_comment, + type_params, range, } = node; let context = folder.will_map_user(&range); @@ -707,6 +739,7 @@ pub fn fold_stmt_function_def + ?Sized>( let decorator_list = Foldable::fold(decorator_list, folder)?; let returns = Foldable::fold(returns, folder)?; let type_comment = Foldable::fold(type_comment, folder)?; + let type_params = Foldable::fold(type_params, folder)?; let range = folder.map_user(range, context)?; Ok(StmtFunctionDef { name, @@ -715,6 +748,7 @@ pub fn fold_stmt_function_def + ?Sized>( decorator_list, returns, type_comment, + type_params, range, }) } @@ -738,6 +772,7 @@ pub fn fold_stmt_async_function_def + ?Sized>( decorator_list, returns, type_comment, + type_params, range, } = node; let context = folder.will_map_user(&range); @@ -748,6 +783,7 @@ pub fn fold_stmt_async_function_def + ?Sized>( let decorator_list = Foldable::fold(decorator_list, folder)?; let returns = Foldable::fold(returns, folder)?; let type_comment = Foldable::fold(type_comment, folder)?; + let type_params = Foldable::fold(type_params, folder)?; let range = folder.map_user(range, context)?; Ok(StmtAsyncFunctionDef { name, @@ -756,6 +792,7 @@ pub fn fold_stmt_async_function_def + ?Sized>( decorator_list, returns, type_comment, + type_params, range, }) } @@ -778,6 +815,7 @@ pub fn fold_stmt_class_def + ?Sized>( keywords, body, decorator_list, + type_params, range, } = node; let context = folder.will_map_user(&range); @@ -787,6 +825,7 @@ pub fn fold_stmt_class_def + ?Sized>( let keywords = Foldable::fold(keywords, folder)?; let body = Foldable::fold(body, folder)?; let decorator_list = Foldable::fold(decorator_list, folder)?; + let type_params = Foldable::fold(type_params, folder)?; let range = folder.map_user(range, context)?; Ok(StmtClassDef { name, @@ -794,6 +833,7 @@ pub fn fold_stmt_class_def + ?Sized>( keywords, body, decorator_list, + type_params, range, }) } @@ -869,6 +909,38 @@ pub fn fold_stmt_assign + ?Sized>( range, }) } +impl Foldable for StmtTypeAlias { + type Mapped = StmtTypeAlias; + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { + folder.fold_stmt_type_alias(self) + } +} +pub fn fold_stmt_type_alias + ?Sized>( + #[allow(unused)] folder: &mut F, + node: StmtTypeAlias, +) -> Result, F::Error> { + let StmtTypeAlias { + name, + type_params, + value, + range, + } = node; + let context = folder.will_map_user(&range); + + let name = Foldable::fold(name, folder)?; + let type_params = Foldable::fold(type_params, folder)?; + let value = Foldable::fold(value, folder)?; + let range = folder.map_user(range, context)?; + Ok(StmtTypeAlias { + name, + type_params, + value, + range, + }) +} impl Foldable for StmtAugAssign { type Mapped = StmtAugAssign; fn fold + ?Sized>( @@ -2791,6 +2863,87 @@ pub fn fold_type_ignore_type_ignore + ?Sized>( let range = folder.map_user_cfg(range, context)?; Ok(TypeIgnoreTypeIgnore { lineno, tag, range }) } +impl Foldable for TypeParam { + type Mapped = TypeParam; + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { + folder.fold_type_param(self) + } +} +pub fn fold_type_param + ?Sized>( + #[allow(unused)] folder: &mut F, + node: TypeParam, +) -> Result, F::Error> { + let folded = match node { + TypeParam::TypeVar(cons) => TypeParam::TypeVar(Foldable::fold(cons, folder)?), + TypeParam::ParamSpec(cons) => TypeParam::ParamSpec(Foldable::fold(cons, folder)?), + TypeParam::TypeVarTuple(cons) => TypeParam::TypeVarTuple(Foldable::fold(cons, folder)?), + }; + Ok(folded) +} +impl Foldable for TypeParamTypeVar { + type Mapped = TypeParamTypeVar; + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { + folder.fold_type_param_type_var(self) + } +} +pub fn fold_type_param_type_var + ?Sized>( + #[allow(unused)] folder: &mut F, + node: TypeParamTypeVar, +) -> Result, F::Error> { + let TypeParamTypeVar { name, bound, range } = node; + let context = folder.will_map_user(&range); + + let name = Foldable::fold(name, folder)?; + let bound = Foldable::fold(bound, folder)?; + let range = folder.map_user(range, context)?; + Ok(TypeParamTypeVar { name, bound, range }) +} +impl Foldable for TypeParamParamSpec { + type Mapped = TypeParamParamSpec; + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { + folder.fold_type_param_param_spec(self) + } +} +pub fn fold_type_param_param_spec + ?Sized>( + #[allow(unused)] folder: &mut F, + node: TypeParamParamSpec, +) -> Result, F::Error> { + let TypeParamParamSpec { name, range } = node; + let context = folder.will_map_user(&range); + + let name = Foldable::fold(name, folder)?; + let range = folder.map_user(range, context)?; + Ok(TypeParamParamSpec { name, range }) +} +impl Foldable for TypeParamTypeVarTuple { + type Mapped = TypeParamTypeVarTuple; + fn fold + ?Sized>( + self, + folder: &mut F, + ) -> Result { + folder.fold_type_param_type_var_tuple(self) + } +} +pub fn fold_type_param_type_var_tuple + ?Sized>( + #[allow(unused)] folder: &mut F, + node: TypeParamTypeVarTuple, +) -> Result, F::Error> { + let TypeParamTypeVarTuple { name, range } = node; + let context = folder.will_map_user(&range); + + let name = Foldable::fold(name, folder)?; + let range = folder.map_user(range, context)?; + Ok(TypeParamTypeVarTuple { name, range }) +} impl Foldable for ArgWithDefault { type Mapped = ArgWithDefault; fn fold + ?Sized>( diff --git a/ast/src/gen/generic.rs b/ast/src/gen/generic.rs index 3b193ec2..5efe9c05 100644 --- a/ast/src/gen/generic.rs +++ b/ast/src/gen/generic.rs @@ -1,8 +1,7 @@ // File automatically generated by ast/asdl_rs.py. use crate::text_size::TextRange; -#[derive(Clone, Debug, PartialEq)] -#[derive(is_macro::Is)] +#[derive(Clone, Debug, PartialEq, is_macro::Is)] pub enum Ast { #[is(name = "module")] Mod(Mod), @@ -23,6 +22,7 @@ pub enum Ast { MatchCase(MatchCase), Pattern(Pattern), TypeIgnore(TypeIgnore), + TypeParam(TypeParam), } impl Node for Ast { const NAME: &'static str = "AST"; @@ -137,6 +137,12 @@ impl From> for Ast { } } +impl From> for Ast { + fn from(node: TypeParam) -> Self { + Ast::TypeParam(node) + } +} + /// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod) #[derive(Clone, Debug, PartialEq, is_macro::Is)] pub enum Mod { @@ -256,6 +262,8 @@ pub enum Stmt { Delete(StmtDelete), #[is(name = "assign_stmt")] Assign(StmtAssign), + #[is(name = "type_alias_stmt")] + TypeAlias(StmtTypeAlias), #[is(name = "aug_assign_stmt")] AugAssign(StmtAugAssign), #[is(name = "ann_assign_stmt")] @@ -310,6 +318,7 @@ pub struct StmtFunctionDef { pub decorator_list: Vec>, pub returns: Option>>, pub type_comment: Option, + pub type_params: Vec>, } impl Node for StmtFunctionDef { @@ -321,6 +330,7 @@ impl Node for StmtFunctionDef { "decorator_list", "returns", "type_comment", + "type_params", ]; } impl From> for Stmt { @@ -344,6 +354,7 @@ pub struct StmtAsyncFunctionDef { pub decorator_list: Vec>, pub returns: Option>>, pub type_comment: Option, + pub type_params: Vec>, } impl Node for StmtAsyncFunctionDef { @@ -355,6 +366,7 @@ impl Node for StmtAsyncFunctionDef { "decorator_list", "returns", "type_comment", + "type_params", ]; } impl From> for Stmt { @@ -377,12 +389,19 @@ pub struct StmtClassDef { pub keywords: Vec>, pub body: Vec>, pub decorator_list: Vec>, + pub type_params: Vec>, } impl Node for StmtClassDef { const NAME: &'static str = "ClassDef"; - const FIELD_NAMES: &'static [&'static str] = - &["name", "bases", "keywords", "body", "decorator_list"]; + const FIELD_NAMES: &'static [&'static str] = &[ + "name", + "bases", + "keywords", + "body", + "decorator_list", + "type_params", + ]; } impl From> for Stmt { fn from(payload: StmtClassDef) -> Self { @@ -463,6 +482,30 @@ impl From> for Ast { } } +/// See also [TypeAlias](https://docs.python.org/3/library/ast.html#ast.TypeAlias) +#[derive(Clone, Debug, PartialEq)] +pub struct StmtTypeAlias { + pub range: R, + pub name: Box>, + pub type_params: Vec>, + pub value: Box>, +} + +impl Node for StmtTypeAlias { + const NAME: &'static str = "TypeAlias"; + const FIELD_NAMES: &'static [&'static str] = &["name", "type_params", "value"]; +} +impl From> for Stmt { + fn from(payload: StmtTypeAlias) -> Self { + Stmt::TypeAlias(payload) + } +} +impl From> for Ast { + fn from(payload: StmtTypeAlias) -> Self { + Stmt::from(payload).into() + } +} + /// See also [AugAssign](https://docs.python.org/3/library/ast.html#ast.AugAssign) #[derive(Clone, Debug, PartialEq)] pub struct StmtAugAssign { @@ -3074,6 +3117,86 @@ impl Node for TypeIgnore { const FIELD_NAMES: &'static [&'static str] = &[]; } +/// See also [type_param](https://docs.python.org/3/library/ast.html#ast.type_param) +#[derive(Clone, Debug, PartialEq, is_macro::Is)] +pub enum TypeParam { + TypeVar(TypeParamTypeVar), + ParamSpec(TypeParamParamSpec), + TypeVarTuple(TypeParamTypeVarTuple), +} + +/// See also [TypeVar](https://docs.python.org/3/library/ast.html#ast.TypeVar) +#[derive(Clone, Debug, PartialEq)] +pub struct TypeParamTypeVar { + pub range: R, + pub name: Identifier, + pub bound: Option>>, +} + +impl Node for TypeParamTypeVar { + const NAME: &'static str = "TypeVar"; + const FIELD_NAMES: &'static [&'static str] = &["name", "bound"]; +} +impl From> for TypeParam { + fn from(payload: TypeParamTypeVar) -> Self { + TypeParam::TypeVar(payload) + } +} +impl From> for Ast { + fn from(payload: TypeParamTypeVar) -> Self { + TypeParam::from(payload).into() + } +} + +/// See also [ParamSpec](https://docs.python.org/3/library/ast.html#ast.ParamSpec) +#[derive(Clone, Debug, PartialEq)] +pub struct TypeParamParamSpec { + pub range: R, + pub name: Identifier, +} + +impl Node for TypeParamParamSpec { + const NAME: &'static str = "ParamSpec"; + const FIELD_NAMES: &'static [&'static str] = &["name"]; +} +impl From> for TypeParam { + fn from(payload: TypeParamParamSpec) -> Self { + TypeParam::ParamSpec(payload) + } +} +impl From> for Ast { + fn from(payload: TypeParamParamSpec) -> Self { + TypeParam::from(payload).into() + } +} + +/// See also [TypeVarTuple](https://docs.python.org/3/library/ast.html#ast.TypeVarTuple) +#[derive(Clone, Debug, PartialEq)] +pub struct TypeParamTypeVarTuple { + pub range: R, + pub name: Identifier, +} + +impl Node for TypeParamTypeVarTuple { + const NAME: &'static str = "TypeVarTuple"; + const FIELD_NAMES: &'static [&'static str] = &["name"]; +} +impl From> for TypeParam { + fn from(payload: TypeParamTypeVarTuple) -> Self { + TypeParam::TypeVarTuple(payload) + } +} +impl From> for Ast { + fn from(payload: TypeParamTypeVarTuple) -> Self { + TypeParam::from(payload).into() + } +} + +impl Node for TypeParam { + const NAME: &'static str = "type_param"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + /// An alternative type of AST `arguments`. This is parser-friendly and human-friendly definition of function arguments. /// This form also has advantage to implement pre-order traverse. /// `defaults` and `kw_defaults` fields are removed and the default values are placed under each `arg_with_default` typed argument. diff --git a/ast/src/gen/located.rs b/ast/src/gen/located.rs index 63a7b474..7376652f 100644 --- a/ast/src/gen/located.rs +++ b/ast/src/gen/located.rs @@ -171,6 +171,20 @@ impl LocatedMut for StmtAssign { } } +pub type StmtTypeAlias = crate::generic::StmtTypeAlias; + +impl Located for StmtTypeAlias { + fn range(&self) -> SourceRange { + self.range + } +} + +impl LocatedMut for StmtTypeAlias { + fn range_mut(&mut self) -> &mut SourceRange { + &mut self.range + } +} + pub type StmtAugAssign = crate::generic::StmtAugAssign; impl Located for StmtAugAssign { @@ -474,6 +488,7 @@ impl Located for Stmt { Self::Return(node) => node.range(), Self::Delete(node) => node.range(), Self::Assign(node) => node.range(), + Self::TypeAlias(node) => node.range(), Self::AugAssign(node) => node.range(), Self::AnnAssign(node) => node.range(), Self::For(node) => node.range(), @@ -508,6 +523,7 @@ impl LocatedMut for Stmt { Self::Return(node) => node.range_mut(), Self::Delete(node) => node.range_mut(), Self::Assign(node) => node.range_mut(), + Self::TypeAlias(node) => node.range_mut(), Self::AugAssign(node) => node.range_mut(), Self::AnnAssign(node) => node.range_mut(), Self::For(node) => node.range_mut(), @@ -1367,6 +1383,70 @@ impl LocatedMut for TypeIgnore { } } +pub type TypeParam = crate::generic::TypeParam; + +pub type TypeParamTypeVar = crate::generic::TypeParamTypeVar; + +impl Located for TypeParamTypeVar { + fn range(&self) -> SourceRange { + self.range + } +} + +impl LocatedMut for TypeParamTypeVar { + fn range_mut(&mut self) -> &mut SourceRange { + &mut self.range + } +} + +pub type TypeParamParamSpec = crate::generic::TypeParamParamSpec; + +impl Located for TypeParamParamSpec { + fn range(&self) -> SourceRange { + self.range + } +} + +impl LocatedMut for TypeParamParamSpec { + fn range_mut(&mut self) -> &mut SourceRange { + &mut self.range + } +} + +pub type TypeParamTypeVarTuple = crate::generic::TypeParamTypeVarTuple; + +impl Located for TypeParamTypeVarTuple { + fn range(&self) -> SourceRange { + self.range + } +} + +impl LocatedMut for TypeParamTypeVarTuple { + fn range_mut(&mut self) -> &mut SourceRange { + &mut self.range + } +} + +impl Located for TypeParam { + fn range(&self) -> SourceRange { + match self { + Self::TypeVar(node) => node.range(), + Self::ParamSpec(node) => node.range(), + Self::TypeVarTuple(node) => node.range(), + } + } +} + +impl LocatedMut for TypeParam { + fn range_mut(&mut self) -> &mut SourceRange { + match self { + Self::TypeVar(node) => node.range_mut(), + Self::ParamSpec(node) => node.range_mut(), + Self::TypeVarTuple(node) => node.range_mut(), + } + } +} + pub type Arguments = crate::generic::Arguments; #[cfg(feature = "all-nodes-with-ranges")] diff --git a/ast/src/gen/ranged.rs b/ast/src/gen/ranged.rs index c6a2ea35..5d48ff3d 100644 --- a/ast/src/gen/ranged.rs +++ b/ast/src/gen/ranged.rs @@ -66,6 +66,11 @@ impl Ranged for crate::generic::StmtAssign { self.range } } +impl Ranged for crate::generic::StmtTypeAlias { + fn range(&self) -> TextRange { + self.range + } +} impl Ranged for crate::generic::StmtAugAssign { fn range(&self) -> TextRange { self.range @@ -180,6 +185,7 @@ impl Ranged for crate::Stmt { Self::Return(node) => node.range(), Self::Delete(node) => node.range(), Self::Assign(node) => node.range(), + Self::TypeAlias(node) => node.range(), Self::AugAssign(node) => node.range(), Self::AnnAssign(node) => node.range(), Self::For(node) => node.range(), @@ -496,6 +502,31 @@ impl Ranged for crate::TypeIgnore { } } +impl Ranged for crate::generic::TypeParamTypeVar { + fn range(&self) -> TextRange { + self.range + } +} +impl Ranged for crate::generic::TypeParamParamSpec { + fn range(&self) -> TextRange { + self.range + } +} +impl Ranged for crate::generic::TypeParamTypeVarTuple { + fn range(&self) -> TextRange { + self.range + } +} +impl Ranged for crate::TypeParam { + fn range(&self) -> TextRange { + match self { + Self::TypeVar(node) => node.range(), + Self::ParamSpec(node) => node.range(), + Self::TypeVarTuple(node) => node.range(), + } + } +} + #[cfg(feature = "all-nodes-with-ranges")] impl Ranged for crate::generic::Arguments { fn range(&self) -> TextRange { diff --git a/ast/src/gen/visitor.rs b/ast/src/gen/visitor.rs index af5fcabe..d84e5423 100644 --- a/ast/src/gen/visitor.rs +++ b/ast/src/gen/visitor.rs @@ -13,6 +13,7 @@ pub trait Visitor { Stmt::Return(data) => self.visit_stmt_return(data), Stmt::Delete(data) => self.visit_stmt_delete(data), Stmt::Assign(data) => self.visit_stmt_assign(data), + Stmt::TypeAlias(data) => self.visit_stmt_type_alias(data), Stmt::AugAssign(data) => self.visit_stmt_aug_assign(data), Stmt::AnnAssign(data) => self.visit_stmt_ann_assign(data), Stmt::For(data) => self.visit_stmt_for(data), @@ -53,6 +54,9 @@ pub trait Visitor { if let Some(value) = node.returns { self.visit_expr(*value); } + for value in node.type_params { + self.visit_type_param(value); + } } fn visit_stmt_async_function_def(&mut self, node: StmtAsyncFunctionDef) { self.generic_visit_stmt_async_function_def(node) @@ -71,6 +75,9 @@ pub trait Visitor { if let Some(value) = node.returns { self.visit_expr(*value); } + for value in node.type_params { + self.visit_type_param(value); + } } fn visit_stmt_class_def(&mut self, node: StmtClassDef) { self.generic_visit_stmt_class_def(node) @@ -88,6 +95,9 @@ pub trait Visitor { for value in node.decorator_list { self.visit_expr(value); } + for value in node.type_params { + self.visit_type_param(value); + } } fn visit_stmt_return(&mut self, node: StmtReturn) { self.generic_visit_stmt_return(node) @@ -117,6 +127,22 @@ pub trait Visitor { self.visit_expr(*value); } } + fn visit_stmt_type_alias(&mut self, node: StmtTypeAlias) { + self.generic_visit_stmt_type_alias(node) + } + fn generic_visit_stmt_type_alias(&mut self, node: StmtTypeAlias) { + { + let value = node.name; + self.visit_expr(*value); + } + for value in node.type_params { + self.visit_type_param(value); + } + { + let value = node.value; + self.visit_expr(*value); + } + } fn visit_stmt_aug_assign(&mut self, node: StmtAugAssign) { self.generic_visit_stmt_aug_assign(node) } @@ -810,4 +836,30 @@ pub trait Visitor { self.visit_pattern(value); } } + fn visit_type_param(&mut self, node: TypeParam) { + self.generic_visit_type_param(node) + } + fn generic_visit_type_param(&mut self, node: TypeParam) { + match node { + TypeParam::TypeVar(data) => self.visit_type_param_type_var(data), + TypeParam::ParamSpec(data) => self.visit_type_param_param_spec(data), + TypeParam::TypeVarTuple(data) => self.visit_type_param_type_var_tuple(data), + } + } + fn visit_type_param_type_var(&mut self, node: TypeParamTypeVar) { + self.generic_visit_type_param_type_var(node) + } + fn generic_visit_type_param_type_var(&mut self, node: TypeParamTypeVar) { + if let Some(value) = node.bound { + self.visit_expr(*value); + } + } + fn visit_type_param_param_spec(&mut self, node: TypeParamParamSpec) { + self.generic_visit_type_param_param_spec(node) + } + fn generic_visit_type_param_param_spec(&mut self, node: TypeParamParamSpec) {} + fn visit_type_param_type_var_tuple(&mut self, node: TypeParamTypeVarTuple) { + self.generic_visit_type_param_type_var_tuple(node) + } + fn generic_visit_type_param_type_var_tuple(&mut self, node: TypeParamTypeVarTuple) {} } diff --git a/ast/src/impls.rs b/ast/src/impls.rs index 3c267e85..594fadb3 100644 --- a/ast/src/impls.rs +++ b/ast/src/impls.rs @@ -57,7 +57,7 @@ impl Expr { #[cfg(target_arch = "x86_64")] static_assertions::assert_eq_size!(crate::Expr, [u8; 72]); #[cfg(target_arch = "x86_64")] -static_assertions::assert_eq_size!(crate::Stmt, [u8; 136]); +static_assertions::assert_eq_size!(crate::Stmt, [u8; 160]); #[cfg(target_arch = "x86_64")] static_assertions::assert_eq_size!(crate::Pattern, [u8; 96]); #[cfg(target_arch = "x86_64")] diff --git a/ast/src/source_locator.rs b/ast/src/source_locator.rs index 366c32bb..c0a0f22e 100644 --- a/ast/src/source_locator.rs +++ b/ast/src/source_locator.rs @@ -149,6 +149,7 @@ impl crate::fold::Fold for LinearLocator<'_> { keywords, body, decorator_list, + type_params, range, } = node; let decorator_list = self.fold(decorator_list)?; @@ -159,12 +160,15 @@ impl crate::fold::Fold for LinearLocator<'_> { let keywords = self.fold(keywords)?; let body = self.fold(body)?; let range = self.map_user(range, context)?; + let type_params = self.fold(type_params)?; + Ok(crate::StmtClassDef { name, bases, keywords, body, decorator_list, + type_params, range, }) } @@ -180,6 +184,7 @@ impl crate::fold::Fold for LinearLocator<'_> { returns, type_comment, range, + type_params, } = node; let decorator_list = self.fold(decorator_list)?; let context = self.will_map_user(&range); @@ -189,6 +194,7 @@ impl crate::fold::Fold for LinearLocator<'_> { let returns = self.fold(returns)?; let body = self.fold(body)?; let type_comment = self.fold(type_comment)?; + let type_params = self.fold(type_params)?; let range = self.map_user(range, context)?; Ok(crate::StmtFunctionDef { name, @@ -196,6 +202,7 @@ impl crate::fold::Fold for LinearLocator<'_> { body, decorator_list, returns, + type_params, type_comment, range, }) @@ -211,6 +218,7 @@ impl crate::fold::Fold for LinearLocator<'_> { decorator_list, returns, type_comment, + type_params, range, } = node; let decorator_list = self.fold(decorator_list)?; @@ -221,6 +229,7 @@ impl crate::fold::Fold for LinearLocator<'_> { let returns = self.fold(returns)?; let body = self.fold(body)?; let type_comment = self.fold(type_comment)?; + let type_params = self.fold(type_params)?; let range = self.map_user(range, context)?; Ok(crate::StmtAsyncFunctionDef { name, @@ -229,6 +238,7 @@ impl crate::fold::Fold for LinearLocator<'_> { decorator_list, returns, type_comment, + type_params, range, }) } diff --git a/parser/src/gen/parse.rs b/parser/src/gen/parse.rs index 01856ac2..64822875 100644 --- a/parser/src/gen/parse.rs +++ b/parser/src/gen/parse.rs @@ -138,6 +138,29 @@ impl Parse for ast::StmtAssign { } } +impl Parse for ast::StmtTypeAlias { + fn lex_starts_at( + source: &str, + offset: TextSize, + ) -> SoftKeywordTransformer> { + ast::Stmt::lex_starts_at(source, offset) + } + fn parse_tokens( + lxr: impl IntoIterator, + source_path: &str, + ) -> Result { + let node = ast::Stmt::parse_tokens(lxr, source_path)?; + match node { + ast::Stmt::TypeAlias(node) => Ok(node), + node => Err(ParseError { + error: ParseErrorType::InvalidToken, + offset: node.range().start(), + source_path: source_path.to_owned(), + }), + } + } +} + impl Parse for ast::StmtAugAssign { fn lex_starts_at( source: &str, diff --git a/parser/src/python.lalrpop b/parser/src/python.lalrpop index 272cf97e..b6e823dc 100644 --- a/parser/src/python.lalrpop +++ b/parser/src/python.lalrpop @@ -970,10 +970,11 @@ FuncDef: ast::Stmt = { let returns = r.map(|x| Box::new(x)); let end_location = body.last().unwrap().end(); let type_comment = None; + let type_params = Vec::new(); if is_async.is_some() { - ast::StmtAsyncFunctionDef { name, args, body, decorator_list, returns, type_comment, range: (location..end_location).into() }.into() + ast::StmtAsyncFunctionDef { name, args, body, decorator_list, returns, type_comment, type_params, range: (location..end_location).into() }.into() } else { - ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment, range: (location..end_location).into() }.into() + ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment, type_params, range: (location..end_location).into() }.into() } }, }; @@ -1131,6 +1132,7 @@ ClassDef: ast::Stmt = { None => (vec![], vec![]), }; let end_location = body.last().unwrap().end(); + let type_params = Vec::new(); ast::Stmt::ClassDef( ast::StmtClassDef { name, @@ -1138,6 +1140,7 @@ ClassDef: ast::Stmt = { keywords, body, decorator_list, + type_params, range: (location..end_location).into() }, ) diff --git a/parser/src/python.rs b/parser/src/python.rs index a0b29e80..f5f9f7be 100644 --- a/parser/src/python.rs +++ b/parser/src/python.rs @@ -1,5 +1,5 @@ // auto-generated: "lalrpop 0.20.0" -// sha3: c39f9711066c6f94aaf93d62d86b41efb4242ddcdcbe5b9d35e5a77a14ff22d6 +// sha3: 63c75be3af99ad823887ab5407feb1d091c0c150fc7ec64c257b95becfbbe6be use crate::{ ast::{self as ast, Ranged, bigint::BigInt}, lexer::{LexicalError, LexicalErrorType}, @@ -31068,10 +31068,11 @@ fn __action157< let returns = r.map(|x| Box::new(x)); let end_location = body.last().unwrap().end(); let type_comment = None; + let type_params = Vec::new(); if is_async.is_some() { - ast::StmtAsyncFunctionDef { name, args, body, decorator_list, returns, type_comment, range: (location..end_location).into() }.into() + ast::StmtAsyncFunctionDef { name, args, body, decorator_list, returns, type_comment, type_params, range: (location..end_location).into() }.into() } else { - ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment, range: (location..end_location).into() }.into() + ast::StmtFunctionDef { name, args, body, decorator_list, returns, type_comment, type_params, range: (location..end_location).into() }.into() } } } @@ -31184,6 +31185,7 @@ fn __action164< None => (vec![], vec![]), }; let end_location = body.last().unwrap().end(); + let type_params = Vec::new(); ast::Stmt::ClassDef( ast::StmtClassDef { name, @@ -31191,6 +31193,7 @@ fn __action164< keywords, body, decorator_list, + type_params, range: (location..end_location).into() }, ) diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args.snap index d13ceb57..e43df55d 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args.snap @@ -65,6 +65,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args_with_defaults.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args_with_defaults.snap index a228709a..fd75fc37 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args_with_defaults.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_kw_only_args_with_defaults.snap @@ -85,6 +85,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_no_args.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_no_args.snap index fa56b395..8619f078 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_no_args.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_no_args.snap @@ -28,6 +28,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args.snap index 9ca2f2a5..8fbf8b95 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args.snap @@ -102,6 +102,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults.snap index af889e4d..47a53831 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults.snap @@ -122,6 +122,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs.snap index ae32c655..69ac86b6 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs.snap @@ -131,6 +131,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs_and_kwargs.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs_and_kwargs.snap index 213589fa..ab96ed62 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs_and_kwargs.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_and_kw_only_args_with_defaults_and_varargs_and_kwargs.snap @@ -140,6 +140,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args.snap index e5515e2a..78481775 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args.snap @@ -65,6 +65,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args_with_defaults.snap b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args_with_defaults.snap index 0c91d69e..aa873314 100644 --- a/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args_with_defaults.snap +++ b/parser/src/snapshots/rustpython_parser__function__tests__function_pos_args_with_defaults.snap @@ -85,6 +85,7 @@ Ok( decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], diff --git a/parser/src/snapshots/rustpython_parser__parser__tests__parse_class.snap b/parser/src/snapshots/rustpython_parser__parser__tests__parse_class.snap index c27d250f..457673c1 100644 --- a/parser/src/snapshots/rustpython_parser__parser__tests__parse_class.snap +++ b/parser/src/snapshots/rustpython_parser__parser__tests__parse_class.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -expression: "parse_program(source, \"\").unwrap()" +expression: "ast::Suite::parse(source, \"\").unwrap()" --- [ ClassDef( @@ -68,6 +68,7 @@ expression: "parse_program(source, \"\").unwrap()" decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), FunctionDef( @@ -129,10 +130,12 @@ expression: "parse_program(source, \"\").unwrap()" decorator_list: [], returns: None, type_comment: None, + type_params: [], }, ), ], decorator_list: [], + type_params: [], }, ), ] diff --git a/parser/src/snapshots/rustpython_parser__parser__tests__variadic_generics.snap b/parser/src/snapshots/rustpython_parser__parser__tests__variadic_generics.snap index 8590915a..9a10e289 100644 --- a/parser/src/snapshots/rustpython_parser__parser__tests__variadic_generics.snap +++ b/parser/src/snapshots/rustpython_parser__parser__tests__variadic_generics.snap @@ -90,6 +90,7 @@ expression: parse_ast ), ), type_comment: None, + type_params: [], }, ), ]