Implement iter(), len() and is_empty() for all display-literal AST nodes (#12807)

This commit is contained in:
Alex Waygood 2024-08-12 11:39:28 +01:00 committed by GitHub
parent a99a45868c
commit aa0db338d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
56 changed files with 304 additions and 240 deletions

View file

@ -582,8 +582,8 @@ pub const fn is_singleton(expr: &Expr) -> bool {
/// Return `true` if the [`Expr`] is a literal or tuple of literals.
pub fn is_constant(expr: &Expr) -> bool {
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = expr {
elts.iter().all(is_constant)
if let Expr::Tuple(tuple) = expr {
tuple.iter().all(is_constant)
} else {
expr.is_literal_expr()
}
@ -630,8 +630,8 @@ pub fn extract_handled_exceptions(handlers: &[ExceptHandler]) -> Vec<&Expr> {
match handler {
ExceptHandler::ExceptHandler(ast::ExceptHandlerExceptHandler { type_, .. }) => {
if let Some(type_) = type_ {
if let Expr::Tuple(ast::ExprTuple { elts, .. }) = &type_.as_ref() {
for type_ in elts {
if let Expr::Tuple(tuple) = &**type_ {
for type_ in tuple {
handled_exceptions.push(type_);
}
} else {
@ -1185,8 +1185,8 @@ impl Truthiness {
Self::Truthy
}
}
Expr::Dict(ast::ExprDict { items, .. }) => {
if items.is_empty() {
Expr::Dict(dict) => {
if dict.is_empty() {
Self::Falsey
} else {
Self::Truthy

View file

@ -856,6 +856,27 @@ impl ExprDict {
pub fn value(&self, n: usize) -> &Expr {
self.items[n].value()
}
pub fn iter(&self) -> std::slice::Iter<'_, DictItem> {
self.items.iter()
}
pub fn len(&self) -> usize {
self.items.len()
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
}
impl<'a> IntoIterator for &'a ExprDict {
type IntoIter = std::slice::Iter<'a, DictItem>;
type Item = &'a DictItem;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl From<ExprDict> for Expr {
@ -955,6 +976,29 @@ pub struct ExprSet {
pub elts: Vec<Expr>,
}
impl ExprSet {
pub fn iter(&self) -> std::slice::Iter<'_, Expr> {
self.elts.iter()
}
pub fn len(&self) -> usize {
self.elts.len()
}
pub fn is_empty(&self) -> bool {
self.elts.is_empty()
}
}
impl<'a> IntoIterator for &'a ExprSet {
type IntoIter = std::slice::Iter<'a, Expr>;
type Item = &'a Expr;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl From<ExprSet> for Expr {
fn from(payload: ExprSet) -> Self {
Expr::Set(payload)
@ -2759,6 +2803,29 @@ pub struct ExprList {
pub ctx: ExprContext,
}
impl ExprList {
pub fn iter(&self) -> std::slice::Iter<'_, Expr> {
self.elts.iter()
}
pub fn len(&self) -> usize {
self.elts.len()
}
pub fn is_empty(&self) -> bool {
self.elts.is_empty()
}
}
impl<'a> IntoIterator for &'a ExprList {
type IntoIter = std::slice::Iter<'a, Expr>;
type Item = &'a Expr;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl From<ExprList> for Expr {
fn from(payload: ExprList) -> Self {
Expr::List(payload)
@ -2776,6 +2843,29 @@ pub struct ExprTuple {
pub parenthesized: bool,
}
impl ExprTuple {
pub fn iter(&self) -> std::slice::Iter<'_, Expr> {
self.elts.iter()
}
pub fn len(&self) -> usize {
self.elts.len()
}
pub fn is_empty(&self) -> bool {
self.elts.is_empty()
}
}
impl<'a> IntoIterator for &'a ExprTuple {
type IntoIter = std::slice::Iter<'a, Expr>;
type Item = &'a Expr;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl From<ExprTuple> for Expr {
fn from(payload: ExprTuple) -> Self {
Expr::Tuple(payload)