mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
Ruby: Deprecate Pattern classes
This commit is contained in:
@@ -692,7 +692,7 @@ class ForExpr extends Loop, TForExpr {
|
||||
final override StmtSequence getBody() { toGenerated(result) = g.getBody() }
|
||||
|
||||
/** Gets the pattern representing the iteration argument. */
|
||||
final Pattern getPattern() { toGenerated(result) = g.getPattern() }
|
||||
final LhsExpr getPattern() { toGenerated(result) = g.getPattern() }
|
||||
|
||||
/**
|
||||
* Gets the value being iterated over. In the following example, the result
|
||||
|
||||
@@ -66,6 +66,83 @@ class ArgumentList extends Expr, TArgumentList {
|
||||
}
|
||||
}
|
||||
|
||||
private class LhsExpr_ =
|
||||
TVariableAccess or TTokenConstantAccess or TScopeResolutionConstantAccess or TMethodCall or
|
||||
TDestructuredLhsExpr;
|
||||
|
||||
/**
|
||||
* A "left-hand-side" (LHS) expression. An `LhsExpr` can occur on the left-hand side of
|
||||
* operator assignments (`AssignOperation`), on the left-hand side of assignments
|
||||
* (`AssignExpr`), as patterns in for loops (`ForExpr`), and as exception variables
|
||||
* in `rescue` clauses (`RescueClause`).
|
||||
*
|
||||
* An `LhsExpr` can be a simple variable, a constant, a call, or an element reference:
|
||||
*
|
||||
* ```rb
|
||||
* var = 1
|
||||
* var += 1
|
||||
* E = 1
|
||||
* foo.bar = 1
|
||||
* foo[0] = 1
|
||||
* rescue E => var
|
||||
* ```
|
||||
*/
|
||||
class LhsExpr extends Expr, LhsExpr_ {
|
||||
LhsExpr() { lhsExpr(this) }
|
||||
|
||||
/** Gets a variable used in (or introduced by) this LHS. */
|
||||
Variable getAVariable() { result = this.(VariableAccess).getVariable() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A "left-hand-side" (LHS) expression of a destructured assignment.
|
||||
*
|
||||
* Examples:
|
||||
* ```rb
|
||||
* a, self.b = value
|
||||
* (a, b), c[3] = value
|
||||
* a, b, *rest, c, d = value
|
||||
* ```
|
||||
*/
|
||||
class DestructuredLhsExpr extends LhsExpr, TDestructuredLhsExpr {
|
||||
override string getAPrimaryQlClass() { result = "DestructuredLhsExpr" }
|
||||
|
||||
private DestructuredLhsExprImpl getImpl() { result = toGenerated(this) }
|
||||
|
||||
private Ruby::AstNode getChild(int i) { result = this.getImpl().getChildNode(i) }
|
||||
|
||||
/** Gets the `i`th element in this destructured LHS. */
|
||||
final Expr getElement(int i) {
|
||||
exists(Ruby::AstNode c | c = this.getChild(i) |
|
||||
toGenerated(result) = c.(Ruby::RestAssignment).getChild()
|
||||
or
|
||||
toGenerated(result) = c
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets an element in this destructured LHS. */
|
||||
final Expr getAnElement() { result = this.getElement(_) }
|
||||
|
||||
/**
|
||||
* Gets the index of the element with the `*` marker on it, if it exists.
|
||||
* In the example below the index is `2`.
|
||||
* ```rb
|
||||
* a, b, *rest, c, d = value
|
||||
* ```
|
||||
*/
|
||||
final int getRestIndex() { result = this.getImpl().getRestIndex() }
|
||||
|
||||
override Variable getAVariable() {
|
||||
result = this.getElement(_).(VariableWriteAccess).getVariable()
|
||||
or
|
||||
result = this.getElement(_).(DestructuredLhsExpr).getAVariable()
|
||||
}
|
||||
|
||||
override string toString() { result = "(..., ...)" }
|
||||
|
||||
override AstNode getAChild(string pred) { pred = "getElement" and result = this.getElement(_) }
|
||||
}
|
||||
|
||||
/** A sequence of expressions. */
|
||||
class StmtSequence extends Expr, TStmtSequence {
|
||||
override string getAPrimaryQlClass() { result = "StmtSequence" }
|
||||
|
||||
@@ -443,7 +443,7 @@ class NoRegExpMatchExpr extends BinaryOperation, TNoRegExpMatchExpr {
|
||||
*/
|
||||
class Assignment extends Operation instanceof AssignmentImpl {
|
||||
/** Gets the left hand side of this assignment. */
|
||||
final Pattern getLeftOperand() { result = super.getLeftOperandImpl() }
|
||||
final LhsExpr getLeftOperand() { result = super.getLeftOperandImpl() }
|
||||
|
||||
/** Gets the right hand side of this assignment. */
|
||||
final Expr getRightOperand() { result = super.getRightOperandImpl() }
|
||||
|
||||
@@ -23,21 +23,59 @@ class Parameter extends AstNode, TParameter {
|
||||
}
|
||||
|
||||
/**
|
||||
* A parameter defined using destructuring. For example
|
||||
*
|
||||
* ```rb
|
||||
* def tuples((a,b))
|
||||
* puts "#{a} #{b}"
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class DestructuredParameter extends Parameter, TDestructuredParameter {
|
||||
private DestructuredParameterImpl getImpl() { result = toGenerated(this) }
|
||||
|
||||
private Ruby::AstNode getChild(int i) { result = this.getImpl().getChildNode(i) }
|
||||
|
||||
/** Gets the `i`th element in this destructured parameter. */
|
||||
final AstNode getElement(int i) {
|
||||
exists(Ruby::AstNode c | c = this.getChild(i) | toGenerated(result) = c)
|
||||
}
|
||||
|
||||
/** Gets an element in this destructured parameter. */
|
||||
final AstNode getAnElement() { result = this.getElement(_) }
|
||||
|
||||
override LocalVariable getAVariable() {
|
||||
result = this.getAnElement().(LocalVariableWriteAccess).getVariable()
|
||||
or
|
||||
result = this.getAnElement().(DestructuredParameter).getAVariable()
|
||||
}
|
||||
|
||||
override string toString() { result = "(..., ...)" }
|
||||
|
||||
override AstNode getAChild(string pred) { pred = "getElement" and result = this.getElement(_) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "DestructuredParameter" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED
|
||||
*
|
||||
* A parameter defined using a pattern.
|
||||
*
|
||||
* This includes both simple parameters and tuple parameters.
|
||||
*/
|
||||
class PatternParameter extends Parameter, Pattern, TPatternParameter {
|
||||
deprecated class PatternParameter extends Parameter, Pattern, TPatternParameter {
|
||||
override LocalVariable getAVariable() { result = Pattern.super.getAVariable() }
|
||||
}
|
||||
|
||||
/** A parameter defined using a tuple pattern. */
|
||||
class TuplePatternParameter extends PatternParameter, TuplePattern, TTuplePatternParameter {
|
||||
/**
|
||||
* DEPRECATED
|
||||
*
|
||||
* A parameter defined using a tuple pattern.
|
||||
*/
|
||||
deprecated class TuplePatternParameter extends PatternParameter, TuplePattern,
|
||||
TDestructuredParameter {
|
||||
final override LocalVariable getAVariable() { result = TuplePattern.super.getAVariable() }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "TuplePatternParameter" }
|
||||
|
||||
override AstNode getAChild(string pred) { result = TuplePattern.super.getAChild(pred) }
|
||||
}
|
||||
|
||||
/** A named parameter. */
|
||||
@@ -72,7 +110,7 @@ class NamedParameter extends Parameter, TNamedParameter {
|
||||
}
|
||||
|
||||
/** A simple (normal) parameter. */
|
||||
class SimpleParameter extends NamedParameter, PatternParameter, VariablePattern, TSimpleParameter instanceof SimpleParameterImpl {
|
||||
class SimpleParameter extends NamedParameter, TSimpleParameter instanceof SimpleParameterImpl {
|
||||
final override string getName() { result = SimpleParameterImpl.super.getNameImpl() }
|
||||
|
||||
final override LocalVariable getVariable() {
|
||||
|
||||
@@ -6,8 +6,12 @@ private import internal.TreeSitter
|
||||
private import internal.Variable
|
||||
private import internal.Parameter
|
||||
|
||||
/** A pattern. */
|
||||
class Pattern extends AstNode {
|
||||
/**
|
||||
* DEPRECATED
|
||||
*
|
||||
* A pattern.
|
||||
*/
|
||||
deprecated class Pattern extends AstNode {
|
||||
Pattern() {
|
||||
explicitAssignmentNode(toGenerated(this), _)
|
||||
or
|
||||
@@ -24,36 +28,20 @@ class Pattern extends AstNode {
|
||||
Variable getAVariable() { none() }
|
||||
}
|
||||
|
||||
private class LhsExpr_ =
|
||||
TVariableAccess or TTokenConstantAccess or TScopeResolutionConstantAccess or TMethodCall or
|
||||
TSimpleParameter;
|
||||
deprecated private class TVariablePattern = TVariableAccess or TSimpleParameter;
|
||||
|
||||
/**
|
||||
* A "left-hand-side" expression. An `LhsExpr` can occur on the left-hand side of
|
||||
* operator assignments (`AssignOperation`), in patterns (`Pattern`) on the left-hand side of
|
||||
* an assignment (`AssignExpr`) or for loop (`ForExpr`), and as the exception
|
||||
* variable of a `rescue` clause (`RescueClause`).
|
||||
* DEPRECATED
|
||||
*
|
||||
* An `LhsExpr` can be a simple variable, a constant, a call, or an element reference:
|
||||
* ```rb
|
||||
* var = 1
|
||||
* var += 1
|
||||
* E = 1
|
||||
* foo.bar = 1
|
||||
* foo[0] = 1
|
||||
* rescue E => var
|
||||
* ```
|
||||
* A simple variable pattern.
|
||||
*/
|
||||
class LhsExpr extends Pattern, LhsExpr_, Expr {
|
||||
deprecated class VariablePattern extends Pattern, LhsExpr, TVariablePattern {
|
||||
override Variable getAVariable() { result = this.(VariableAccess).getVariable() }
|
||||
}
|
||||
|
||||
private class TVariablePattern = TVariableAccess or TSimpleParameter;
|
||||
|
||||
/** A simple variable pattern. */
|
||||
class VariablePattern extends Pattern, LhsExpr, TVariablePattern { }
|
||||
|
||||
/**
|
||||
* DEPRECATED
|
||||
*
|
||||
* A tuple pattern.
|
||||
*
|
||||
* This includes both tuple patterns in parameters and assignments. Example patterns:
|
||||
@@ -63,9 +51,7 @@ class VariablePattern extends Pattern, LhsExpr, TVariablePattern { }
|
||||
* a, b, *rest, c, d = value
|
||||
* ```
|
||||
*/
|
||||
class TuplePattern extends Pattern, TTuplePattern {
|
||||
override string getAPrimaryQlClass() { result = "TuplePattern" }
|
||||
|
||||
deprecated class TuplePattern extends Pattern, TTuplePattern {
|
||||
private TuplePatternImpl getImpl() { result = toGenerated(this) }
|
||||
|
||||
private Ruby::AstNode getChild(int i) { result = this.getImpl().getChildNode(i) }
|
||||
@@ -92,10 +78,6 @@ class TuplePattern extends Pattern, TTuplePattern {
|
||||
final int getRestIndex() { result = this.getImpl().getRestIndex() }
|
||||
|
||||
override Variable getAVariable() { result = this.getElement(_).getAVariable() }
|
||||
|
||||
override string toString() { result = "(..., ...)" }
|
||||
|
||||
override AstNode getAChild(string pred) { pred = "getElement" and result = this.getElement(_) }
|
||||
}
|
||||
|
||||
private class TPatternNode =
|
||||
|
||||
@@ -296,7 +296,7 @@ private module Cached {
|
||||
TTokenSuperCall(Ruby::Super g) { vcall(g) } or
|
||||
TToplevel(Ruby::Program g) or
|
||||
TTrueLiteral(Ruby::True g) or
|
||||
TTuplePatternParameter(Ruby::DestructuredParameter g) or
|
||||
TDestructuredParameter(Ruby::DestructuredParameter g) or
|
||||
TUnaryMinusExpr(Ruby::Unary g) { g instanceof @ruby_unary_minus } or
|
||||
TUnaryPlusExpr(Ruby::Unary g) { g instanceof @ruby_unary_plus } or
|
||||
TUndefStmt(Ruby::Undef g) or
|
||||
@@ -342,7 +342,7 @@ private module Cached {
|
||||
TStringConcatenation or TStringEscapeSequenceComponent or TStringInterpolationComponent or
|
||||
TStringTextComponent or TSubExprReal or TSubshellLiteral or TSymbolArrayLiteral or
|
||||
TTernaryIfExpr or TThen or TTokenConstantAccess or TTokenMethodName or TTokenSuperCall or
|
||||
TToplevel or TTrueLiteral or TTuplePatternParameter or TUnaryMinusExpr or TUnaryPlusExpr or
|
||||
TToplevel or TTrueLiteral or TDestructuredParameter or TUnaryMinusExpr or TUnaryPlusExpr or
|
||||
TUndefStmt or TUnlessExpr or TUnlessModifierExpr or TUntilExpr or TUntilModifierExpr or
|
||||
TVariableReferencePattern or TWhenExpr or TWhileExpr or TWhileModifierExpr or TYieldCall;
|
||||
|
||||
@@ -502,7 +502,7 @@ private module Cached {
|
||||
n = TTokenSuperCall(result) or
|
||||
n = TToplevel(result) or
|
||||
n = TTrueLiteral(result) or
|
||||
n = TTuplePatternParameter(result) or
|
||||
n = TDestructuredParameter(result) or
|
||||
n = TUnaryMinusExpr(result) or
|
||||
n = TUnaryPlusExpr(result) or
|
||||
n = TUndefStmt(result) or
|
||||
@@ -613,6 +613,15 @@ private module Cached {
|
||||
or
|
||||
result = toGenerated(n).getLocation()
|
||||
}
|
||||
|
||||
cached
|
||||
predicate lhsExpr(AST::Expr e) {
|
||||
explicitAssignmentNode(toGenerated(e), _)
|
||||
or
|
||||
implicitAssignmentNode(toGenerated(e))
|
||||
or
|
||||
e = getSynthChild(any(AST::AssignExpr ae), 0)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
@@ -645,11 +654,13 @@ class TLoop = TConditionalLoop or TForExpr;
|
||||
|
||||
class TSelf = TSelfReal or TSelfSynth;
|
||||
|
||||
class TDestructuredLhsExpr = TDestructuredLeftAssignment or TLeftAssignmentList;
|
||||
|
||||
class TExpr =
|
||||
TSelf or TArgumentList or TInClause or TRescueClause or TRescueModifierExpr or TPair or
|
||||
TStringConcatenation or TCall or TBlockArgument or TConstantAccess or TControlExpr or
|
||||
TWhenExpr or TLiteral or TCallable or TVariableAccess or TStmtSequence or TOperation or
|
||||
TSimpleParameter or TForwardArgument;
|
||||
TSimpleParameter or TForwardArgument or TDestructuredLhsExpr;
|
||||
|
||||
class TSplatExpr = TSplatExprReal or TSplatExprSynth;
|
||||
|
||||
@@ -778,18 +789,20 @@ class TStmt =
|
||||
class TReturningStmt = TReturnStmt or TBreakStmt or TNextStmt;
|
||||
|
||||
class TParameter =
|
||||
TPatternParameter or TBlockParameter or THashSplatParameter or THashSplatNilParameter or
|
||||
TKeywordParameter or TOptionalParameter or TSplatParameter or TForwardParameter;
|
||||
TSimpleParameter or TDestructuredParameter or TBlockParameter or THashSplatParameter or
|
||||
THashSplatNilParameter or TKeywordParameter or TOptionalParameter or TSplatParameter or
|
||||
TForwardParameter;
|
||||
|
||||
class TSimpleParameter = TSimpleParameterReal or TSimpleParameterSynth;
|
||||
|
||||
class TPatternParameter = TSimpleParameter or TTuplePatternParameter;
|
||||
deprecated class TPatternParameter = TSimpleParameter or TDestructuredParameter;
|
||||
|
||||
class TNamedParameter =
|
||||
TSimpleParameter or TBlockParameter or THashSplatParameter or TKeywordParameter or
|
||||
TOptionalParameter or TSplatParameter;
|
||||
|
||||
class TTuplePattern = TTuplePatternParameter or TDestructuredLeftAssignment or TLeftAssignmentList;
|
||||
deprecated class TTuplePattern =
|
||||
TDestructuredParameter or TDestructuredLeftAssignment or TLeftAssignmentList;
|
||||
|
||||
class TVariableAccess =
|
||||
TLocalVariableAccess or TGlobalVariableAccess or TInstanceVariableAccess or
|
||||
|
||||
@@ -73,3 +73,29 @@ Ruby::AstNode getBodyStmtChild(TBodyStmt b, int i) {
|
||||
or
|
||||
result = any(Ruby::Begin g | b = TBeginExpr(g)).getChild(i)
|
||||
}
|
||||
|
||||
abstract class DestructuredLhsExprImpl extends Ruby::AstNode {
|
||||
abstract Ruby::AstNode getChildNode(int i);
|
||||
|
||||
final int getRestIndex() {
|
||||
result = unique(int i | this.getChildNode(i) instanceof Ruby::RestAssignment)
|
||||
}
|
||||
}
|
||||
|
||||
class DestructuredLeftAssignmentImpl extends DestructuredLhsExprImpl,
|
||||
Ruby::DestructuredLeftAssignment {
|
||||
override Ruby::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
}
|
||||
|
||||
class LeftAssignmentListImpl extends DestructuredLhsExprImpl, Ruby::LeftAssignmentList {
|
||||
override Ruby::AstNode getChildNode(int i) {
|
||||
this =
|
||||
any(Ruby::LeftAssignmentList lal |
|
||||
if
|
||||
strictcount(int j | exists(lal.getChild(j))) = 1 and
|
||||
lal.getChild(0) instanceof Ruby::DestructuredLeftAssignment
|
||||
then result = lal.getChild(0).(Ruby::DestructuredLeftAssignment).getChild(i)
|
||||
else result = lal.getChild(i)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ class BitwiseXorSynthExpr extends BinaryOperationSynth, TBitwiseXorExprSynth {
|
||||
}
|
||||
|
||||
abstract class AssignmentImpl extends OperationImpl, TAssignment {
|
||||
abstract Pattern getLeftOperandImpl();
|
||||
abstract Expr getLeftOperandImpl();
|
||||
|
||||
abstract Expr getRightOperandImpl();
|
||||
|
||||
@@ -172,7 +172,7 @@ class AssignExprReal extends AssignmentImpl, TAssignExprReal {
|
||||
|
||||
final override string getOperatorImpl() { result = "=" }
|
||||
|
||||
final override Pattern getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
|
||||
final override Expr getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
|
||||
|
||||
final override Expr getRightOperandImpl() { toGenerated(result) = g.getRight() }
|
||||
}
|
||||
@@ -180,7 +180,7 @@ class AssignExprReal extends AssignmentImpl, TAssignExprReal {
|
||||
class AssignExprSynth extends AssignmentImpl, TAssignExprSynth {
|
||||
final override string getOperatorImpl() { result = "=" }
|
||||
|
||||
final override Pattern getLeftOperandImpl() { synthChild(this, 0, result) }
|
||||
final override Expr getLeftOperandImpl() { synthChild(this, 0, result) }
|
||||
|
||||
final override Expr getRightOperandImpl() { synthChild(this, 1, result) }
|
||||
}
|
||||
@@ -192,7 +192,7 @@ class AssignOperationImpl extends AssignmentImpl, TAssignOperation {
|
||||
|
||||
final override string getOperatorImpl() { result = g.getOperator() }
|
||||
|
||||
final override Pattern getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
|
||||
final override Expr getLeftOperandImpl() { toGenerated(result) = g.getLeft() }
|
||||
|
||||
final override Expr getRightOperandImpl() { toGenerated(result) = g.getRight() }
|
||||
}
|
||||
|
||||
@@ -44,3 +44,7 @@ class SimpleParameterSynthImpl extends SimpleParameterImpl, TSimpleParameterSynt
|
||||
|
||||
override string getNameImpl() { result = this.getVariableImpl().getName() }
|
||||
}
|
||||
|
||||
class DestructuredParameterImpl extends Ruby::DestructuredParameter {
|
||||
Ruby::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
}
|
||||
|
||||
@@ -1,36 +1,28 @@
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.ast.internal.Expr
|
||||
private import codeql.ruby.ast.internal.Parameter
|
||||
private import AST
|
||||
private import TreeSitter
|
||||
|
||||
abstract class TuplePatternImpl extends Ruby::AstNode {
|
||||
abstract Ruby::AstNode getChildNode(int i);
|
||||
deprecated class TuplePatternImpl extends Ruby::AstNode {
|
||||
TuplePatternImpl() {
|
||||
this instanceof DestructuredParameterImpl or
|
||||
this instanceof DestructuredLhsExprImpl
|
||||
}
|
||||
|
||||
Ruby::AstNode getChildNode(int i) {
|
||||
result =
|
||||
[
|
||||
this.(DestructuredParameterImpl).getChildNode(i),
|
||||
this.(DestructuredLhsExprImpl).getChildNode(i)
|
||||
]
|
||||
}
|
||||
|
||||
final int getRestIndex() {
|
||||
result = unique(int i | this.getChildNode(i) instanceof Ruby::RestAssignment)
|
||||
}
|
||||
}
|
||||
|
||||
class TuplePatternParameterImpl extends TuplePatternImpl, Ruby::DestructuredParameter {
|
||||
override Ruby::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
}
|
||||
|
||||
class DestructuredLeftAssignmentImpl extends TuplePatternImpl, Ruby::DestructuredLeftAssignment {
|
||||
override Ruby::AstNode getChildNode(int i) { result = this.getChild(i) }
|
||||
}
|
||||
|
||||
class LeftAssignmentListImpl extends TuplePatternImpl, Ruby::LeftAssignmentList {
|
||||
override Ruby::AstNode getChildNode(int i) {
|
||||
this =
|
||||
any(Ruby::LeftAssignmentList lal |
|
||||
if
|
||||
strictcount(int j | exists(lal.getChild(j))) = 1 and
|
||||
lal.getChild(0) instanceof Ruby::DestructuredLeftAssignment
|
||||
then result = lal.getChild(0).(Ruby::DestructuredLeftAssignment).getChild(i)
|
||||
else result = lal.getChild(i)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is a case pattern.
|
||||
*/
|
||||
|
||||
@@ -636,36 +636,36 @@ private module AssignOperationDesugar {
|
||||
}
|
||||
}
|
||||
|
||||
private module CompoundAssignDesugar {
|
||||
/** An assignment where the left-hand side is a tuple pattern. */
|
||||
private class TupleAssignExpr extends AssignExpr {
|
||||
private TuplePattern tp;
|
||||
private module DestructuredAssignDesugar {
|
||||
/** A destructured assignment. */
|
||||
private class DestructuredAssignExpr extends AssignExpr {
|
||||
private DestructuredLhsExpr lhs;
|
||||
|
||||
pragma[nomagic]
|
||||
TupleAssignExpr() { tp = this.getLeftOperand() }
|
||||
DestructuredAssignExpr() { lhs = this.getLeftOperand() }
|
||||
|
||||
TuplePattern getTuplePattern() { result = tp }
|
||||
DestructuredLhsExpr getLhs() { result = lhs }
|
||||
|
||||
pragma[nomagic]
|
||||
Pattern getElement(int i) { result = tp.getElement(i) }
|
||||
Expr getElement(int i) { result = lhs.getElement(i) }
|
||||
|
||||
pragma[nomagic]
|
||||
int getNumberOfElements() {
|
||||
toGenerated(tp) = any(TuplePatternImpl impl | result = count(impl.getChildNode(_)))
|
||||
toGenerated(lhs) = any(DestructuredLhsExprImpl impl | result = count(impl.getChildNode(_)))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
int getRestIndexOrNumberOfElements() {
|
||||
result = tp.getRestIndex()
|
||||
result = lhs.getRestIndex()
|
||||
or
|
||||
toGenerated(tp) = any(TuplePatternImpl impl | not exists(impl.getRestIndex())) and
|
||||
toGenerated(lhs) = any(DestructuredLhsExprImpl impl | not exists(impl.getRestIndex())) and
|
||||
result = this.getNumberOfElements()
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate compoundAssignSynthesis(AstNode parent, int i, Child child) {
|
||||
exists(TupleAssignExpr tae |
|
||||
private predicate destructuredAssignSynthesis(AstNode parent, int i, Child child) {
|
||||
exists(DestructuredAssignExpr tae |
|
||||
parent = tae and
|
||||
i = -1 and
|
||||
child = SynthChild(StmtSequenceKind())
|
||||
@@ -689,8 +689,8 @@ private module CompoundAssignDesugar {
|
||||
child = childRef(tae.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(Pattern p, int j, int restIndex |
|
||||
p = tae.getElement(j) and
|
||||
exists(AstNode elem, int j, int restIndex |
|
||||
elem = tae.getElement(j) and
|
||||
restIndex = tae.getRestIndexOrNumberOfElements()
|
||||
|
|
||||
parent = seq and
|
||||
@@ -700,7 +700,7 @@ private module CompoundAssignDesugar {
|
||||
exists(AstNode assign | assign = TAssignExprSynth(seq, j + 1) |
|
||||
parent = assign and
|
||||
i = 0 and
|
||||
child = childRef(p)
|
||||
child = childRef(elem)
|
||||
or
|
||||
parent = assign and
|
||||
i = 1 and
|
||||
@@ -756,26 +756,26 @@ private module CompoundAssignDesugar {
|
||||
* z = __synth__0[-1];
|
||||
* ```
|
||||
*/
|
||||
private class CompoundAssignSynthesis extends Synthesis {
|
||||
private class DestructuredAssignSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
compoundAssignSynthesis(parent, i, child)
|
||||
destructuredAssignSynthesis(parent, i, child)
|
||||
}
|
||||
|
||||
final override predicate location(AstNode n, Location l) {
|
||||
exists(TupleAssignExpr tae, StmtSequence seq | seq = tae.getDesugared() |
|
||||
exists(DestructuredAssignExpr tae, StmtSequence seq | seq = tae.getDesugared() |
|
||||
n = seq.getStmt(0) and
|
||||
hasLocation(tae.getRightOperand(), l)
|
||||
or
|
||||
exists(Pattern p, int j |
|
||||
p = tae.getElement(j) and
|
||||
exists(AstNode elem, int j |
|
||||
elem = tae.getElement(j) and
|
||||
n = seq.getStmt(j + 1) and
|
||||
hasLocation(p, l)
|
||||
hasLocation(elem, l)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
final override predicate localVariable(AstNode n, int i) {
|
||||
n instanceof TupleAssignExpr and
|
||||
n instanceof DestructuredAssignExpr and
|
||||
i = 0
|
||||
}
|
||||
|
||||
@@ -784,10 +784,6 @@ private module CompoundAssignDesugar {
|
||||
setter = false and
|
||||
arity = 1
|
||||
}
|
||||
|
||||
final override predicate excludeFromControlFlowTree(AstNode n) {
|
||||
n = any(TupleAssignExpr tae).getTuplePattern()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,7 +816,7 @@ private module ArrayLiteralDesugar {
|
||||
* ::Array.[](1, 2, 3)
|
||||
* ```
|
||||
*/
|
||||
private class CompoundAssignSynthesis extends Synthesis {
|
||||
private class ArrayLiteralSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
arrayLiteralSynthesis(parent, i, child)
|
||||
}
|
||||
|
||||
@@ -935,6 +935,10 @@ module Trees {
|
||||
}
|
||||
}
|
||||
|
||||
private class DestructuredParameterTree extends StandardPostOrderTree, DestructuredParameter {
|
||||
final override ControlFlowTree getChildElement(int i) { result = this.getElement(i) }
|
||||
}
|
||||
|
||||
private class DesugaredTree extends ControlFlowTree {
|
||||
ControlFlowTree desugared;
|
||||
|
||||
@@ -1381,10 +1385,6 @@ module Trees {
|
||||
}
|
||||
}
|
||||
|
||||
private class TuplePatternTree extends StandardPostOrderTree, TuplePattern {
|
||||
final override ControlFlowTree getChildElement(int i) { result = this.getElement(i) }
|
||||
}
|
||||
|
||||
private class UndefStmtTree extends StandardPreOrderTree, UndefStmt {
|
||||
final override ControlFlowTree getChildElement(int i) { result = this.getMethodName(i) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user