mirror of
https://github.com/github/codeql.git
synced 2026-05-14 19:29:28 +02:00
Previously a Py::BoolExpr appeared in two newtype branches: as TExpr(be) (the outermost pair) and TBoolExprPair(be, i) for inner pairs of 3+ operand expressions. This forced BinaryExpr/LogicalAndExpr/LogicalOrExpr to disjoin two cases, and the synthetic-pair handling spanned multiple layers. Restrict TExpr to non-BoolExpr Py::Expr, and extend TBoolExprPair to cover every operand pair (index 0..n-2). Now every Py::BoolExpr is represented uniformly as TBoolExprPair(_, 0) for the whole expression and TBoolExprPair(_, i) for inner pairs. Extend AstNode.asExpr() to also recover the underlying Py::BoolExpr from TBoolExprPair(_, 0). This makes asExpr() the inverse of construction: every 'result = TExpr(e)' turns into 'result.asExpr() = e', which works uniformly for BoolExprs and non-BoolExprs alike. Consequences: - BinaryExpr now extends TBoolExprPair directly with a single uniform rule for left/right operands. - LogicalAndExpr/LogicalOrExpr are one-line char preds via getBoolExpr(). - The private BoolExprPair wrapper class folds into BinaryExpr. - 60+ leaf wrappers now read 'result.asExpr() = py_expr' instead of 'result = TExpr(py_expr)'. No behaviour change: all 24 NewCfg evaluation-order tests pass; all 11 shared-CFG consistency queries report 0 violations on CPython. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>