Merge pull request #17816 from hvitved/rust/expr-trees-module

Rust: Move all expression CFG trees inside an `ExprTrees` module
This commit is contained in:
Tom Hvitved
2024-10-21 15:12:51 +02:00
committed by GitHub
2 changed files with 393 additions and 385 deletions

View File

@@ -65,148 +65,6 @@ private module CfgImpl =
import CfgImpl
class ArrayExprTree extends StandardPostOrderTree, ArrayExpr {
override AstNode getChildNode(int i) { result = this.getExpr(i) }
}
class AsmExprTree extends LeafTree instanceof AsmExpr { }
class AwaitExprTree extends StandardPostOrderTree instanceof AwaitExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
// NOTE: `become` is a reserved but unused keyword.
class BecomeExprTree extends StandardPostOrderTree instanceof BecomeExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryExpr {
BinaryOpExprTree() { not this instanceof BinaryLogicalOperation }
override AstNode getChildNode(int i) {
i = 0 and result = super.getLhs()
or
i = 1 and result = super.getRhs()
}
}
class LogicalOrTree extends PostOrderTree, LogicalOrExpr {
final override predicate propagatesAbnormal(AstNode child) { child = this.getAnOperand() }
override predicate first(AstNode node) { first(this.getLhs(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from lhs to rhs
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).failed() and
first(this.getRhs(), succ)
or
// Edge from lhs to this
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).succeeded() and
succ = this
or
// Edge from rhs to this
last(this.getRhs(), pred, c) and
succ = this and
completionIsNormal(c)
}
}
class LogicalAndTree extends PostOrderTree, LogicalAndExpr {
final override predicate propagatesAbnormal(AstNode child) { child = this.getAnOperand() }
override predicate first(AstNode node) { first(this.getLhs(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from lhs to rhs
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).succeeded() and
first(this.getRhs(), succ)
or
// Edge from lhs to this
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).failed() and
succ = this
or
// Edge from rhs to this
last(this.getRhs(), pred, c) and
succ = this and
completionIsNormal(c)
}
}
class BlockExprTree extends StandardPostOrderTree, BlockExpr {
override AstNode getChildNode(int i) {
result = this.getStmtList().getStatement(i)
or
i = this.getStmtList().getNumberOfStatements() and
result = this.getStmtList().getTailExpr()
}
override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) }
}
class BreakExprTree extends StandardPostOrderTree, BreakExpr {
override AstNode getChildNode(int i) { i = 0 and result = this.getExpr() }
override predicate last(AstNode last, Completion c) { none() }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
super.succ(pred, succ, c)
or
pred = this and c.isValidFor(pred) and succ = this.getTarget()
}
}
class CallExprTree extends StandardPostOrderTree instanceof CallExpr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getExpr()
or
result = super.getArgList().getArg(i - 1)
}
}
class CastExprTree extends StandardPostOrderTree instanceof CastExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class ClosureExprTree extends StandardTree, ClosureExpr {
override predicate first(AstNode first) { first = this }
override predicate last(AstNode last, Completion c) {
last = this and
completionIsValidFor(c, this)
}
override predicate propagatesAbnormal(AstNode child) { none() }
override AstNode getChildNode(int i) {
result = this.getParamList().getParam(i)
or
i = this.getParamList().getNumberOfParams() and
result = this.getBody()
}
}
class ContinueExprTree extends LeafTree, ContinueExpr {
override predicate last(AstNode last, Completion c) { none() }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
pred = this and
c.isValidFor(pred) and
first(this.getTarget().(LoopingExprTree).getLoopContinue(), succ)
}
}
class ExprStmtTree extends StandardPreOrderTree instanceof ExprStmt {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class FieldExprTree extends StandardPostOrderTree instanceof FieldExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class FunctionTree extends StandardTree, Function {
override predicate first(AstNode first) { first = this }
@@ -229,58 +87,6 @@ class ParamTree extends StandardPostOrderTree, Param {
override AstNode getChildNode(int i) { i = 0 and result = this.getPat() }
}
class IfExprTree extends PostOrderTree instanceof IfExpr {
override predicate first(AstNode node) { first(super.getCondition(), node) }
override predicate propagatesAbnormal(AstNode child) {
child = [super.getCondition(), super.getThen(), super.getElse()]
}
private ConditionalCompletion conditionCompletion(Completion c) {
if super.getCondition() instanceof LetExpr
then result = c.(MatchCompletion)
else result = c.(BooleanCompletion)
}
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edges from the condition to the branches
last(super.getCondition(), pred, c) and
(
first(super.getThen(), succ) and this.conditionCompletion(c).succeeded()
or
first(super.getElse(), succ) and this.conditionCompletion(c).failed()
or
not super.hasElse() and succ = this and this.conditionCompletion(c).failed()
)
or
// An edge from the then branch to the last node
last(super.getThen(), pred, c) and
succ = this and
completionIsNormal(c)
or
// An edge from the else branch to the last node
last(super.getElse(), pred, c) and
succ = this and
completionIsNormal(c)
}
}
class FormatArgsExprTree extends StandardPostOrderTree, FormatArgsExpr {
override AstNode getChildNode(int i) {
i = -1 and result = this.getTemplate()
or
result = this.getArg(i).getExpr()
}
}
class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getBase()
or
i = 1 and result = super.getIndex()
}
}
class ItemTree extends LeafTree, Item {
ItemTree() {
not this instanceof MacroCall and
@@ -288,19 +94,6 @@ class ItemTree extends LeafTree, Item {
}
}
// `LetExpr` is a pre-order tree such that the pattern itself ends up
// dominating successors in the graph in the same way that patterns do in
// `match` expressions.
class LetExprTree extends StandardPreOrderTree, LetExpr {
override AstNode getChildNode(int i) {
i = 0 and
result = this.getExpr()
or
i = 1 and
result = this.getPat()
}
}
class LetStmtTree extends PreOrderTree, LetStmt {
final override predicate propagatesAbnormal(AstNode child) {
child = [this.getInitializer(), this.getLetElse().getBlockExpr()]
@@ -332,97 +125,6 @@ class LetStmtTree extends PreOrderTree, LetStmt {
}
}
class LiteralExprTree extends LeafTree instanceof LiteralExpr { }
abstract class LoopingExprTree extends PostOrderTree {
override predicate propagatesAbnormal(AstNode child) { child = this.getLoopBody() }
abstract BlockExpr getLoopBody();
/**
* Gets the node to execute when continuing the loop; either after
* executing the last node in the body or after an explicit `continue`.
*/
abstract AstNode getLoopContinue();
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge back to the start for final expression and continue expressions
last(this.getLoopBody(), pred, c) and
completionIsNormal(c) and
first(this.getLoopContinue(), succ)
}
}
class LoopExprTree extends LoopingExprTree instanceof LoopExpr {
override BlockExpr getLoopBody() { result = LoopExpr.super.getLoopBody() }
override AstNode getLoopContinue() { result = this.getLoopBody() }
override predicate first(AstNode node) { first(this.getLoopBody(), node) }
}
class WhileExprTree extends LoopingExprTree instanceof WhileExpr {
override BlockExpr getLoopBody() { result = WhileExpr.super.getLoopBody() }
override AstNode getLoopContinue() { result = super.getCondition() }
override predicate propagatesAbnormal(AstNode child) {
super.propagatesAbnormal(child)
or
child = super.getCondition()
}
override predicate first(AstNode node) { first(super.getCondition(), node) }
private ConditionalCompletion conditionCompletion(Completion c) {
if super.getCondition() instanceof LetExpr
then result = c.(MatchCompletion)
else result = c.(BooleanCompletion)
}
override predicate succ(AstNode pred, AstNode succ, Completion c) {
super.succ(pred, succ, c)
or
last(super.getCondition(), pred, c) and
this.conditionCompletion(c).succeeded() and
first(this.getLoopBody(), succ)
or
last(super.getCondition(), pred, c) and
this.conditionCompletion(c).failed() and
succ = this
}
}
class ForExprTree extends LoopingExprTree instanceof ForExpr {
override BlockExpr getLoopBody() { result = ForExpr.super.getLoopBody() }
override AstNode getLoopContinue() { result = super.getPat() }
override predicate propagatesAbnormal(AstNode child) {
super.propagatesAbnormal(child)
or
child = super.getIterable()
}
override predicate first(AstNode node) { first(super.getIterable(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
super.succ(pred, succ, c)
or
last(super.getIterable(), pred, c) and
first(super.getPat(), succ) and
completionIsNormal(c)
or
last(super.getPat(), pred, c) and
c.(MatchCompletion).succeeded() and
first(this.getLoopBody(), succ)
or
last(super.getPat(), pred, c) and
c.(MatchCompletion).failed() and
succ = this
}
}
class MacroCallTree extends ControlFlowTree, MacroCall {
override predicate first(AstNode first) {
first(this.getExpanded(), first)
@@ -443,10 +145,6 @@ class MacroCallTree extends ControlFlowTree, MacroCall {
override predicate propagatesAbnormal(AstNode child) { child = this.getExpanded() }
}
class MacroExprTree extends StandardPostOrderTree, MacroExpr {
override AstNode getChildNode(int i) { i = 0 and result = this.getMacroCall() }
}
class MacroStmtsTree extends StandardPreOrderTree, MacroStmts {
override AstNode getChildNode(int i) {
result = this.getStatement(i)
@@ -486,44 +184,6 @@ class MatchArmTree extends ControlFlowTree, MatchArm {
}
}
class MatchExprTree extends PostOrderTree instanceof MatchExpr {
override predicate propagatesAbnormal(AstNode child) {
child = [super.getExpr(), super.getAnArm().getExpr()]
}
override predicate first(AstNode node) { first(super.getExpr(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from the scrutinee to the first arm or to the match expression if no arms.
last(super.getExpr(), pred, c) and
(
first(super.getArm(0).getPat(), succ)
or
not exists(super.getArm(0)) and succ = this
) and
completionIsNormal(c)
or
// Edge from a failed pattern or guard in one arm to the beginning of the next arm.
exists(int i |
(
last(super.getArm(i).getPat(), pred, c) or
last(super.getArm(i).getGuard().getCondition(), pred, c)
) and
first(super.getArm(i + 1), succ) and
c.(ConditionalCompletion).failed()
)
or
// Edge from the end of each arm to the match expression.
last(super.getArm(_).getExpr(), pred, c) and succ = this and completionIsNormal(c)
}
}
class MethodCallExprTree extends StandardPostOrderTree, MethodCallExpr {
override AstNode getChildNode(int i) {
if i = 0 then result = this.getReceiver() else result = this.getArgList().getArg(i - 1)
}
}
class NameTree extends LeafTree, Name { }
class NameRefTree extends LeafTree, NameRef { }
@@ -544,54 +204,402 @@ class ParenExprTree extends ControlFlowTree, ParenExpr {
override predicate succ(AstNode pred, AstNode succ, Completion c) { none() }
}
class PathExprTree extends LeafTree instanceof PathExpr { }
class PrefixExprTree extends StandardPostOrderTree instanceof PrefixExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class RangeExprTree extends StandardPostOrderTree instanceof RangeExpr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getStart()
or
i = 1 and result = super.getEnd()
}
}
class RecordExprTree extends StandardPostOrderTree instanceof RecordExpr {
override AstNode getChildNode(int i) {
result = super.getRecordExprFieldList().getField(i).getExpr()
}
}
class RefExprTree extends StandardPostOrderTree instanceof RefExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class ReturnExprTree extends StandardPostOrderTree instanceof ReturnExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class TryExprTree extends StandardPostOrderTree instanceof TryExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class TupleExprTree extends StandardPostOrderTree instanceof TupleExpr {
override AstNode getChildNode(int i) { result = super.getField(i) }
}
class TypeRefTree extends LeafTree instanceof TypeRef { }
class UnderscoreExprTree extends LeafTree instanceof UnderscoreExpr { }
/**
* Provides `ControlFlowTree`s for expressions.
*
* Since expressions construct values, they are modeled in post-order, except for
* `LetExpr`s.
*/
module ExprTrees {
class ArrayExprTree extends StandardPostOrderTree, ArrayExpr {
override AstNode getChildNode(int i) { result = this.getExpr(i) }
}
// NOTE: `yield` is a reserved but unused keyword.
class YieldExprTree extends StandardPostOrderTree instanceof YieldExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class AsmExprTree extends LeafTree instanceof AsmExpr { }
// NOTE: `yeet` is experimental and not a part of Rust.
class YeetExprTree extends StandardPostOrderTree instanceof YeetExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
class AwaitExprTree extends StandardPostOrderTree instanceof AwaitExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
// NOTE: `become` is a reserved but unused keyword.
class BecomeExprTree extends StandardPostOrderTree instanceof BecomeExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryExpr {
BinaryOpExprTree() { not this instanceof BinaryLogicalOperation }
override AstNode getChildNode(int i) {
i = 0 and result = super.getLhs()
or
i = 1 and result = super.getRhs()
}
}
class LogicalOrExprTree extends PostOrderTree, LogicalOrExpr {
final override predicate propagatesAbnormal(AstNode child) { child = this.getAnOperand() }
override predicate first(AstNode node) { first(this.getLhs(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from lhs to rhs
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).failed() and
first(this.getRhs(), succ)
or
// Edge from lhs to this
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).succeeded() and
succ = this
or
// Edge from rhs to this
last(this.getRhs(), pred, c) and
succ = this and
completionIsNormal(c)
}
}
class LogicalAndExprTree extends PostOrderTree, LogicalAndExpr {
final override predicate propagatesAbnormal(AstNode child) { child = this.getAnOperand() }
override predicate first(AstNode node) { first(this.getLhs(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from lhs to rhs
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).succeeded() and
first(this.getRhs(), succ)
or
// Edge from lhs to this
last(this.getLhs(), pred, c) and
c.(BooleanCompletion).failed() and
succ = this
or
// Edge from rhs to this
last(this.getRhs(), pred, c) and
succ = this and
completionIsNormal(c)
}
}
class BlockExprTree extends StandardPostOrderTree, BlockExpr {
override AstNode getChildNode(int i) {
result = this.getStmtList().getStatement(i)
or
i = this.getStmtList().getNumberOfStatements() and
result = this.getStmtList().getTailExpr()
}
override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) }
}
class BreakExprTree extends StandardPostOrderTree, BreakExpr {
override AstNode getChildNode(int i) { i = 0 and result = this.getExpr() }
override predicate last(AstNode last, Completion c) { none() }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
super.succ(pred, succ, c)
or
pred = this and c.isValidFor(pred) and succ = this.getTarget()
}
}
class CallExprTree extends StandardPostOrderTree instanceof CallExpr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getExpr()
or
result = super.getArgList().getArg(i - 1)
}
}
class CastExprTree extends StandardPostOrderTree instanceof CastExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class ClosureExprTree extends StandardTree, ClosureExpr {
override predicate first(AstNode first) { first = this }
override predicate last(AstNode last, Completion c) {
last = this and
completionIsValidFor(c, this)
}
override predicate propagatesAbnormal(AstNode child) { none() }
override AstNode getChildNode(int i) {
result = this.getParamList().getParam(i)
or
i = this.getParamList().getNumberOfParams() and
result = this.getBody()
}
}
class ContinueExprTree extends LeafTree, ContinueExpr {
override predicate last(AstNode last, Completion c) { none() }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
pred = this and
c.isValidFor(pred) and
first(this.getTarget().(LoopingExprTree).getLoopContinue(), succ)
}
}
class ExprStmtTree extends StandardPreOrderTree instanceof ExprStmt {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class FieldExprTree extends StandardPostOrderTree instanceof FieldExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class IfExprTree extends PostOrderTree instanceof IfExpr {
override predicate first(AstNode node) { first(super.getCondition(), node) }
override predicate propagatesAbnormal(AstNode child) {
child = [super.getCondition(), super.getThen(), super.getElse()]
}
private ConditionalCompletion conditionCompletion(Completion c) {
if super.getCondition() instanceof LetExpr
then result = c.(MatchCompletion)
else result = c.(BooleanCompletion)
}
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edges from the condition to the branches
last(super.getCondition(), pred, c) and
(
first(super.getThen(), succ) and this.conditionCompletion(c).succeeded()
or
first(super.getElse(), succ) and this.conditionCompletion(c).failed()
or
not super.hasElse() and succ = this and this.conditionCompletion(c).failed()
)
or
// An edge from the then branch to the last node
last(super.getThen(), pred, c) and
succ = this and
completionIsNormal(c)
or
// An edge from the else branch to the last node
last(super.getElse(), pred, c) and
succ = this and
completionIsNormal(c)
}
}
class FormatArgsExprTree extends StandardPostOrderTree, FormatArgsExpr {
override AstNode getChildNode(int i) {
i = -1 and result = this.getTemplate()
or
result = this.getArg(i).getExpr()
}
}
class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getBase()
or
i = 1 and result = super.getIndex()
}
}
// `LetExpr` is a pre-order tree such that the pattern itself ends up
// dominating successors in the graph in the same way that patterns do in
// `match` expressions.
class LetExprTree extends StandardPreOrderTree, LetExpr {
override AstNode getChildNode(int i) {
i = 0 and
result = this.getExpr()
or
i = 1 and
result = this.getPat()
}
}
class LiteralExprTree extends LeafTree instanceof LiteralExpr { }
abstract class LoopingExprTree extends PostOrderTree {
override predicate propagatesAbnormal(AstNode child) { child = this.getLoopBody() }
abstract BlockExpr getLoopBody();
/**
* Gets the node to execute when continuing the loop; either after
* executing the last node in the body or after an explicit `continue`.
*/
abstract AstNode getLoopContinue();
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge back to the start for final expression and continue expressions
last(this.getLoopBody(), pred, c) and
completionIsNormal(c) and
first(this.getLoopContinue(), succ)
}
}
class LoopExprTree extends LoopingExprTree instanceof LoopExpr {
override BlockExpr getLoopBody() { result = LoopExpr.super.getLoopBody() }
override AstNode getLoopContinue() { result = this.getLoopBody() }
override predicate first(AstNode node) { first(this.getLoopBody(), node) }
}
class WhileExprTree extends LoopingExprTree instanceof WhileExpr {
override BlockExpr getLoopBody() { result = WhileExpr.super.getLoopBody() }
override AstNode getLoopContinue() { result = super.getCondition() }
override predicate propagatesAbnormal(AstNode child) {
super.propagatesAbnormal(child)
or
child = super.getCondition()
}
override predicate first(AstNode node) { first(super.getCondition(), node) }
private ConditionalCompletion conditionCompletion(Completion c) {
if super.getCondition() instanceof LetExpr
then result = c.(MatchCompletion)
else result = c.(BooleanCompletion)
}
override predicate succ(AstNode pred, AstNode succ, Completion c) {
super.succ(pred, succ, c)
or
last(super.getCondition(), pred, c) and
this.conditionCompletion(c).succeeded() and
first(this.getLoopBody(), succ)
or
last(super.getCondition(), pred, c) and
this.conditionCompletion(c).failed() and
succ = this
}
}
class ForExprTree extends LoopingExprTree instanceof ForExpr {
override BlockExpr getLoopBody() { result = ForExpr.super.getLoopBody() }
override AstNode getLoopContinue() { result = super.getPat() }
override predicate propagatesAbnormal(AstNode child) {
super.propagatesAbnormal(child)
or
child = super.getIterable()
}
override predicate first(AstNode node) { first(super.getIterable(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
super.succ(pred, succ, c)
or
last(super.getIterable(), pred, c) and
first(super.getPat(), succ) and
completionIsNormal(c)
or
last(super.getPat(), pred, c) and
c.(MatchCompletion).succeeded() and
first(this.getLoopBody(), succ)
or
last(super.getPat(), pred, c) and
c.(MatchCompletion).failed() and
succ = this
}
}
class MacroExprTree extends StandardPostOrderTree, MacroExpr {
override AstNode getChildNode(int i) { i = 0 and result = this.getMacroCall() }
}
class MatchExprTree extends PostOrderTree instanceof MatchExpr {
override predicate propagatesAbnormal(AstNode child) {
child = [super.getExpr(), super.getAnArm().getExpr()]
}
override predicate first(AstNode node) { first(super.getExpr(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from the scrutinee to the first arm or to the match expression if no arms.
last(super.getExpr(), pred, c) and
(
first(super.getArm(0).getPat(), succ)
or
not exists(super.getArm(0)) and succ = this
) and
completionIsNormal(c)
or
// Edge from a failed pattern or guard in one arm to the beginning of the next arm.
exists(int i |
(
last(super.getArm(i).getPat(), pred, c) or
last(super.getArm(i).getGuard().getCondition(), pred, c)
) and
first(super.getArm(i + 1), succ) and
c.(ConditionalCompletion).failed()
)
or
// Edge from the end of each arm to the match expression.
last(super.getArm(_).getExpr(), pred, c) and succ = this and completionIsNormal(c)
}
}
class MethodCallExprTree extends StandardPostOrderTree, MethodCallExpr {
override AstNode getChildNode(int i) {
if i = 0 then result = this.getReceiver() else result = this.getArgList().getArg(i - 1)
}
}
class PathExprTree extends LeafTree instanceof PathExpr { }
class PrefixExprTree extends StandardPostOrderTree instanceof PrefixExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class RangeExprTree extends StandardPostOrderTree instanceof RangeExpr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getStart()
or
i = 1 and result = super.getEnd()
}
}
class RecordExprTree extends StandardPostOrderTree instanceof RecordExpr {
override AstNode getChildNode(int i) {
result = super.getRecordExprFieldList().getField(i).getExpr()
}
}
class RefExprTree extends StandardPostOrderTree instanceof RefExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class ReturnExprTree extends StandardPostOrderTree instanceof ReturnExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class TryExprTree extends StandardPostOrderTree instanceof TryExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class TupleExprTree extends StandardPostOrderTree instanceof TupleExpr {
override AstNode getChildNode(int i) { result = super.getField(i) }
}
class UnderscoreExprTree extends LeafTree instanceof UnderscoreExpr { }
// NOTE: `yield` is a reserved but unused keyword.
class YieldExprTree extends StandardPostOrderTree instanceof YieldExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
// NOTE: `yeet` is experimental and not a part of Rust.
class YeetExprTree extends StandardPostOrderTree instanceof YeetExpr {
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
}
}
/**

View File

@@ -27,7 +27,7 @@ final class FunctionScope extends CfgScope, Function {
final class ClosureScope extends CfgScope, ClosureExpr {
override predicate scopeFirst(AstNode node) {
first(this.(ClosureExprTree).getFirstChildNode(), node)
first(this.(ExprTrees::ClosureExprTree).getFirstChildNode(), node)
}
override predicate scopeLast(AstNode node, Completion c) { last(this.getBody(), node, c) }