AST: add SetterMethodCall as instance of LhsExpr

This commit is contained in:
Arthur Baars
2021-02-22 15:07:21 +01:00
parent 79bb20b31f
commit 7ae20f3b5b
5 changed files with 66 additions and 0 deletions

View File

@@ -7,6 +7,8 @@ private import internal.Call
class Call extends Expr {
override Call::Range range;
Call() { range.isNormal() }
override string getAPrimaryQlClass() { result = "Call" }
/**
@@ -93,6 +95,19 @@ class MethodCall extends Call {
final Block getBlock() { result = range.getBlock() }
}
/**
* A call to a setter method.
* ```rb
* self.foo = 10
* a[0] = 10
* ```
*/
class SetterMethodCall extends LhsExpr {
final override SetterMethodCall::Range range;
final override string getAPrimaryQlClass() { result = "SetterMethodCall" }
}
/**
* An element reference; a call to the `[]` method.
* ```rb

View File

@@ -1,6 +1,7 @@
private import codeql_ruby.AST
private import codeql_ruby.ast.internal.AST
private import codeql_ruby.ast.internal.Expr
private import codeql_ruby.ast.internal.Pattern
private import codeql_ruby.ast.internal.TreeSitter
private import codeql_ruby.ast.internal.Variable
@@ -8,6 +9,12 @@ module Call {
abstract class Range extends Expr::Range {
abstract Expr getArgument(int n);
final predicate isSetter() { this instanceof LhsExpr }
final predicate isNormal() {
not isSetter() or generated.getParent() instanceof AssignOperation
}
override predicate child(string label, AstNode::Range child) {
label = "getArgument" and child = getArgument(_)
}
@@ -111,6 +118,30 @@ module ElementReference {
}
}
module SetterMethodCall {
class Range extends LhsExpr::Range {
private MethodCall::Range range;
Range() { this = range }
final Expr getReceiver() { result = range.getReceiver() }
final Expr getArgument(int n) { result = range.getArgument(n) }
final string getMethodName() { result = range.getMethodName() }
final override string toString() { result = range.toString() }
final override predicate child(string label, AstNode::Range child) {
super.child(label, child)
or
label = "getReceiver" and child = getReceiver()
or
label = "getArgument" and child = getArgument(_)
}
}
}
module YieldCall {
class Range extends Call::Range, @yield {
final override Generated::Yield generated;

View File

@@ -77,6 +77,9 @@ callsWithNoReceiverArgumentsOrBlock
| calls.rb:305:5:305:9 | call to super | super |
| calls.rb:310:1:310:3 | call to foo | foo |
| calls.rb:311:1:311:3 | call to foo | foo |
| calls.rb:315:1:315:3 | call to foo | foo |
| calls.rb:316:22:316:24 | call to foo | foo |
| calls.rb:317:5:317:7 | call to foo | foo |
callsWithArguments
| calls.rb:14:1:14:11 | call to foo | foo | 0 | calls.rb:14:5:14:5 | 0 |
| calls.rb:14:1:14:11 | call to foo | foo | 1 | calls.rb:14:8:14:8 | 1 |
@@ -184,6 +187,7 @@ callsWithReceiver
| calls.rb:305:5:305:15 | call to super | calls.rb:305:5:305:9 | call to super |
| calls.rb:310:1:310:6 | call to call | calls.rb:310:1:310:3 | call to foo |
| calls.rb:311:1:311:7 | call to call | calls.rb:311:1:311:3 | call to foo |
| calls.rb:318:1:318:10 | call to count | calls.rb:318:1:318:4 | self |
callsWithBlock
| calls.rb:17:1:17:17 | call to foo | calls.rb:17:5:17:17 | { ... } |
| calls.rb:20:1:22:3 | call to foo | calls.rb:20:5:22:3 | do ... end |
@@ -221,3 +225,11 @@ superCallsWithBlock
| calls.rb:291:5:291:26 | call to super | calls.rb:291:11:291:26 | do ... end |
| calls.rb:292:5:292:30 | call to super | calls.rb:292:16:292:30 | { ... } |
| calls.rb:293:5:293:33 | call to super | calls.rb:293:16:293:33 | do ... end |
setterCalls
| calls.rb:314:1:314:8 | call to foo |
| calls.rb:315:1:315:6 | ...[...] |
| calls.rb:316:1:316:8 | call to foo |
| calls.rb:316:12:316:19 | call to bar |
| calls.rb:316:22:316:27 | ...[...] |
| calls.rb:317:5:317:10 | ...[...] |
| calls.rb:318:1:318:10 | call to count |

View File

@@ -30,3 +30,5 @@ 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() }
query predicate setterCalls(SetterMethodCall c) { any() }

View File

@@ -310,3 +310,9 @@ end
foo.()
foo.(1)
# setter calls
self.foo = 10
foo[0] = 10
self.foo, *self.bar, foo[4] = [1, 2, 3, 4]
a, *foo[5] = [1, 2, 3]
self.count += 1