mirror of
https://github.com/github/codeql.git
synced 2026-02-20 17:03:41 +01:00
Add SuperCall class for calls to super
This commit is contained in:
@@ -108,6 +108,22 @@ class YieldCall extends Call, @yield {
|
||||
final override string getAPrimaryQlClass() { result = "YieldCall" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `super`.
|
||||
* ```rb
|
||||
* class Foo < Bar
|
||||
* def baz
|
||||
* super
|
||||
* end
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
class SuperCall extends Call {
|
||||
final override SuperCall::Range range;
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "SuperCall" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A block argument in a method call.
|
||||
* ```rb
|
||||
|
||||
@@ -66,6 +66,47 @@ module YieldCall {
|
||||
}
|
||||
}
|
||||
|
||||
module SuperCall {
|
||||
abstract class Range extends Call::Range { }
|
||||
|
||||
private class SuperTokenCallRange extends SuperCall::Range, @token_super {
|
||||
final override Generated::Super generated;
|
||||
|
||||
SuperTokenCallRange() { vcall(this) and not access(this, _) }
|
||||
|
||||
final override Expr getReceiver() { none() }
|
||||
|
||||
final override string getMethodName() { result = generated.getValue() }
|
||||
|
||||
final override ScopeResolution getMethodScopeResolution() { none() }
|
||||
|
||||
final override Expr getArgument(int n) { none() }
|
||||
|
||||
final override Block getBlock() { none() }
|
||||
}
|
||||
|
||||
private class RegularSuperCallRange extends SuperCall::Range, @call {
|
||||
final override Generated::Call generated;
|
||||
|
||||
RegularSuperCallRange() {
|
||||
generated = this and
|
||||
generated.getMethod() instanceof Generated::Super
|
||||
}
|
||||
|
||||
final override Expr getReceiver() { result = generated.getReceiver() }
|
||||
|
||||
final override string getMethodName() {
|
||||
result = generated.getMethod().(Generated::Super).getValue()
|
||||
}
|
||||
|
||||
final override ScopeResolution getMethodScopeResolution() { none() }
|
||||
|
||||
final override Expr getArgument(int n) { result = generated.getArguments().getChild(n) }
|
||||
|
||||
final override Block getBlock() { result = generated.getBlock() }
|
||||
}
|
||||
}
|
||||
|
||||
module BlockArgument {
|
||||
class Range extends Expr::Range, @block_argument {
|
||||
final override Generated::BlockArgument generated;
|
||||
|
||||
@@ -125,6 +125,11 @@ private module Cached {
|
||||
not scope.(CapturingScope).inherits(name, _)
|
||||
}
|
||||
|
||||
// Token types that can be accesses/vcalls
|
||||
private class AccessTokenUnion = @token_identifier or @token_super;
|
||||
|
||||
private class AccessToken extends Generated::Token, AccessTokenUnion { }
|
||||
|
||||
/**
|
||||
* Holds if `i` is an `identifier` node occurring in the context where it
|
||||
* should be considered a VCALL. VCALL is the term that MRI/Ripper uses
|
||||
@@ -139,7 +144,7 @@ private module Cached {
|
||||
* ```
|
||||
*/
|
||||
cached
|
||||
predicate vcall(Generated::Identifier i) {
|
||||
predicate vcall(AccessToken i) {
|
||||
i = any(Generated::ArgumentList x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Array x).getChild(_)
|
||||
@@ -266,7 +271,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate access(Generated::Identifier access, Variable variable) {
|
||||
predicate access(AccessToken access, Variable variable) {
|
||||
exists(string name | name = access.getValue() |
|
||||
variable = enclosingScope(access).getVariable(name) and
|
||||
not strictlyBefore(access.getLocation(), variable.getLocation()) and
|
||||
|
||||
Reference in New Issue
Block a user