Add a TypeParams node to the AST (#6261)

## Summary

Similar to #6259, this PR adds a `TypeParams` node to the AST, to
capture the list of type parameters with their surrounding brackets.

If a statement lacks type parameters, the `type_params` field will be
`None`.
This commit is contained in:
Charlie Marsh 2023-08-02 10:12:45 -04:00 committed by GitHub
parent 981e64f82b
commit b095b7204b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 1104 additions and 866 deletions

View file

@ -969,7 +969,7 @@ pub struct StmtFunctionDef<'a> {
parameters: ComparableParameters<'a>,
body: Vec<ComparableStmt<'a>>,
decorator_list: Vec<ComparableDecorator<'a>>,
type_params: Vec<ComparableTypeParam<'a>>,
type_params: Option<ComparableTypeParams<'a>>,
returns: Option<ComparableExpr<'a>>,
}
@ -979,7 +979,7 @@ pub struct StmtAsyncFunctionDef<'a> {
parameters: ComparableParameters<'a>,
body: Vec<ComparableStmt<'a>>,
decorator_list: Vec<ComparableDecorator<'a>>,
type_params: Vec<ComparableTypeParam<'a>>,
type_params: Option<ComparableTypeParams<'a>>,
returns: Option<ComparableExpr<'a>>,
}
@ -989,7 +989,7 @@ pub struct StmtClassDef<'a> {
arguments: Option<ComparableArguments<'a>>,
body: Vec<ComparableStmt<'a>>,
decorator_list: Vec<ComparableDecorator<'a>>,
type_params: Vec<ComparableTypeParam<'a>>,
type_params: Option<ComparableTypeParams<'a>>,
}
#[derive(Debug, PartialEq, Eq, Hash)]
@ -1005,10 +1005,23 @@ pub struct StmtDelete<'a> {
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct StmtTypeAlias<'a> {
pub name: Box<ComparableExpr<'a>>,
pub type_params: Vec<ComparableTypeParam<'a>>,
pub type_params: Option<ComparableTypeParams<'a>>,
pub value: Box<ComparableExpr<'a>>,
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct ComparableTypeParams<'a> {
pub type_params: Vec<ComparableTypeParam<'a>>,
}
impl<'a> From<&'a ast::TypeParams> for ComparableTypeParams<'a> {
fn from(type_params: &'a ast::TypeParams) -> Self {
Self {
type_params: type_params.iter().map(Into::into).collect(),
}
}
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub enum ComparableTypeParam<'a> {
TypeVar(TypeParamTypeVar<'a>),
@ -1237,7 +1250,7 @@ impl<'a> From<&'a ast::Stmt> for ComparableStmt<'a> {
body: body.iter().map(Into::into).collect(),
decorator_list: decorator_list.iter().map(Into::into).collect(),
returns: returns.as_ref().map(Into::into),
type_params: type_params.iter().map(Into::into).collect(),
type_params: type_params.as_ref().map(Into::into),
}),
ast::Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef {
name,
@ -1253,7 +1266,7 @@ impl<'a> From<&'a ast::Stmt> for ComparableStmt<'a> {
body: body.iter().map(Into::into).collect(),
decorator_list: decorator_list.iter().map(Into::into).collect(),
returns: returns.as_ref().map(Into::into),
type_params: type_params.iter().map(Into::into).collect(),
type_params: type_params.as_ref().map(Into::into),
}),
ast::Stmt::ClassDef(ast::StmtClassDef {
name,
@ -1267,7 +1280,7 @@ impl<'a> From<&'a ast::Stmt> for ComparableStmt<'a> {
arguments: arguments.as_ref().map(Into::into),
body: body.iter().map(Into::into).collect(),
decorator_list: decorator_list.iter().map(Into::into).collect(),
type_params: type_params.iter().map(Into::into).collect(),
type_params: type_params.as_ref().map(Into::into),
}),
ast::Stmt::Return(ast::StmtReturn {
value,
@ -1288,7 +1301,7 @@ impl<'a> From<&'a ast::Stmt> for ComparableStmt<'a> {
value,
}) => Self::TypeAlias(StmtTypeAlias {
name: name.into(),
type_params: type_params.iter().map(Into::into).collect(),
type_params: type_params.as_ref().map(Into::into),
value: value.into(),
}),
ast::Stmt::Assign(ast::StmtAssign {

View file

@ -1,16 +1,17 @@
use std::borrow::Cow;
use std::path::Path;
use num_traits::Zero;
use smallvec::SmallVec;
use ruff_text_size::TextRange;
use crate::call_path::CallPath;
use crate::statement_visitor::{walk_body, walk_stmt, StatementVisitor};
use crate::{
self as ast, Arguments, Constant, ExceptHandler, Expr, Keyword, MatchCase, Parameters, Pattern,
Ranged, Stmt, TypeParam,
};
use num_traits::Zero;
use ruff_text_size::TextRange;
use smallvec::SmallVec;
use crate::call_path::CallPath;
use crate::statement_visitor::{walk_body, walk_stmt, StatementVisitor};
/// Return `true` if the `Stmt` is a compound statement (as opposed to a simple statement).
pub const fn is_compound_statement(stmt: &Stmt) -> bool {
@ -346,6 +347,7 @@ where
match stmt {
Stmt::FunctionDef(ast::StmtFunctionDef {
parameters,
type_params,
body,
decorator_list,
returns,
@ -353,6 +355,7 @@ where
})
| Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef {
parameters,
type_params,
body,
decorator_list,
returns,
@ -385,6 +388,11 @@ where
.as_ref()
.is_some_and(|expr| any_over_expr(expr, func))
})
|| type_params.as_ref().is_some_and(|type_params| {
type_params
.iter()
.any(|type_param| any_over_type_param(type_param, func))
})
|| body.iter().any(|stmt| any_over_stmt(stmt, func))
|| decorator_list
.iter()
@ -395,6 +403,7 @@ where
}
Stmt::ClassDef(ast::StmtClassDef {
arguments,
type_params,
body,
decorator_list,
..
@ -407,6 +416,11 @@ where
.iter()
.any(|keyword| any_over_expr(&keyword.value, func))
})
|| type_params.as_ref().is_some_and(|type_params| {
type_params
.iter()
.any(|type_param| any_over_type_param(type_param, func))
})
|| body.iter().any(|stmt| any_over_stmt(stmt, func))
|| decorator_list
.iter()
@ -429,9 +443,11 @@ where
..
}) => {
any_over_expr(name, func)
|| type_params
.iter()
.any(|type_param| any_over_type_param(type_param, func))
|| type_params.as_ref().is_some_and(|type_params| {
type_params
.iter()
.any(|type_param| any_over_type_param(type_param, func))
})
|| any_over_expr(value, func)
}
Stmt::Assign(ast::StmtAssign { targets, value, .. }) => {
@ -1271,13 +1287,13 @@ mod tests {
use std::cell::RefCell;
use std::vec;
use crate::{
Constant, Expr, ExprConstant, ExprContext, ExprName, Identifier, Stmt, StmtTypeAlias,
TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple,
};
use ruff_text_size::TextRange;
use crate::helpers::{any_over_stmt, any_over_type_param, resolve_imported_module_path};
use crate::{
Constant, Expr, ExprConstant, ExprContext, ExprName, Identifier, Stmt, StmtTypeAlias,
TypeParam, TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams,
};
#[test]
fn resolve_import() {
@ -1351,7 +1367,10 @@ mod tests {
});
let type_alias = Stmt::TypeAlias(StmtTypeAlias {
name: Box::new(name.clone()),
type_params: vec![type_var_one, type_var_two],
type_params: Some(TypeParams {
type_params: vec![type_var_one, type_var_two],
range: TextRange::default(),
}),
value: Box::new(constant_three.clone()),
range: TextRange::default(),
});

View file

@ -1,7 +1,7 @@
use crate::{
self as ast, Alias, Arguments, Comprehension, Decorator, ExceptHandler, Expr, Keyword,
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, WithItem,
TypeParamParamSpec, TypeParamTypeVar, TypeParamTypeVarTuple, TypeParams, WithItem,
};
use ruff_text_size::TextRange;
use std::ptr::NonNull;
@ -100,9 +100,10 @@ pub enum AnyNode {
MatchCase(MatchCase),
Decorator(Decorator),
ElifElseClause(ast::ElifElseClause),
TypeParamTypeVar(ast::TypeParamTypeVar),
TypeParamTypeVarTuple(ast::TypeParamTypeVarTuple),
TypeParamParamSpec(ast::TypeParamParamSpec),
TypeParams(TypeParams),
TypeParamTypeVar(TypeParamTypeVar),
TypeParamTypeVarTuple(TypeParamTypeVarTuple),
TypeParamParamSpec(TypeParamParamSpec),
}
impl AnyNode {
@ -187,6 +188,7 @@ impl AnyNode {
| AnyNode::WithItem(_)
| AnyNode::MatchCase(_)
| AnyNode::Decorator(_)
| AnyNode::TypeParams(_)
| AnyNode::TypeParamTypeVar(_)
| AnyNode::TypeParamTypeVarTuple(_)
| AnyNode::TypeParamParamSpec(_)
@ -275,6 +277,7 @@ impl AnyNode {
| AnyNode::WithItem(_)
| AnyNode::MatchCase(_)
| AnyNode::Decorator(_)
| AnyNode::TypeParams(_)
| AnyNode::TypeParamTypeVar(_)
| AnyNode::TypeParamTypeVarTuple(_)
| AnyNode::TypeParamParamSpec(_)
@ -363,6 +366,7 @@ impl AnyNode {
| AnyNode::WithItem(_)
| AnyNode::MatchCase(_)
| AnyNode::Decorator(_)
| AnyNode::TypeParams(_)
| AnyNode::TypeParamTypeVar(_)
| AnyNode::TypeParamTypeVarTuple(_)
| AnyNode::TypeParamParamSpec(_)
@ -451,6 +455,7 @@ impl AnyNode {
| AnyNode::WithItem(_)
| AnyNode::MatchCase(_)
| AnyNode::Decorator(_)
| AnyNode::TypeParams(_)
| AnyNode::TypeParamTypeVar(_)
| AnyNode::TypeParamTypeVarTuple(_)
| AnyNode::TypeParamParamSpec(_)
@ -539,6 +544,7 @@ impl AnyNode {
| AnyNode::WithItem(_)
| AnyNode::MatchCase(_)
| AnyNode::Decorator(_)
| AnyNode::TypeParams(_)
| AnyNode::TypeParamTypeVar(_)
| AnyNode::TypeParamTypeVarTuple(_)
| AnyNode::TypeParamParamSpec(_)
@ -646,6 +652,7 @@ impl AnyNode {
Self::WithItem(node) => AnyNodeRef::WithItem(node),
Self::MatchCase(node) => AnyNodeRef::MatchCase(node),
Self::Decorator(node) => AnyNodeRef::Decorator(node),
Self::TypeParams(node) => AnyNodeRef::TypeParams(node),
Self::TypeParamTypeVar(node) => AnyNodeRef::TypeParamTypeVar(node),
Self::TypeParamTypeVarTuple(node) => AnyNodeRef::TypeParamTypeVarTuple(node),
Self::TypeParamParamSpec(node) => AnyNodeRef::TypeParamParamSpec(node),
@ -3590,6 +3597,7 @@ impl Ranged for AnyNode {
AnyNode::WithItem(node) => node.range(),
AnyNode::MatchCase(node) => node.range(),
AnyNode::Decorator(node) => node.range(),
AnyNode::TypeParams(node) => node.range(),
AnyNode::TypeParamTypeVar(node) => node.range(),
AnyNode::TypeParamTypeVarTuple(node) => node.range(),
AnyNode::TypeParamParamSpec(node) => node.range(),
@ -3678,9 +3686,10 @@ pub enum AnyNodeRef<'a> {
WithItem(&'a WithItem),
MatchCase(&'a MatchCase),
Decorator(&'a Decorator),
TypeParamTypeVar(&'a ast::TypeParamTypeVar),
TypeParamTypeVarTuple(&'a ast::TypeParamTypeVarTuple),
TypeParamParamSpec(&'a ast::TypeParamParamSpec),
TypeParams(&'a TypeParams),
TypeParamTypeVar(&'a TypeParamTypeVar),
TypeParamTypeVarTuple(&'a TypeParamTypeVarTuple),
TypeParamParamSpec(&'a TypeParamParamSpec),
ElifElseClause(&'a ast::ElifElseClause),
}
@ -3765,6 +3774,7 @@ impl AnyNodeRef<'_> {
AnyNodeRef::WithItem(node) => NonNull::from(*node).cast(),
AnyNodeRef::MatchCase(node) => NonNull::from(*node).cast(),
AnyNodeRef::Decorator(node) => NonNull::from(*node).cast(),
AnyNodeRef::TypeParams(node) => NonNull::from(*node).cast(),
AnyNodeRef::TypeParamTypeVar(node) => NonNull::from(*node).cast(),
AnyNodeRef::TypeParamTypeVarTuple(node) => NonNull::from(*node).cast(),
AnyNodeRef::TypeParamParamSpec(node) => NonNull::from(*node).cast(),
@ -3858,6 +3868,7 @@ impl AnyNodeRef<'_> {
AnyNodeRef::WithItem(_) => NodeKind::WithItem,
AnyNodeRef::MatchCase(_) => NodeKind::MatchCase,
AnyNodeRef::Decorator(_) => NodeKind::Decorator,
AnyNodeRef::TypeParams(_) => NodeKind::TypeParams,
AnyNodeRef::TypeParamTypeVar(_) => NodeKind::TypeParamTypeVar,
AnyNodeRef::TypeParamTypeVarTuple(_) => NodeKind::TypeParamTypeVarTuple,
AnyNodeRef::TypeParamParamSpec(_) => NodeKind::TypeParamParamSpec,
@ -3946,6 +3957,7 @@ impl AnyNodeRef<'_> {
| AnyNodeRef::WithItem(_)
| AnyNodeRef::MatchCase(_)
| AnyNodeRef::Decorator(_)
| AnyNodeRef::TypeParams(_)
| AnyNodeRef::TypeParamTypeVar(_)
| AnyNodeRef::TypeParamTypeVarTuple(_)
| AnyNodeRef::TypeParamParamSpec(_)
@ -4034,6 +4046,7 @@ impl AnyNodeRef<'_> {
| AnyNodeRef::WithItem(_)
| AnyNodeRef::MatchCase(_)
| AnyNodeRef::Decorator(_)
| AnyNodeRef::TypeParams(_)
| AnyNodeRef::TypeParamTypeVar(_)
| AnyNodeRef::TypeParamTypeVarTuple(_)
| AnyNodeRef::TypeParamParamSpec(_)
@ -4121,6 +4134,7 @@ impl AnyNodeRef<'_> {
| AnyNodeRef::WithItem(_)
| AnyNodeRef::MatchCase(_)
| AnyNodeRef::Decorator(_)
| AnyNodeRef::TypeParams(_)
| AnyNodeRef::TypeParamTypeVar(_)
| AnyNodeRef::TypeParamTypeVarTuple(_)
| AnyNodeRef::TypeParamParamSpec(_)
@ -4209,6 +4223,7 @@ impl AnyNodeRef<'_> {
| AnyNodeRef::WithItem(_)
| AnyNodeRef::MatchCase(_)
| AnyNodeRef::Decorator(_)
| AnyNodeRef::TypeParams(_)
| AnyNodeRef::TypeParamTypeVar(_)
| AnyNodeRef::TypeParamTypeVarTuple(_)
| AnyNodeRef::TypeParamParamSpec(_)
@ -4297,6 +4312,7 @@ impl AnyNodeRef<'_> {
| AnyNodeRef::WithItem(_)
| AnyNodeRef::MatchCase(_)
| AnyNodeRef::Decorator(_)
| AnyNodeRef::TypeParams(_)
| AnyNodeRef::TypeParamTypeVar(_)
| AnyNodeRef::TypeParamTypeVarTuple(_)
| AnyNodeRef::TypeParamParamSpec(_)
@ -5011,6 +5027,7 @@ impl Ranged for AnyNodeRef<'_> {
AnyNodeRef::MatchCase(node) => node.range(),
AnyNodeRef::Decorator(node) => node.range(),
AnyNodeRef::ElifElseClause(node) => node.range(),
AnyNodeRef::TypeParams(node) => node.range(),
AnyNodeRef::TypeParamTypeVar(node) => node.range(),
AnyNodeRef::TypeParamTypeVarTuple(node) => node.range(),
AnyNodeRef::TypeParamParamSpec(node) => node.range(),
@ -5102,6 +5119,7 @@ pub enum NodeKind {
MatchCase,
Decorator,
ElifElseClause,
TypeParams,
TypeParamTypeVar,
TypeParamTypeVarTuple,
TypeParamParamSpec,

View file

@ -5,6 +5,7 @@ use num_bigint::BigInt;
use ruff_text_size::{TextRange, TextSize};
use std::fmt;
use std::fmt::Debug;
use std::ops::Deref;
/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
#[derive(Clone, Debug, PartialEq, is_macro::Is)]
@ -121,12 +122,12 @@ impl From<StmtLineMagic> for Stmt {
#[derive(Clone, Debug, PartialEq)]
pub struct StmtFunctionDef {
pub range: TextRange,
pub name: Identifier,
pub parameters: Box<Parameters>,
pub body: Vec<Stmt>,
pub decorator_list: Vec<Decorator>,
pub name: Identifier,
pub type_params: Option<TypeParams>,
pub parameters: Box<Parameters>,
pub returns: Option<Box<Expr>>,
pub type_params: Vec<TypeParam>,
pub body: Vec<Stmt>,
}
impl From<StmtFunctionDef> for Stmt {
@ -139,12 +140,12 @@ impl From<StmtFunctionDef> for Stmt {
#[derive(Clone, Debug, PartialEq)]
pub struct StmtAsyncFunctionDef {
pub range: TextRange,
pub name: Identifier,
pub parameters: Box<Parameters>,
pub body: Vec<Stmt>,
pub decorator_list: Vec<Decorator>,
pub name: Identifier,
pub type_params: Option<TypeParams>,
pub parameters: Box<Parameters>,
pub returns: Option<Box<Expr>>,
pub type_params: Vec<TypeParam>,
pub body: Vec<Stmt>,
}
impl From<StmtAsyncFunctionDef> for Stmt {
@ -157,11 +158,11 @@ impl From<StmtAsyncFunctionDef> for Stmt {
#[derive(Clone, Debug, PartialEq)]
pub struct StmtClassDef {
pub range: TextRange,
pub decorator_list: Vec<Decorator>,
pub name: Identifier,
pub type_params: Option<TypeParams>,
pub arguments: Option<Arguments>,
pub body: Vec<Stmt>,
pub type_params: Vec<TypeParam>,
pub decorator_list: Vec<Decorator>,
}
impl StmtClassDef {
@ -221,7 +222,7 @@ impl From<StmtDelete> for Stmt {
pub struct StmtTypeAlias {
pub range: TextRange,
pub name: Box<Expr>,
pub type_params: Vec<TypeParam>,
pub type_params: Option<TypeParams>,
pub value: Box<Expr>,
}
@ -2120,6 +2121,29 @@ pub struct Arguments {
pub keywords: Vec<Keyword>,
}
/// An AST node used to represent a sequence of type parameters.
///
/// For example, given:
/// ```python
/// class C[T, U, V]: ...
/// ```
/// The `TypeParams` node would span from the left to right brackets (inclusive), and contain
/// the `T`, `U`, and `V` type parameters in the order they appear in the source code.
#[derive(Clone, Debug, PartialEq)]
pub struct TypeParams {
pub range: TextRange,
pub type_params: Vec<TypeParam>,
}
impl Deref for TypeParams {
type Target = [TypeParam];
fn deref(&self) -> &Self::Target {
&self.type_params
}
}
pub type Suite = Vec<Stmt>;
impl CmpOp {
@ -2952,6 +2976,11 @@ impl Ranged for crate::Pattern {
}
}
impl Ranged for crate::nodes::TypeParams {
fn range(&self) -> TextRange {
self.range
}
}
impl Ranged for crate::nodes::TypeParamTypeVar {
fn range(&self) -> TextRange {
self.range
@ -3003,9 +3032,9 @@ mod size_assertions {
use super::*;
use static_assertions::assert_eq_size;
assert_eq_size!(Stmt, [u8; 176]);
assert_eq_size!(StmtFunctionDef, [u8; 128]);
assert_eq_size!(StmtClassDef, [u8; 168]);
assert_eq_size!(Stmt, [u8; 184]);
assert_eq_size!(StmtFunctionDef, [u8; 136]);
assert_eq_size!(StmtClassDef, [u8; 176]);
assert_eq_size!(StmtTry, [u8; 104]);
assert_eq_size!(Expr, [u8; 80]);
assert_eq_size!(Constant, [u8; 32]);

View file

@ -5,7 +5,7 @@ pub mod preorder;
use crate::{
self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause,
ExceptHandler, Expr, ExprContext, Keyword, MatchCase, Operator, Parameter, Parameters, Pattern,
Stmt, TypeParam, TypeParamTypeVar, UnaryOp, WithItem,
Stmt, TypeParam, TypeParamTypeVar, TypeParams, UnaryOp, WithItem,
};
/// A trait for AST visitors. Visits all nodes in the AST recursively in evaluation-order.
@ -70,6 +70,9 @@ pub trait Visitor<'a> {
fn visit_with_item(&mut self, with_item: &'a WithItem) {
walk_with_item(self, with_item);
}
fn visit_type_params(&mut self, type_params: &'a TypeParams) {
walk_type_params(self, type_params);
}
fn visit_type_param(&mut self, type_param: &'a TypeParam) {
walk_type_param(self, type_param);
}
@ -116,8 +119,8 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
for decorator in decorator_list {
visitor.visit_decorator(decorator);
}
for type_param in type_params {
visitor.visit_type_param(type_param);
if let Some(type_params) = type_params {
visitor.visit_type_params(type_params);
}
visitor.visit_parameters(parameters);
for expr in returns {
@ -136,8 +139,8 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
for decorator in decorator_list {
visitor.visit_decorator(decorator);
}
for type_param in type_params {
visitor.visit_type_param(type_param);
if let Some(type_params) = type_params {
visitor.visit_type_params(type_params);
}
visitor.visit_parameters(parameters);
for expr in returns {
@ -155,8 +158,8 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
for decorator in decorator_list {
visitor.visit_decorator(decorator);
}
for type_param in type_params {
visitor.visit_type_param(type_param);
if let Some(type_params) = type_params {
visitor.visit_type_params(type_params);
}
if let Some(arguments) = arguments {
visitor.visit_arguments(arguments);
@ -186,8 +189,8 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
value,
}) => {
visitor.visit_expr(value);
for type_param in type_params {
visitor.visit_type_param(type_param);
if let Some(type_params) = type_params {
visitor.visit_type_params(type_params);
}
visitor.visit_expr(name);
}
@ -699,6 +702,12 @@ pub fn walk_with_item<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, with_item: &
}
}
pub fn walk_type_params<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, type_params: &'a TypeParams) {
for type_param in &type_params.type_params {
visitor.visit_type_param(type_param);
}
}
pub fn walk_type_param<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, type_param: &'a TypeParam) {
match type_param {
TypeParam::TypeVar(TypeParamTypeVar {

View file

@ -1,8 +1,8 @@
use crate::{
self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Constant, Decorator,
ElifElseClause, ExceptHandler, Expr, Keyword, MatchCase, Mod, Operator, Parameter,
ParameterWithDefault, Parameters, Pattern, Stmt, TypeParam, TypeParamTypeVar, UnaryOp,
WithItem,
ParameterWithDefault, Parameters, Pattern, Stmt, TypeParam, TypeParamTypeVar, TypeParams,
UnaryOp, WithItem,
};
/// Visitor that traverses all nodes recursively in pre-order.
@ -85,6 +85,10 @@ pub trait PreorderVisitor<'a> {
walk_with_item(self, with_item);
}
fn visit_type_params(&mut self, type_params: &'a TypeParams) {
walk_type_params(self, type_params);
}
fn visit_type_param(&mut self, type_param: &'a TypeParam) {
walk_type_param(self, type_param);
}
@ -157,8 +161,8 @@ where
visitor.visit_decorator(decorator);
}
for type_param in type_params {
visitor.visit_type_param(type_param);
if let Some(type_params) = type_params {
visitor.visit_type_params(type_params);
}
visitor.visit_parameters(parameters);
@ -181,8 +185,8 @@ where
visitor.visit_decorator(decorator);
}
for type_param in type_params {
visitor.visit_type_param(type_param);
if let Some(type_params) = type_params {
visitor.visit_type_params(type_params);
}
if let Some(arguments) = arguments {
@ -217,8 +221,8 @@ where
value,
}) => {
visitor.visit_expr(name);
for type_param in type_params {
visitor.visit_type_param(type_param);
if let Some(type_params) = type_params {
visitor.visit_type_params(type_params);
}
visitor.visit_expr(value);
}
@ -817,6 +821,15 @@ where
}
}
pub fn walk_type_params<'a, V>(visitor: &mut V, type_params: &'a TypeParams)
where
V: PreorderVisitor<'a> + ?Sized,
{
for type_param in &type_params.type_params {
visitor.visit_type_param(type_param);
}
}
pub fn walk_type_param<'a, V>(visitor: &mut V, type_param: &'a TypeParam)
where
V: PreorderVisitor<'a> + ?Sized,