mirror of
https://github.com/github/codeql.git
synced 2026-05-14 19:29:28 +02:00
Python: merge T*AstNode wrappers into matching public classes
Five of the six per-newtype-branch wrapper classes had a natural public class corresponding to that branch: TStmtAstNode -> Stmt (TStmt subset; BlockStmt overrides for TBlockStmt) TExprAstNode -> Expr (TExpr subset; BoolExprPair overrides for TBoolExprPair) TScopeAstNode -> Callable (= TScope exactly) TPatternAstNode -> Pattern (= TPattern exactly) TBlockStmtAstNode -> BlockStmt (= TBlockStmt exactly) Move toString/getLocation/getEnclosingCallable onto these classes and delete the wrappers. The sixth wrapper (TBoolExprPair) has no exact public counterpart - BinaryExpr is broader, including TExpr-branch BoolExprs - so it remains as a small private class, renamed BoolExprPair. 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>
This commit is contained in:
@@ -105,64 +105,12 @@ module Ast implements AstSig<Py::Location> {
|
||||
AstNode getChild(int index) { none() }
|
||||
}
|
||||
|
||||
/** Implementation of `AstNode` predicates for `TStmt` nodes. */
|
||||
private class TStmtAstNode extends AstNode, TStmt {
|
||||
private Py::Stmt s;
|
||||
|
||||
TStmtAstNode() { this = TStmt(s) }
|
||||
|
||||
override string toString() { result = s.toString() }
|
||||
|
||||
override Py::Location getLocation() { result = s.getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = s.getScope() }
|
||||
}
|
||||
|
||||
/** Implementation of `AstNode` predicates for `TExpr` nodes. */
|
||||
private class TExprAstNode extends AstNode, TExpr {
|
||||
private Py::Expr e;
|
||||
|
||||
TExprAstNode() { this = TExpr(e) }
|
||||
|
||||
override string toString() { result = e.toString() }
|
||||
|
||||
override Py::Location getLocation() { result = e.getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = e.getScope() }
|
||||
}
|
||||
|
||||
/** Implementation of `AstNode` predicates for `TScope` nodes. */
|
||||
private class TScopeAstNode extends AstNode, TScope {
|
||||
private Py::Scope sc;
|
||||
|
||||
TScopeAstNode() { this = TScope(sc) }
|
||||
|
||||
override string toString() { result = sc.toString() }
|
||||
|
||||
override Py::Location getLocation() { result = sc.getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = sc.getEnclosingScope() }
|
||||
}
|
||||
|
||||
/** Implementation of `AstNode` predicates for `TPattern` nodes. */
|
||||
private class TPatternAstNode extends AstNode, TPattern {
|
||||
private Py::Pattern p;
|
||||
|
||||
TPatternAstNode() { this = TPattern(p) }
|
||||
|
||||
override string toString() { result = p.toString() }
|
||||
|
||||
override Py::Location getLocation() { result = p.getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = p.getScope() }
|
||||
}
|
||||
|
||||
/** Implementation of `AstNode` predicates for synthetic `TBoolExprPair` nodes. */
|
||||
private class TBoolExprPairAstNode extends AstNode, TBoolExprPair {
|
||||
private class BoolExprPair extends Expr, TBoolExprPair {
|
||||
private Py::BoolExpr be;
|
||||
private int index;
|
||||
|
||||
TBoolExprPairAstNode() { this = TBoolExprPair(be, index) }
|
||||
BoolExprPair() { this = TBoolExprPair(be, index) }
|
||||
|
||||
override string toString() { result = be.getOperator() }
|
||||
|
||||
@@ -171,28 +119,6 @@ module Ast implements AstSig<Py::Location> {
|
||||
override Callable getEnclosingCallable() { result.asScope() = be.getScope() }
|
||||
}
|
||||
|
||||
/** Implementation of `AstNode` predicates for synthetic `TBlockStmt` nodes. */
|
||||
private class TBlockStmtAstNode extends AstNode, TBlockStmt {
|
||||
private Py::AstNode parent;
|
||||
private string slot;
|
||||
|
||||
TBlockStmtAstNode() { this = TBlockStmt(parent, slot) }
|
||||
|
||||
override string toString() { result = "block:" + slot }
|
||||
|
||||
// BlockStmt has no native location; approximate with the first
|
||||
// item's location.
|
||||
override Py::Location getLocation() {
|
||||
result = getBodyStmtList(parent, slot).getItem(0).getLocation()
|
||||
}
|
||||
|
||||
override Callable getEnclosingCallable() {
|
||||
result.asScope() = parent.(Py::Scope)
|
||||
or
|
||||
result.asScope() = parent.(Py::Stmt).getScope()
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets the immediately enclosing callable that contains `node`. */
|
||||
Callable getEnclosingCallable(AstNode node) { result = node.getEnclosingCallable() }
|
||||
|
||||
@@ -201,7 +127,17 @@ module Ast implements AstSig<Py::Location> {
|
||||
*
|
||||
* In Python, all three are executable scopes with statement bodies.
|
||||
*/
|
||||
class Callable extends AstNode, TScope { }
|
||||
class Callable extends AstNode, TScope {
|
||||
private Py::Scope sc;
|
||||
|
||||
Callable() { this = TScope(sc) }
|
||||
|
||||
override string toString() { result = sc.toString() }
|
||||
|
||||
override Py::Location getLocation() { result = sc.getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = sc.getEnclosingScope() }
|
||||
}
|
||||
|
||||
/** Gets the body of callable `c`. */
|
||||
AstNode callableGetBody(Callable c) { result = TBlockStmt(c.asScope(), "body") }
|
||||
@@ -223,15 +159,41 @@ module Ast implements AstSig<Py::Location> {
|
||||
/** A statement. */
|
||||
class Stmt extends AstNode {
|
||||
Stmt() { this instanceof TStmt or this instanceof TBlockStmt }
|
||||
|
||||
// For `TStmt` instances, delegate to the wrapped Python statement.
|
||||
// `BlockStmt` (the only `TBlockStmt` subclass) provides its own overrides.
|
||||
override string toString() { result = this.asStmt().toString() }
|
||||
|
||||
override Py::Location getLocation() { result = this.asStmt().getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = this.asStmt().getScope() }
|
||||
}
|
||||
|
||||
/** An expression. */
|
||||
class Expr extends AstNode {
|
||||
Expr() { this instanceof TExpr or this instanceof TBoolExprPair }
|
||||
|
||||
// For `TExpr` instances, delegate to the wrapped Python expression.
|
||||
// `BoolExprPair` (the only `TBoolExprPair` subclass) provides its own overrides.
|
||||
override string toString() { result = this.asExpr().toString() }
|
||||
|
||||
override Py::Location getLocation() { result = this.asExpr().getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = this.asExpr().getScope() }
|
||||
}
|
||||
|
||||
/** A pattern in a `match` statement. */
|
||||
additional class Pattern extends AstNode, TPattern { }
|
||||
additional class Pattern extends AstNode, TPattern {
|
||||
private Py::Pattern p;
|
||||
|
||||
Pattern() { this = TPattern(p) }
|
||||
|
||||
override string toString() { result = p.toString() }
|
||||
|
||||
override Py::Location getLocation() { result = p.getLocation() }
|
||||
|
||||
override Callable getEnclosingCallable() { result.asScope() = p.getScope() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A block statement, modeling the body of a parent AST node as a
|
||||
@@ -249,6 +211,20 @@ module Ast implements AstSig<Py::Location> {
|
||||
/** Gets the last statement in this block. */
|
||||
Stmt getLastStmt() { result = TStmt(getBodyStmtList(parent, slot).getLastItem()) }
|
||||
|
||||
override string toString() { result = "block:" + slot }
|
||||
|
||||
// BlockStmt has no native location; approximate with the first
|
||||
// item's location.
|
||||
override Py::Location getLocation() {
|
||||
result = getBodyStmtList(parent, slot).getItem(0).getLocation()
|
||||
}
|
||||
|
||||
override Callable getEnclosingCallable() {
|
||||
result.asScope() = parent.(Py::Scope)
|
||||
or
|
||||
result.asScope() = parent.(Py::Stmt).getScope()
|
||||
}
|
||||
|
||||
override AstNode getChild(int index) { result = this.getStmt(index) }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user