mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Update AST library
This commit is contained in:
@@ -348,6 +348,9 @@ class CaseExpr extends ControlExpr, TCaseExpr {
|
||||
*/
|
||||
final Expr getABranch() { result = this.getBranch(_) }
|
||||
|
||||
/** Gets the `n`th `when` branch of this case expression. */
|
||||
final WhenExpr getWhenBranch(int n) { result = this.getBranch(n) }
|
||||
|
||||
/** Gets a `when` branch of this case expression. */
|
||||
final WhenExpr getAWhenBranch() { result = this.getABranch() }
|
||||
|
||||
@@ -367,6 +370,10 @@ class CaseExpr extends ControlExpr, TCaseExpr {
|
||||
pred = "getValue" and result = this.getValue()
|
||||
or
|
||||
pred = "getBranch" and result = this.getBranch(_)
|
||||
or
|
||||
pred = "getWhenBranch" and result = this.getWhenBranch(_)
|
||||
or
|
||||
pred = "getElseBranch" and result = this.getElseBranch()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,6 +429,204 @@ class WhenExpr extends Expr, TWhenExpr {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `case` statement used for pattern matching. For example:
|
||||
* ```rb
|
||||
* config = {db: {user: 'admin', password: 'abc123'}}
|
||||
* case config
|
||||
* in db: {user:} # matches subhash and puts matched value in variable user
|
||||
* puts "Connect with user '#{user}'"
|
||||
* in connection: {username: } unless username == 'admin'
|
||||
* puts "Connect with user '#{username}'"
|
||||
* else
|
||||
* puts "Unrecognized structure of config"
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class CaseMatch extends ControlExpr, TCaseMatch {
|
||||
private Ruby::CaseMatch g;
|
||||
|
||||
CaseMatch() { this = TCaseMatch(g) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "CaseMatch" }
|
||||
|
||||
/**
|
||||
* Gets the expression being matched. For example, `foo` in the following example.
|
||||
* ```rb
|
||||
* case foo
|
||||
* in 0
|
||||
* puts 'zero'
|
||||
* in 1
|
||||
* puts 'one'
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
final Expr getValue() { toGenerated(result) = g.getValue() }
|
||||
|
||||
/**
|
||||
* Gets the `n`th branch of this case expression, either an `InClause` or a
|
||||
* `StmtSequence`.
|
||||
*/
|
||||
final Expr getBranch(int n) {
|
||||
toGenerated(result) = g.getClauses(n)
|
||||
or
|
||||
n = count(g.getClauses(_)) and toGenerated(result) = g.getElse()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a branch of this case expression, either an `InClause` or an
|
||||
* `StmtSequence`.
|
||||
*/
|
||||
final Expr getABranch() { result = this.getBranch(_) }
|
||||
|
||||
/** Gets the `n`th `in` clause of this case expression. */
|
||||
final InClause getInClause(int n) { result = this.getBranch(n) }
|
||||
|
||||
/** Gets an `in` clause of this case expression. */
|
||||
final InClause getAnInClause() { result = this.getABranch() }
|
||||
|
||||
/** Gets the `else` branch of this case expression, if any. */
|
||||
final StmtSequence getElseBranch() { result = this.getABranch() }
|
||||
|
||||
/**
|
||||
* Gets the number of branches of this case expression.
|
||||
*/
|
||||
final int getNumberOfBranches() { result = count(this.getBranch(_)) }
|
||||
|
||||
final override string toString() { result = "case ... in" }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getValue" and result = this.getValue()
|
||||
or
|
||||
pred = "getBranch" and result = this.getBranch(_)
|
||||
or
|
||||
pred = "getInClause" and result = this.getInClause(_)
|
||||
or
|
||||
pred = "getElseBranch" and result = this.getElseBranch()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An `in` clause of a `case` expression.
|
||||
* ```rb
|
||||
* case foo
|
||||
* in [ a ] then a
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class InClause extends Expr, TInClause {
|
||||
private Ruby::InClause g;
|
||||
|
||||
InClause() { this = TInClause(g) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "InClause" }
|
||||
|
||||
/** Gets the body of this case-in expression. */
|
||||
final Stmt getBody() { toGenerated(result) = g.getBody() }
|
||||
|
||||
/**
|
||||
* Gets the pattern in this case-in expression. In the
|
||||
* following example, the pattern is `Point{ x:, y: }`.
|
||||
* ```rb
|
||||
* case foo
|
||||
* in Point{ x:, y: }
|
||||
* x + y
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
final CasePattern getPattern() { toGenerated(result) = g.getPattern() }
|
||||
|
||||
/**
|
||||
* Gets the pattern guard in this case-in expression. In the
|
||||
* following example, the pattern guard is `x > 10`.
|
||||
* ```rb
|
||||
* case foo
|
||||
* in [ x ] if x > 10 then ...
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
final PatternGuard getPatternGuard() { toGenerated(result) = g.getGuard() }
|
||||
|
||||
final override string toString() { result = "in ... then ..." }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getBody" and result = this.getBody()
|
||||
or
|
||||
pred = "getPattern" and result = this.getPattern()
|
||||
or
|
||||
pred = "getGuard" and result = this.getPatternGuard()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard used in pattern matching. For example:
|
||||
* ```rb
|
||||
* in pattern if guard
|
||||
* in pattern unless guard
|
||||
* ```
|
||||
*/
|
||||
class PatternGuard extends AstNode, TPatternGuard {
|
||||
/**
|
||||
* Gets the condition expression. For example, the result is `foo` in the
|
||||
* following:
|
||||
* ```rb
|
||||
* if foo
|
||||
* unless foo
|
||||
* ```
|
||||
*/
|
||||
Expr getCondition() { none() }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getCondition" and result = this.getCondition()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An `if` pattern guard. For example:
|
||||
* ```rb
|
||||
* case foo
|
||||
* in [ bar] if bar > 10
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class IfGuard extends PatternGuard, TIfGuard {
|
||||
private Ruby::IfGuard g;
|
||||
|
||||
IfGuard() { this = TIfGuard(g) }
|
||||
|
||||
final override Expr getCondition() { toGenerated(result) = g.getCondition() }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "IfGuard" }
|
||||
|
||||
final override string toString() { result = "if ..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `unless` pattern guard. For example:
|
||||
* ```rb
|
||||
* case foo
|
||||
* in [ bar] unless bar > 10
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class UnlessGuard extends PatternGuard, TUnlessGuard {
|
||||
private Ruby::UnlessGuard g;
|
||||
|
||||
UnlessGuard() { this = TUnlessGuard(g) }
|
||||
|
||||
final override Expr getCondition() { toGenerated(result) = g.getCondition() }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "UnlessGuard" }
|
||||
|
||||
final override string toString() { result = "unless ..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* A loop. That is, a `for` loop, a `while` or `until` loop, or their
|
||||
* expression-modifier variants.
|
||||
|
||||
@@ -223,6 +223,40 @@ private class FalseLiteral extends BooleanLiteral, TFalseLiteral {
|
||||
final override predicate isFalse() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `__ENCODING__` literal.
|
||||
*/
|
||||
class EncodingLiteral extends Literal, TEncoding {
|
||||
final override string getAPrimaryQlClass() { result = "EncodingLiteral" }
|
||||
|
||||
final override string toString() { result = "__ENCODING__" }
|
||||
|
||||
// TODO: return the encoding defined by a magic encoding: comment, if any.
|
||||
override string getValueText() { result = "UTF-8" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `__LINE__` literal.
|
||||
*/
|
||||
class LineLiteral extends Literal, TLine {
|
||||
final override string getAPrimaryQlClass() { result = "LineLiteral" }
|
||||
|
||||
final override string toString() { result = "__LINE__" }
|
||||
|
||||
override string getValueText() { result = this.getLocation().getStartLine().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `__FILE__` literal.
|
||||
*/
|
||||
class FileLiteral extends Literal, TFile {
|
||||
final override string getAPrimaryQlClass() { result = "FileLiteral" }
|
||||
|
||||
final override string toString() { result = "__FILE__" }
|
||||
|
||||
override string getValueText() { result = this.getLocation().getFile().getAbsolutePath() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The base class for a component of a string: `StringTextComponent`,
|
||||
* `StringEscapeSequenceComponent`, or `StringInterpolationComponent`.
|
||||
|
||||
@@ -131,6 +131,23 @@ class HashSplatParameter extends NamedParameter, THashSplatParameter {
|
||||
final override string getName() { result = g.getName().getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `nil` hash splat (`**nil`) indicating that there are no keyword parameters or keyword patterns.
|
||||
* For example:
|
||||
* ```rb
|
||||
* def foo(bar, **nil)
|
||||
* case bar
|
||||
* in { x:, **nil } then puts x
|
||||
* end
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class HashSplatNilParameter extends Parameter, THashSplatNilParameter {
|
||||
final override string getAPrimaryQlClass() { result = "HashSplatNilParameter" }
|
||||
|
||||
final override string toString() { result = "**nil" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A keyword parameter, including a default value if the parameter is optional.
|
||||
* For example, in the following example, `foo` is a keyword parameter with a
|
||||
|
||||
@@ -97,3 +97,322 @@ class TuplePattern extends Pattern, TTuplePattern {
|
||||
|
||||
override AstNode getAChild(string pred) { pred = "getElement" and result = this.getElement(_) }
|
||||
}
|
||||
|
||||
private class TPatternNode =
|
||||
TArrayPattern or TFindPattern or THashPattern or TAlternativePattern or TAsPattern or
|
||||
TVariableReferencePattern;
|
||||
|
||||
private class TPattern =
|
||||
TPatternNode or TLiteral or TLambda or TConstantAccess or TLocalVariableAccess or
|
||||
TUnaryArithmeticOperation;
|
||||
|
||||
/**
|
||||
* A pattern used in a `case-in` expression. For example
|
||||
* ```rb
|
||||
* case expr
|
||||
* in [ x ] then ...
|
||||
* in Point(a:, b:) then ...
|
||||
* in Integer => x then ...
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class CasePattern extends AstNode, TPattern {
|
||||
CasePattern() { casePattern(toGenerated(this)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An array pattern, for example:
|
||||
* ```rb
|
||||
* in []
|
||||
* in ["first", Integer => x, "last"]
|
||||
* in ["a", Integer => x, *]
|
||||
* in ["a", Integer => x, ]
|
||||
* in [1, 2, *x, 7, 8]
|
||||
* in [*init, 7, 8]
|
||||
* in List["a", Integer => x, *tail]
|
||||
* ```
|
||||
*/
|
||||
class ArrayPattern extends CasePattern, TArrayPattern {
|
||||
private Ruby::ArrayPattern g;
|
||||
|
||||
ArrayPattern() { this = TArrayPattern(g) }
|
||||
|
||||
/** Gets the class this pattern matches objects against, if any. */
|
||||
ConstantReadAccess getClass() { toGenerated(result) = g.getClass() }
|
||||
|
||||
/**
|
||||
* Gets the `n`th element of this list pattern's prefix, i.e. the elements `1, ^two, 3`
|
||||
* in the following examples:
|
||||
* ```
|
||||
* in [ 1, ^two, 3 ]
|
||||
* in [ 1, ^two, 3, ]
|
||||
* in [ 1, ^two, 3, *, 4 , 5]
|
||||
* in [ 1, ^two, 3, *more]
|
||||
* ```
|
||||
*/
|
||||
CasePattern getPrefixElement(int n) {
|
||||
toGenerated(result) = g.getChild(n) and
|
||||
(
|
||||
n < this.restIndex()
|
||||
or
|
||||
not exists(restIndex())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `n`th element of this list pattern's suffix, i.e. the elements `4, 5`
|
||||
* in the following examples:
|
||||
* ```
|
||||
* in [ *, 4, 5 ]
|
||||
* in [ 1, 2, 3, *middle, 4 , 5]
|
||||
* ```
|
||||
*/
|
||||
CasePattern getSuffixElement(int n) { toGenerated(result) = g.getChild(n + this.restIndex() + 1) }
|
||||
|
||||
/**
|
||||
* Gets the variable of the rest token, if any. For example `middle` in `the following array pattern.
|
||||
* ```rb
|
||||
* [ 1, 2, 3, *middle, 4 , 5]
|
||||
* ```
|
||||
*/
|
||||
LocalVariableWriteAccess getRestVariable() {
|
||||
toGenerated(result) = g.getChild(restIndex()).(Ruby::SplatParameter).getName()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this pattern permits any unmatched remaining elements, i.e. the pattern does not have a trailing `,`
|
||||
* and does not contain a rest token (`*` or `*name`) either.
|
||||
*/
|
||||
predicate allowUnmatchedElements() { not exists(this.restIndex()) }
|
||||
|
||||
private int restIndex() { g.getChild(result) instanceof Ruby::SplatParameter }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "ArrayPattern" }
|
||||
|
||||
final override string toString() { result = "[ ..., * ]" }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getClass" and result = this.getClass()
|
||||
or
|
||||
pred = "getPrefixElement" and result = this.getPrefixElement(_)
|
||||
or
|
||||
pred = "getSuffixElement" and result = this.getSuffixElement(_)
|
||||
or
|
||||
pred = "getRestVariable" and result = this.getRestVariable()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A find pattern, for example:
|
||||
* ```rb
|
||||
* in [*, "a", Integer => x, *]
|
||||
* in List[*init, "a", Integer => x, *tail]
|
||||
* in List[*, "a", Integer => x, *]
|
||||
* ```
|
||||
*/
|
||||
class FindPattern extends CasePattern, TFindPattern {
|
||||
private Ruby::FindPattern g;
|
||||
|
||||
FindPattern() { this = TFindPattern(g) }
|
||||
|
||||
/** Gets the class this pattern matches objects against, if any. */
|
||||
ConstantReadAccess getClass() { toGenerated(result) = g.getClass() }
|
||||
|
||||
/** Gets the `n`th element of this list pattern. */
|
||||
CasePattern getElement(int n) { toGenerated(result) = g.getChild(n + 1) }
|
||||
|
||||
/** Gets an element of this list pattern. */
|
||||
CasePattern getAnElement() { result = this.getElement(_) }
|
||||
|
||||
/**
|
||||
* Gets the variable for the prefix of this list pattern, if any. For example `init` in:
|
||||
* ```rb
|
||||
* in List[*init, "a", Integer => x, *tail]
|
||||
* ```
|
||||
*/
|
||||
LocalVariableWriteAccess getPrefix() {
|
||||
toGenerated(result) = g.getChild(0).(Ruby::SplatParameter).getName()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the variable for the suffix of this list pattern, if any. For example `tail` in:
|
||||
* ```rb
|
||||
* in List[*init, "a", Integer => x, *tail]
|
||||
* ```
|
||||
*/
|
||||
LocalVariableWriteAccess getSuffix() {
|
||||
toGenerated(result) = max(int i | | g.getChild(i) order by i).(Ruby::SplatParameter).getName()
|
||||
}
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "FindPattern" }
|
||||
|
||||
final override string toString() { result = "[ *,...,* ]" }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getClass" and result = this.getClass()
|
||||
or
|
||||
pred = "getElement" and result = this.getElement(_)
|
||||
or
|
||||
pred = "getPrefix" and result = this.getPrefix()
|
||||
or
|
||||
pred = "getSuffix" and result = this.getSuffix()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A hash pattern, for example:
|
||||
* ```rb
|
||||
* in {}
|
||||
* in { a: 1 }
|
||||
* in { a: 1, **rest }
|
||||
* in { a: 1, **nil }
|
||||
* in Node{ label: , children: [] }
|
||||
* ```
|
||||
*/
|
||||
class HashPattern extends CasePattern, THashPattern {
|
||||
private Ruby::HashPattern g;
|
||||
|
||||
HashPattern() { this = THashPattern(g) }
|
||||
|
||||
/** Gets the class this pattern matches objects against, if any. */
|
||||
ConstantReadAccess getClass() { toGenerated(result) = g.getClass() }
|
||||
|
||||
private Ruby::KeywordPattern keyValuePair(int n) { result = g.getChild(n) }
|
||||
|
||||
/** Gets the key of the `n`th pair. */
|
||||
StringlikeLiteral getKey(int n) { toGenerated(result) = keyValuePair(n).getKey() }
|
||||
|
||||
/** Gets the value of the `n`th pair. */
|
||||
CasePattern getValue(int n) { toGenerated(result) = keyValuePair(n).getValue() }
|
||||
|
||||
/** Gets the value for a given key name. */
|
||||
CasePattern getValueByKey(string key) {
|
||||
exists(int i | key = this.getKey(i).getValueText() and result = this.getValue(i))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the variable of the keyword rest token, if any. For example `rest` in:
|
||||
* ```rb
|
||||
* in { a: 1, **rest }
|
||||
* ```
|
||||
*/
|
||||
LocalVariableWriteAccess getRestVariable() {
|
||||
toGenerated(result) =
|
||||
max(int i | | g.getChild(i) order by i).(Ruby::HashSplatParameter).getName()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this pattern is terminated by `**nil` indicating that the pattern does not permit
|
||||
* any unmatched remaining pairs.
|
||||
*/
|
||||
predicate allowUnmatchedElements() { g.getChild(_) instanceof Ruby::HashSplatNil }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "HashPattern" }
|
||||
|
||||
final override string toString() { result = "{ ..., ** }" }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getClass" and result = this.getClass()
|
||||
or
|
||||
pred = "getKey" and result = this.getKey(_)
|
||||
or
|
||||
pred = "getValue" and result = this.getValue(_)
|
||||
or
|
||||
pred = "getRestVariable" and result = this.getRestVariable()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A composite pattern matching one of the given sub-patterns, for example:
|
||||
* ```rb
|
||||
* in 1 | 2 | 3
|
||||
* ```
|
||||
*/
|
||||
class AlternativePattern extends CasePattern, TAlternativePattern {
|
||||
private Ruby::AlternativePattern g;
|
||||
|
||||
AlternativePattern() { this = TAlternativePattern(g) }
|
||||
|
||||
/** Gets the `n`th alternative of this pattern. */
|
||||
CasePattern getAlternative(int n) { toGenerated(result) = g.getAlternatives(n) }
|
||||
|
||||
/** Gets an alternative of this pattern. */
|
||||
CasePattern getAnAlternative() { result = this.getAlternative(_) }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "AlternativePattern" }
|
||||
|
||||
final override string toString() { result = "... | ..." }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getAlternative" and result = this.getAlternative(_)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A pattern match that binds to the specified local variable, for example `Integer => a`
|
||||
* in the following:
|
||||
* ```rb
|
||||
* case 1
|
||||
* in Integer => a then puts "#{a} is an integer value"
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class AsPattern extends CasePattern, TAsPattern {
|
||||
private Ruby::AsPattern g;
|
||||
|
||||
AsPattern() { this = TAsPattern(g) }
|
||||
|
||||
/** Gets the underlying pattern. */
|
||||
CasePattern getValue() { toGenerated(result) = g.getValue() }
|
||||
|
||||
/** Gets the variable access for this pattern. */
|
||||
LocalVariableWriteAccess getVariableAccess() { toGenerated(result) = g.getName() }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "AsPattern" }
|
||||
|
||||
final override string toString() { result = "... => ..." }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getValue" and result = this.getValue()
|
||||
or
|
||||
pred = "getVariableAccess" and result = this.getVariableAccess()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A variable reference in a pattern, i.e. `^x` in the following example:
|
||||
* ```rb
|
||||
* x = 10
|
||||
* case expr
|
||||
* in ^x then puts "ok"
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class VariableReferencePattern extends CasePattern, TVariableReferencePattern {
|
||||
private Ruby::VariableReferencePattern g;
|
||||
|
||||
VariableReferencePattern() { this = TVariableReferencePattern(g) }
|
||||
|
||||
/** Gets the variable access correspinging to this variable reference pattern. */
|
||||
LocalVariableReadAccess getVariableAccess() { toGenerated(result) = g.getName() }
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "VariableReferencePattern" }
|
||||
|
||||
final override string toString() { result = "^..." }
|
||||
|
||||
final override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = "getVariableAccess" and result = this.getVariableAccess()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import codeql.Locations
|
||||
private import TreeSitter
|
||||
private import codeql.ruby.ast.internal.Call
|
||||
private import codeql.ruby.ast.internal.Parameter
|
||||
private import codeql.ruby.ast.internal.Pattern
|
||||
private import codeql.ruby.ast.internal.Variable
|
||||
private import codeql.ruby.AST as AST
|
||||
private import Synthesis
|
||||
@@ -30,6 +31,7 @@ private module Cached {
|
||||
TAddExprReal(Ruby::Binary g) { g instanceof @ruby_binary_plus } or
|
||||
TAddExprSynth(AST::AstNode parent, int i) { mkSynthChild(AddExprKind(), parent, i) } or
|
||||
TAliasStmt(Ruby::Alias g) or
|
||||
TAlternativePattern(Ruby::AlternativePattern g) or
|
||||
TArgumentList(Ruby::AstNode g) {
|
||||
(
|
||||
g.getParent() instanceof Ruby::Break or
|
||||
@@ -44,6 +46,7 @@ private module Cached {
|
||||
g instanceof Ruby::RightAssignmentList
|
||||
)
|
||||
} or
|
||||
TArrayPattern(Ruby::ArrayPattern g) or
|
||||
TAssignAddExpr(Ruby::OperatorAssignment g) { g instanceof @ruby_operator_assignment_plusequal } or
|
||||
TAssignBitwiseAndExpr(Ruby::OperatorAssignment g) {
|
||||
g instanceof @ruby_operator_assignment_ampersandequal
|
||||
@@ -77,6 +80,7 @@ private module Cached {
|
||||
g instanceof @ruby_operator_assignment_ranglerangleequal
|
||||
} or
|
||||
TAssignSubExpr(Ruby::OperatorAssignment g) { g instanceof @ruby_operator_assignment_minusequal } or
|
||||
TAsPattern(Ruby::AsPattern g) or
|
||||
TBareStringLiteral(Ruby::BareString g) or
|
||||
TBareSymbolLiteral(Ruby::BareSymbol g) or
|
||||
TBeginBlock(Ruby::BeginBlock g) or
|
||||
@@ -98,6 +102,7 @@ private module Cached {
|
||||
TBreakStmt(Ruby::Break g) or
|
||||
TCaseEqExpr(Ruby::Binary g) { g instanceof @ruby_binary_equalequalequal } or
|
||||
TCaseExpr(Ruby::Case g) or
|
||||
TCaseMatch(Ruby::CaseMatch g) or
|
||||
TCharacterLiteral(Ruby::Character g) or
|
||||
TClassDeclaration(Ruby::Class g) or
|
||||
TClassVariableAccessReal(Ruby::ClassVariable g, AST::ClassVariable v) {
|
||||
@@ -124,12 +129,15 @@ private module Cached {
|
||||
TElse(Ruby::Else g) or
|
||||
TElsif(Ruby::Elsif g) or
|
||||
TEmptyStmt(Ruby::EmptyStatement g) or
|
||||
TEncoding(Ruby::Encoding g) or
|
||||
TEndBlock(Ruby::EndBlock g) or
|
||||
TEnsure(Ruby::Ensure g) or
|
||||
TEqExpr(Ruby::Binary g) { g instanceof @ruby_binary_equalequal } or
|
||||
TExponentExprReal(Ruby::Binary g) { g instanceof @ruby_binary_starstar } or
|
||||
TExponentExprSynth(AST::AstNode parent, int i) { mkSynthChild(ExponentExprKind(), parent, i) } or
|
||||
TFalseLiteral(Ruby::False g) or
|
||||
TFile(Ruby::File g) or
|
||||
TFindPattern(Ruby::FindPattern g) or
|
||||
TFloatLiteral(Ruby::Float g) { not any(Ruby::Rational r).getChild() = g } or
|
||||
TForExpr(Ruby::For g) or
|
||||
TForwardParameter(Ruby::ForwardParameter g) or
|
||||
@@ -144,12 +152,18 @@ private module Cached {
|
||||
} or
|
||||
THashKeySymbolLiteral(Ruby::HashKeySymbol g) or
|
||||
THashLiteral(Ruby::Hash g) or
|
||||
THashPattern(Ruby::HashPattern g) or
|
||||
THashSplatExpr(Ruby::HashSplatArgument g) or
|
||||
THashSplatParameter(Ruby::HashSplatParameter g) or
|
||||
THashSplatNilParameter(Ruby::HashSplatNil g) { not g.getParent() instanceof Ruby::HashPattern } or
|
||||
THashSplatParameter(Ruby::HashSplatParameter g) {
|
||||
not g.getParent() instanceof Ruby::HashPattern
|
||||
} or
|
||||
THereDoc(Ruby::HeredocBeginning g) or
|
||||
TIdentifierMethodCall(Ruby::Identifier g) { isIdentifierMethodCall(g) } or
|
||||
TIf(Ruby::If g) or
|
||||
TIfGuard(Ruby::IfGuard g) or
|
||||
TIfModifierExpr(Ruby::IfModifier g) or
|
||||
TInClause(Ruby::InClause g) or
|
||||
TInstanceVariableAccessReal(Ruby::InstanceVariable g, AST::InstanceVariable v) {
|
||||
InstanceVariableAccess::range(g, v)
|
||||
} or
|
||||
@@ -166,6 +180,7 @@ private module Cached {
|
||||
TLShiftExprSynth(AST::AstNode parent, int i) { mkSynthChild(LShiftExprKind(), parent, i) } or
|
||||
TLTExpr(Ruby::Binary g) { g instanceof @ruby_binary_langle } or
|
||||
TLambda(Ruby::Lambda g) or
|
||||
TLine(Ruby::Line g) or
|
||||
TLeftAssignmentList(Ruby::LeftAssignmentList g) or
|
||||
TLocalVariableAccessReal(Ruby::Identifier g, TLocalVariableReal v) {
|
||||
LocalVariableAccess::range(g, v)
|
||||
@@ -229,6 +244,10 @@ private module Cached {
|
||||
vcall(g)
|
||||
or
|
||||
explicitAssignmentNode(g, _)
|
||||
or
|
||||
casePattern(g)
|
||||
or
|
||||
classReferencePattern(g)
|
||||
)
|
||||
} or
|
||||
TScopeResolutionMethodCall(Ruby::ScopeResolution g, Ruby::Identifier i) {
|
||||
@@ -248,7 +267,10 @@ private module Cached {
|
||||
TSpaceshipExpr(Ruby::Binary g) { g instanceof @ruby_binary_langleequalrangle } or
|
||||
TSplatExprReal(Ruby::SplatArgument g) or
|
||||
TSplatExprSynth(AST::AstNode parent, int i) { mkSynthChild(SplatExprKind(), parent, i) } or
|
||||
TSplatParameter(Ruby::SplatParameter g) or
|
||||
TSplatParameter(Ruby::SplatParameter g) {
|
||||
not g.getParent() instanceof Ruby::ArrayPattern and
|
||||
not g.getParent() instanceof Ruby::FindPattern
|
||||
} or
|
||||
TStmtSequenceSynth(AST::AstNode parent, int i) { mkSynthChild(StmtSequenceKind(), parent, i) } or
|
||||
TStringArrayLiteral(Ruby::StringArray g) or
|
||||
TStringConcatenation(Ruby::ChainedString g) or
|
||||
@@ -269,6 +291,10 @@ private module Cached {
|
||||
vcall(g)
|
||||
or
|
||||
explicitAssignmentNode(g, _)
|
||||
or
|
||||
casePattern(g)
|
||||
or
|
||||
classReferencePattern(g)
|
||||
} or
|
||||
TTokenMethodName(MethodName::Token g) { MethodName::range(g) } or
|
||||
TTokenSuperCall(Ruby::Super g) { vcall(g) } or
|
||||
@@ -279,31 +305,36 @@ private module Cached {
|
||||
TUnaryPlusExpr(Ruby::Unary g) { g instanceof @ruby_unary_plus } or
|
||||
TUndefStmt(Ruby::Undef g) or
|
||||
TUnlessExpr(Ruby::Unless g) or
|
||||
TUnlessGuard(Ruby::UnlessGuard g) or
|
||||
TUnlessModifierExpr(Ruby::UnlessModifier g) or
|
||||
TUntilExpr(Ruby::Until g) or
|
||||
TUntilModifierExpr(Ruby::UntilModifier g) or
|
||||
TVariableReferencePattern(Ruby::VariableReferencePattern g) or
|
||||
TWhenExpr(Ruby::When g) or
|
||||
TWhileExpr(Ruby::While g) or
|
||||
TWhileModifierExpr(Ruby::WhileModifier g) or
|
||||
TYieldCall(Ruby::Yield g)
|
||||
|
||||
class TAstNodeReal =
|
||||
TAddExprReal or TAliasStmt or TArgumentList or TAssignAddExpr or TAssignBitwiseAndExpr or
|
||||
TAssignBitwiseOrExpr or TAssignBitwiseXorExpr or TAssignDivExpr or TAssignExponentExpr or
|
||||
TAssignExprReal or TAssignLShiftExpr or TAssignLogicalAndExpr or TAssignLogicalOrExpr or
|
||||
TAssignModuloExpr or TAssignMulExpr or TAssignRShiftExpr or TAssignSubExpr or
|
||||
TBareStringLiteral or TBareSymbolLiteral or TBeginBlock or TBeginExpr or
|
||||
TBitwiseAndExprReal or TBitwiseOrExprReal or TBitwiseXorExprReal or TBlockArgument or
|
||||
TBlockParameter or TBraceBlockReal or TBreakStmt or TCaseEqExpr or TCaseExpr or
|
||||
TAddExprReal or TAliasStmt or TAlternativePattern or TArgumentList or TArrayPattern or
|
||||
TAsPattern or TAssignAddExpr or TAssignBitwiseAndExpr or TAssignBitwiseOrExpr or
|
||||
TAssignBitwiseXorExpr or TAssignDivExpr or TAssignExponentExpr or TAssignExprReal or
|
||||
TAssignLShiftExpr or TAssignLogicalAndExpr or TAssignLogicalOrExpr or TAssignModuloExpr or
|
||||
TAssignMulExpr or TAssignRShiftExpr or TAssignSubExpr or TBareStringLiteral or
|
||||
TBareSymbolLiteral or TBeginBlock or TBeginExpr or TBitwiseAndExprReal or
|
||||
TBitwiseOrExprReal or TBitwiseXorExprReal or TBlockArgument or TBlockParameter or
|
||||
TBraceBlockReal or TBreakStmt or TCaseEqExpr or TCaseExpr or TCaseMatch or
|
||||
TCharacterLiteral or TClassDeclaration or TClassVariableAccessReal or TComplementExpr or
|
||||
TComplexLiteral or TDefinedExpr or TDelimitedSymbolLiteral or TDestructuredLeftAssignment or
|
||||
TDivExprReal or TDo or TDoBlock or TElementReference or TElse or TElsif or TEmptyStmt or
|
||||
TEndBlock or TEnsure or TEqExpr or TExponentExprReal or TFalseLiteral or TFloatLiteral or
|
||||
TForExpr or TForwardParameter or TForwardArgument or TGEExpr or TGTExpr or
|
||||
TGlobalVariableAccessReal or THashKeySymbolLiteral or THashLiteral or THashSplatExpr or
|
||||
THashSplatParameter or THereDoc or TIdentifierMethodCall or TIf or TIfModifierExpr or
|
||||
TInstanceVariableAccessReal or TIntegerLiteralReal or TKeywordParameter or TLEExpr or
|
||||
TLShiftExprReal or TLTExpr or TLambda or TLeftAssignmentList or TLocalVariableAccessReal or
|
||||
TEncoding or TEndBlock or TEnsure or TEqExpr or TExponentExprReal or TFalseLiteral or
|
||||
TFile or TFindPattern or TFloatLiteral or TForExpr or TForwardParameter or
|
||||
TForwardArgument or TGEExpr or TGTExpr or TGlobalVariableAccessReal or
|
||||
THashKeySymbolLiteral or THashLiteral or THashPattern or THashSplatExpr or
|
||||
THashSplatNilParameter or THashSplatParameter or THereDoc or TIdentifierMethodCall or TIf or
|
||||
TIfGuard or TIfModifierExpr or TInClause or TInstanceVariableAccessReal or
|
||||
TIntegerLiteralReal or TKeywordParameter or TLEExpr or TLShiftExprReal or TLTExpr or
|
||||
TLambda or TLeftAssignmentList or TLine or TLocalVariableAccessReal or
|
||||
TLogicalAndExprReal or TLogicalOrExprReal or TMethod or TModuleDeclaration or
|
||||
TModuloExprReal or TMulExprReal or TNEExpr or TNextStmt or TNilLiteral or
|
||||
TNoRegExpMatchExpr or TNotExpr or TOptionalParameter or TPair or TParenthesizedExpr or
|
||||
@@ -317,8 +348,9 @@ private module Cached {
|
||||
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
|
||||
TUndefStmt or TUnlessExpr or TUnlessModifierExpr or TUntilExpr or TUntilModifierExpr or
|
||||
TWhenExpr or TWhileExpr or TWhileModifierExpr or TYieldCall;
|
||||
TUndefStmt or TUnlessExpr or TUnlessGuard or TUnlessModifierExpr or TUntilExpr or
|
||||
TUntilModifierExpr or TVariableReferencePattern or TWhenExpr or TWhileExpr or
|
||||
TWhileModifierExpr or TYieldCall;
|
||||
|
||||
class TAstNodeSynth =
|
||||
TAddExprSynth or TAssignExprSynth or TBitwiseAndExprSynth or TBitwiseOrExprSynth or
|
||||
@@ -339,7 +371,10 @@ private module Cached {
|
||||
Ruby::AstNode toGenerated(TAstNodeReal n) {
|
||||
n = TAddExprReal(result) or
|
||||
n = TAliasStmt(result) or
|
||||
n = TAlternativePattern(result) or
|
||||
n = TArgumentList(result) or
|
||||
n = TArrayPattern(result) or
|
||||
n = TAsPattern(result) or
|
||||
n = TAssignAddExpr(result) or
|
||||
n = TAssignBitwiseAndExpr(result) or
|
||||
n = TAssignBitwiseOrExpr(result) or
|
||||
@@ -347,9 +382,9 @@ private module Cached {
|
||||
n = TAssignDivExpr(result) or
|
||||
n = TAssignExponentExpr(result) or
|
||||
n = TAssignExprReal(result) or
|
||||
n = TAssignLShiftExpr(result) or
|
||||
n = TAssignLogicalAndExpr(result) or
|
||||
n = TAssignLogicalOrExpr(result) or
|
||||
n = TAssignLShiftExpr(result) or
|
||||
n = TAssignModuloExpr(result) or
|
||||
n = TAssignMulExpr(result) or
|
||||
n = TAssignRShiftExpr(result) or
|
||||
@@ -367,6 +402,7 @@ private module Cached {
|
||||
n = TBreakStmt(result) or
|
||||
n = TCaseEqExpr(result) or
|
||||
n = TCaseExpr(result) or
|
||||
n = TCaseMatch(result) or
|
||||
n = TCharacterLiteral(result) or
|
||||
n = TClassDeclaration(result) or
|
||||
n = TClassVariableAccessReal(result, _) or
|
||||
@@ -376,43 +412,51 @@ private module Cached {
|
||||
n = TDelimitedSymbolLiteral(result) or
|
||||
n = TDestructuredLeftAssignment(result) or
|
||||
n = TDivExprReal(result) or
|
||||
n = TDo(result) or
|
||||
n = TDoBlock(result) or
|
||||
n = TDo(result) or
|
||||
n = TElementReference(result) or
|
||||
n = TElse(result) or
|
||||
n = TElsif(result) or
|
||||
n = TEmptyStmt(result) or
|
||||
n = TEncoding(result) or
|
||||
n = TEndBlock(result) or
|
||||
n = TEnsure(result) or
|
||||
n = TEqExpr(result) or
|
||||
n = TExponentExprReal(result) or
|
||||
n = TFalseLiteral(result) or
|
||||
n = TFile(result) or
|
||||
n = TFindPattern(result) or
|
||||
n = TFloatLiteral(result) or
|
||||
n = TForExpr(result) or
|
||||
n = TForwardArgument(result) or
|
||||
n = TForwardParameter(result) or
|
||||
n = TGEExpr(result) or
|
||||
n = TGTExpr(result) or
|
||||
n = TGlobalVariableAccessReal(result, _) or
|
||||
n = TGTExpr(result) or
|
||||
n = THashKeySymbolLiteral(result) or
|
||||
n = THashLiteral(result) or
|
||||
n = THashPattern(result) or
|
||||
n = THashSplatExpr(result) or
|
||||
n = THashSplatNilParameter(result) or
|
||||
n = THashSplatParameter(result) or
|
||||
n = THereDoc(result) or
|
||||
n = TIdentifierMethodCall(result) or
|
||||
n = TIf(result) or
|
||||
n = TIfGuard(result) or
|
||||
n = TIfModifierExpr(result) or
|
||||
n = TIf(result) or
|
||||
n = TInClause(result) or
|
||||
n = TInstanceVariableAccessReal(result, _) or
|
||||
n = TIntegerLiteralReal(result) or
|
||||
n = TKeywordParameter(result) or
|
||||
n = TLEExpr(result) or
|
||||
n = TLShiftExprReal(result) or
|
||||
n = TLTExpr(result) or
|
||||
n = TLambda(result) or
|
||||
n = TLEExpr(result) or
|
||||
n = TLeftAssignmentList(result) or
|
||||
n = TLine(result) or
|
||||
n = TLocalVariableAccessReal(result, _) or
|
||||
n = TLogicalAndExprReal(result) or
|
||||
n = TLogicalOrExprReal(result) or
|
||||
n = TLShiftExprReal(result) or
|
||||
n = TLTExpr(result) or
|
||||
n = TMethod(result) or
|
||||
n = TModuleDeclaration(result) or
|
||||
n = TModuloExprReal(result) or
|
||||
@@ -425,7 +469,6 @@ private module Cached {
|
||||
n = TOptionalParameter(result) or
|
||||
n = TPair(result) or
|
||||
n = TParenthesizedExpr(result) or
|
||||
n = TRShiftExprReal(result) or
|
||||
n = TRangeLiteralReal(result) or
|
||||
n = TRationalLiteral(result) or
|
||||
n = TRedoStmt(result) or
|
||||
@@ -439,6 +482,7 @@ private module Cached {
|
||||
n = TRescueModifierExpr(result) or
|
||||
n = TRetryStmt(result) or
|
||||
n = TReturnStmt(result) or
|
||||
n = TRShiftExprReal(result) or
|
||||
n = TScopeResolutionConstantAccess(result, _) or
|
||||
n = TScopeResolutionMethodCall(result, _) or
|
||||
n = TSelfReal(result) or
|
||||
@@ -469,9 +513,11 @@ private module Cached {
|
||||
n = TUnaryPlusExpr(result) or
|
||||
n = TUndefStmt(result) or
|
||||
n = TUnlessExpr(result) or
|
||||
n = TUnlessGuard(result) or
|
||||
n = TUnlessModifierExpr(result) or
|
||||
n = TUntilExpr(result) or
|
||||
n = TUntilModifierExpr(result) or
|
||||
n = TVariableReferencePattern(result) or
|
||||
n = TWhenExpr(result) or
|
||||
n = TWhileExpr(result) or
|
||||
n = TWhileModifierExpr(result) or
|
||||
@@ -591,11 +637,13 @@ class TSuperCall = TTokenSuperCall or TRegularSuperCall;
|
||||
class TConstantAccess =
|
||||
TTokenConstantAccess or TScopeResolutionConstantAccess or TNamespace or TConstantReadAccessSynth;
|
||||
|
||||
class TControlExpr = TConditionalExpr or TCaseExpr or TLoop;
|
||||
class TControlExpr = TConditionalExpr or TCaseExpr or TCaseMatch or TLoop;
|
||||
|
||||
class TConditionalExpr =
|
||||
TIfExpr or TUnlessExpr or TIfModifierExpr or TUnlessModifierExpr or TTernaryIfExpr;
|
||||
|
||||
class TPatternGuard = TIfGuard or TUnlessGuard;
|
||||
|
||||
class TIfExpr = TIf or TElsif;
|
||||
|
||||
class TConditionalLoop = TWhileExpr or TUntilExpr or TWhileModifierExpr or TUntilModifierExpr;
|
||||
@@ -605,10 +653,10 @@ class TLoop = TConditionalLoop or TForExpr;
|
||||
class TSelf = TSelfReal or TSelfSynth;
|
||||
|
||||
class TExpr =
|
||||
TSelf or TArgumentList 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;
|
||||
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;
|
||||
|
||||
class TSplatExpr = TSplatExprReal or TSplatExprSynth;
|
||||
|
||||
@@ -619,8 +667,9 @@ class TStmtSequence =
|
||||
class TBodyStmt = TBeginExpr or TModuleBase or TMethod or TLambda or TDoBlock or TSingletonMethod;
|
||||
|
||||
class TLiteral =
|
||||
TNumericLiteral or TNilLiteral or TBooleanLiteral or TStringlikeLiteral or TCharacterLiteral or
|
||||
TArrayLiteral or THashLiteral or TRangeLiteral or TTokenMethodName;
|
||||
TEncoding or TFile or TLine or TNumericLiteral or TNilLiteral or TBooleanLiteral or
|
||||
TStringlikeLiteral or TCharacterLiteral or TArrayLiteral or THashLiteral or TRangeLiteral or
|
||||
TTokenMethodName;
|
||||
|
||||
class TNumericLiteral = TIntegerLiteral or TFloatLiteral or TRationalLiteral or TComplexLiteral;
|
||||
|
||||
@@ -736,8 +785,8 @@ class TStmt =
|
||||
class TReturningStmt = TReturnStmt or TBreakStmt or TNextStmt;
|
||||
|
||||
class TParameter =
|
||||
TPatternParameter or TBlockParameter or THashSplatParameter or TKeywordParameter or
|
||||
TOptionalParameter or TSplatParameter or TForwardParameter;
|
||||
TPatternParameter or TBlockParameter or THashSplatParameter or THashSplatNilParameter or
|
||||
TKeywordParameter or TOptionalParameter or TSplatParameter or TForwardParameter;
|
||||
|
||||
class TSimpleParameter = TSimpleParameterReal or TSimpleParameterSynth;
|
||||
|
||||
|
||||
@@ -30,3 +30,32 @@ class LeftAssignmentListImpl extends TuplePatternImpl, Ruby::LeftAssignmentList
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is a case pattern.
|
||||
*/
|
||||
predicate casePattern(Ruby::AstNode node) {
|
||||
node = any(Ruby::InClause parent).getPattern()
|
||||
or
|
||||
node = any(Ruby::ArrayPattern parent).getChild(_).(Ruby::UnderscorePatternExpr)
|
||||
or
|
||||
node = any(Ruby::FindPattern parent).getChild(_).(Ruby::UnderscorePatternExpr)
|
||||
or
|
||||
node = any(Ruby::AlternativePattern parent).getAlternatives(_)
|
||||
or
|
||||
node = any(Ruby::AsPattern parent).getValue()
|
||||
or
|
||||
node = any(Ruby::KeywordPattern parent).getValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is a class reference used in an
|
||||
* array, find, or hash pattern.
|
||||
*/
|
||||
predicate classReferencePattern(Ruby::AstNode node) {
|
||||
node = any(Ruby::ArrayPattern p).getClass()
|
||||
or
|
||||
node = any(Ruby::FindPattern p).getClass()
|
||||
or
|
||||
node = any(Ruby::HashPattern p).getClass()
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ private import codeql.Locations
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.ast.internal.AST
|
||||
private import codeql.ruby.ast.internal.Parameter
|
||||
private import codeql.ruby.ast.internal.Pattern
|
||||
private import codeql.ruby.ast.internal.Scope
|
||||
private import codeql.ruby.ast.internal.Synthesis
|
||||
|
||||
@@ -28,6 +29,16 @@ predicate explicitAssignmentNode(Ruby::AstNode n, Ruby::AstNode assignment) {
|
||||
|
||||
/** Holds if `n` is inside an implicit assignment. */
|
||||
predicate implicitAssignmentNode(Ruby::AstNode n) {
|
||||
casePattern(n) and n instanceof Ruby::Identifier
|
||||
or
|
||||
n = any(Ruby::AsPattern p).getName()
|
||||
or
|
||||
n = any(Ruby::ArrayPattern parent).getChild(_).(Ruby::SplatParameter).getName()
|
||||
or
|
||||
n = any(Ruby::FindPattern parent).getChild(_).(Ruby::SplatParameter).getName()
|
||||
or
|
||||
n = any(Ruby::HashPattern parent).getChild(_).(Ruby::HashSplatParameter).getName()
|
||||
or
|
||||
n = any(Ruby::ExceptionVariable ev).getChild()
|
||||
or
|
||||
n = any(Ruby::For for).getPattern()
|
||||
@@ -177,6 +188,8 @@ private module Cached {
|
||||
or
|
||||
i = any(Ruby::Case x).getValue()
|
||||
or
|
||||
i = any(Ruby::CaseMatch x).getValue()
|
||||
or
|
||||
i = any(Ruby::Class x).getChild(_)
|
||||
or
|
||||
i = any(Ruby::Conditional x).getCondition()
|
||||
@@ -498,11 +511,10 @@ module LocalVariableAccess {
|
||||
predicate range(Ruby::Identifier id, TLocalVariableReal v) {
|
||||
access(id, v) and
|
||||
(
|
||||
explicitWriteAccess(id, _)
|
||||
or
|
||||
implicitWriteAccess(id)
|
||||
or
|
||||
vcall(id)
|
||||
explicitWriteAccess(id, _) or
|
||||
implicitWriteAccess(id) or
|
||||
vcall(id) or
|
||||
id = any(Ruby::VariableReferencePattern vr).getName()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,6 +603,8 @@ module Trees {
|
||||
final override ControlFlowTree getChildElement(int i) { result = this.getElement(i) }
|
||||
}
|
||||
|
||||
private class HashSplatNilParameterTree extends LeafTree, HashSplatNilParameter { }
|
||||
|
||||
private class HashSplatParameterTree extends NonDefaultValueParameterTree, HashSplatParameter { }
|
||||
|
||||
private class HereDocTree extends StandardPreOrderTree, HereDoc {
|
||||
|
||||
Reference in New Issue
Block a user