///|
/// Expression tree analysis helpers.
///|
fn expr_has_await(expr : Expr) -> Bool {
match expr {
Expr::Await(_) => true
Expr::List(items) | Expr::Tuple(items) | Expr::Set(items) => {
let mut found = false
for item in items {
if expr_has_await(item) {
found = true
break
}
}
found
}
Expr::Dict(items) => {
let mut found = false
for pair in items {
if expr_has_await(pair.0) || expr_has_await(pair.1) {
found = true
break
}
}
found
}
Expr::ListComp(elt~, clauses~, filters~)
| Expr::GenExp(elt~, clauses~, filters~)
| Expr::SetComp(elt~, clauses~, filters~) => {
let mut found = expr_has_await(elt)
if !found {
for clause in clauses {
if expr_has_await(clause.iter) {
found = true
break
}
}
}
if !found {
for filter in filters {
if expr_has_await(filter) {
found = true
break
}
}
}
found
}
Expr::DictComp(key~, value~, clauses~, filters~) => {
let mut found = expr_has_await(key) || expr_has_await(value)
if !found {
for clause in clauses {
if expr_has_await(clause.iter) {
found = true
break
}
}
}
if !found {
for filter in filters {
if expr_has_await(filter) {
found = true
break
}
}
}
found
}
Expr::IfExpr(condition~, then_expr~, else_expr~) =>
expr_has_await(condition) ||
expr_has_await(then_expr) ||
expr_has_await(else_expr)
Expr::NamedExpr(name~, value~) => {
let _ = name
expr_has_await(value)
}
Expr::Yield(expr_opt) =>
match expr_opt {
Some(value) => expr_has_await(value)
None => false
}
Expr::YieldFrom(value) => expr_has_await(value)
Expr::Slice(start~, end~, step~) => {
let mut found = false
match start {
Some(value) => found = expr_has_await(value)
None => ()
}
if !found {
match end {
Some(value) => found = expr_has_await(value)
None => ()
}
}
if !found {
match step {
Some(value) => found = expr_has_await(value)
None => ()
}
}
found
}
Expr::Attribute(value~, attr~) => {
let _ = attr
expr_has_await(value)
}
Expr::Subscript(value~, index~) =>
expr_has_await(value) || expr_has_await(index)
Expr::Starred(value~) | Expr::DoubleStarred(value~) => expr_has_await(value)
Expr::Unary(op~, expr~) => {
let _ = op
expr_has_await(expr)
}
Expr::Binary(op~, left~, right~) => {
let _ = op
expr_has_await(left) || expr_has_await(right)
}
Expr::BoolOp(op~, values~) => {
let _ = op
let mut found = false
for value in values {
if expr_has_await(value) {
found = true
break
}
}
found
}
Expr::Compare(left~, ops~, comparators~) => {
let _ = ops
let mut found = expr_has_await(left)
if !found {
for value in comparators {
if expr_has_await(value) {
found = true
break
}
}
}
found
}
Expr::Call(callee~, args~) => {
let mut found = expr_has_await(callee)
if !found {
for arg in args {
if expr_has_await(arg) {
found = true
break
}
}
}
found
}
Expr::Keyword(name~, value~) => {
let _ = name
expr_has_await(value)
}
Expr::Lambda(params~, defaults~, body~) => {
let _ = params
let mut found = false
for default_value in defaults {
if expr_has_await(default_value) {
found = true
break
}
}
if found {
true
} else {
expr_has_await(body)
}
}
Expr::WithSpan(span~, expr~) => {
let _ = span
expr_has_await(expr)
}
_ => false
}
}