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;