mirror of
https://github.com/github/codeql.git
synced 2026-02-20 08:53:49 +01:00
Merge pull request #106 from github/self
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,46 @@ module YieldCall {
|
||||
}
|
||||
}
|
||||
|
||||
module SuperCall {
|
||||
abstract class Range extends Call::Range { }
|
||||
|
||||
private class SuperTokenCallRange extends SuperCall::Range, @token_super {
|
||||
final override Generated::Super generated;
|
||||
|
||||
// N.B. `super` tokens can never be accesses, so any vcall with `super` must
|
||||
// be a call.
|
||||
SuperTokenCallRange() { vcall(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.getMethod() instanceof Generated::Super }
|
||||
|
||||
final override Expr getReceiver() { none() }
|
||||
|
||||
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,9 @@ private module Cached {
|
||||
not scope.(CapturingScope).inherits(name, _)
|
||||
}
|
||||
|
||||
// Token types that can be vcalls
|
||||
private class VcallToken = @token_identifier or @token_super;
|
||||
|
||||
/**
|
||||
* 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 +142,7 @@ private module Cached {
|
||||
* ```
|
||||
*/
|
||||
cached
|
||||
predicate vcall(Generated::Identifier i) {
|
||||
predicate vcall(VcallToken i) {
|
||||
i = any(Generated::ArgumentList x).getChild(_)
|
||||
or
|
||||
i = any(Generated::Array x).getChild(_)
|
||||
|
||||
@@ -72,6 +72,11 @@ callsWithNoReceiverArgumentsOrBlock
|
||||
| calls.rb:204:6:204:8 | call to bar | bar |
|
||||
| calls.rb:207:7:207:9 | call to bar | bar |
|
||||
| calls.rb:210:11:210:13 | call to bar | bar |
|
||||
| calls.rb:217:5:217:9 | call to super | super |
|
||||
| calls.rb:218:5:218:11 | call to super | super |
|
||||
| calls.rb:234:5:234:7 | call to foo | foo |
|
||||
| calls.rb:235:5:235:14 | call to super | super |
|
||||
| calls.rb:236:5:236:9 | call to super | super |
|
||||
callsWithScopeResolutionName
|
||||
| calls.rb:5:1:5:10 | call to bar | calls.rb:5:1:5:8 | ...::bar |
|
||||
callsWithArguments
|
||||
@@ -86,16 +91,54 @@ callsWithArguments
|
||||
| calls.rb:204:1:204:9 | call to foo | foo | 0 | calls.rb:204:5:204:8 | *... |
|
||||
| calls.rb:207:1:207:10 | call to foo | foo | 0 | calls.rb:207:5:207:9 | **... |
|
||||
| calls.rb:210:1:210:14 | call to foo | foo | 0 | calls.rb:210:5:210:13 | Pair |
|
||||
| calls.rb:219:5:219:16 | call to super | super | 0 | calls.rb:219:11:219:16 | blah |
|
||||
| calls.rb:220:5:220:17 | call to super | super | 0 | calls.rb:220:11:220:11 | 1 |
|
||||
| calls.rb:220:5:220:17 | call to super | super | 1 | calls.rb:220:14:220:14 | 2 |
|
||||
| calls.rb:220:5:220:17 | call to super | super | 2 | calls.rb:220:17:220:17 | 3 |
|
||||
| calls.rb:223:5:223:30 | call to super | super | 0 | calls.rb:223:11:223:11 | 4 |
|
||||
| calls.rb:223:5:223:30 | call to super | super | 1 | calls.rb:223:14:223:14 | 5 |
|
||||
| calls.rb:224:5:224:33 | call to super | super | 0 | calls.rb:224:11:224:11 | 6 |
|
||||
| calls.rb:224:5:224:33 | call to super | super | 1 | calls.rb:224:14:224:14 | 7 |
|
||||
callsWithReceiver
|
||||
| calls.rb:8:1:8:7 | call to bar | calls.rb:8:1:8:3 | 123 |
|
||||
| calls.rb:22:1:24:3 | call to bar | calls.rb:22:1:22:3 | 123 |
|
||||
| calls.rb:86:1:86:9 | call to bar | calls.rb:86:1:86:3 | call to foo |
|
||||
| calls.rb:234:5:234:13 | call to super | calls.rb:234:5:234:7 | call to foo |
|
||||
| calls.rb:236:5:236:15 | call to super | calls.rb:236:5:236:9 | call to super |
|
||||
callsWithBlock
|
||||
| calls.rb:14:1:14:17 | call to foo | calls.rb:14:5:14:17 | { ... } |
|
||||
| calls.rb:17:1:19:3 | call to foo | calls.rb:17:5:19:3 | do ... end |
|
||||
| calls.rb:22:1:24:3 | call to bar | calls.rb:22:16:24:3 | do ... end |
|
||||
| calls.rb:80:1:80:13 | call to foo | calls.rb:80:7:80:13 | { ... } |
|
||||
| calls.rb:83:1:83:16 | call to foo | calls.rb:83:7:83:16 | do ... end |
|
||||
| calls.rb:221:5:221:23 | call to super | calls.rb:221:11:221:23 | { ... } |
|
||||
| calls.rb:222:5:222:26 | call to super | calls.rb:222:11:222:26 | do ... end |
|
||||
| calls.rb:223:5:223:30 | call to super | calls.rb:223:16:223:30 | { ... } |
|
||||
| calls.rb:224:5:224:33 | call to super | calls.rb:224:16:224:33 | do ... end |
|
||||
yieldCalls
|
||||
| calls.rb:28:3:28:7 | call to yield |
|
||||
| calls.rb:33:3:33:16 | call to yield |
|
||||
superCalls
|
||||
| calls.rb:217:5:217:9 | call to super |
|
||||
| calls.rb:218:5:218:11 | call to super |
|
||||
| calls.rb:219:5:219:16 | call to super |
|
||||
| calls.rb:220:5:220:17 | call to super |
|
||||
| calls.rb:221:5:221:23 | call to super |
|
||||
| calls.rb:222:5:222:26 | call to super |
|
||||
| calls.rb:223:5:223:30 | call to super |
|
||||
| calls.rb:224:5:224:33 | call to super |
|
||||
| calls.rb:236:5:236:9 | call to super |
|
||||
superCallsWithArguments
|
||||
| calls.rb:219:5:219:16 | call to super | 0 | calls.rb:219:11:219:16 | blah |
|
||||
| calls.rb:220:5:220:17 | call to super | 0 | calls.rb:220:11:220:11 | 1 |
|
||||
| calls.rb:220:5:220:17 | call to super | 1 | calls.rb:220:14:220:14 | 2 |
|
||||
| calls.rb:220:5:220:17 | call to super | 2 | calls.rb:220:17:220:17 | 3 |
|
||||
| calls.rb:223:5:223:30 | call to super | 0 | calls.rb:223:11:223:11 | 4 |
|
||||
| calls.rb:223:5:223:30 | call to super | 1 | calls.rb:223:14:223:14 | 5 |
|
||||
| calls.rb:224:5:224:33 | call to super | 0 | calls.rb:224:11:224:11 | 6 |
|
||||
| calls.rb:224:5:224:33 | call to super | 1 | calls.rb:224:14:224:14 | 7 |
|
||||
superCallsWithBlock
|
||||
| calls.rb:221:5:221:23 | call to super | calls.rb:221:11:221:23 | { ... } |
|
||||
| calls.rb:222:5:222:26 | call to super | calls.rb:222:11:222:26 | do ... end |
|
||||
| calls.rb:223:5:223:30 | call to super | calls.rb:223:16:223:30 | { ... } |
|
||||
| calls.rb:224:5:224:33 | call to super | calls.rb:224:16:224:33 | do ... end |
|
||||
|
||||
@@ -22,3 +22,9 @@ query predicate callsWithReceiver(Call c, Expr rcv) { rcv = c.getReceiver() }
|
||||
query predicate callsWithBlock(Call c, Block b) { b = c.getBlock() }
|
||||
|
||||
query predicate yieldCalls(YieldCall c) { any() }
|
||||
|
||||
query predicate superCalls(SuperCall c) { any() }
|
||||
|
||||
query predicate superCallsWithArguments(SuperCall c, int n, Expr argN) { argN = c.getArgument(n) }
|
||||
|
||||
query predicate superCallsWithBlock(SuperCall c, Block b) { b = c.getBlock() }
|
||||
|
||||
@@ -207,4 +207,32 @@ foo(*bar)
|
||||
foo(**bar)
|
||||
|
||||
# the value in a keyword argument
|
||||
foo(blah: bar)
|
||||
foo(blah: bar)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# calls to `super`
|
||||
|
||||
class MyClass
|
||||
def my_method
|
||||
super
|
||||
super()
|
||||
super 'blah'
|
||||
super 1, 2, 3
|
||||
super { |x| x + 1 }
|
||||
super do |x| x * 2 end
|
||||
super 4, 5 { |x| x + 100 }
|
||||
super 6, 7 do |x| x + 200 end
|
||||
end
|
||||
end
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# calls to methods simply named `super`, i.e. *not* calls to the same method in
|
||||
# a parent classs, so these should be Call but not SuperCall
|
||||
|
||||
class AnotherClass
|
||||
def another_method
|
||||
foo.super
|
||||
self.super # TODO: this shows up as a call without a receiver, but that should be fixed once we handle `self` expressions
|
||||
super.super # we expect the receiver to be a SuperCall, while the outer call should not (it's just a regular Call)
|
||||
end
|
||||
end
|
||||
@@ -1631,12 +1631,12 @@ cfg.rb:
|
||||
#-----| -> exit print (normal)
|
||||
|
||||
# 144| puts
|
||||
#-----| -> super
|
||||
#-----| -> call to super
|
||||
|
||||
# 144| call to print
|
||||
#-----| -> call to puts
|
||||
|
||||
# 144| super
|
||||
# 144| call to super
|
||||
#-----| -> print
|
||||
|
||||
# 144| print
|
||||
|
||||
Reference in New Issue
Block a user