mirror of
https://github.com/github/codeql.git
synced 2026-05-14 11:19:27 +02:00
C#: Add compound assignment operator call classes.
This commit is contained in:
@@ -94,13 +94,17 @@ class AssignOperation extends Assignment, @assign_op_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A compound assignment operation that implicitly invokes an operator.
|
||||
* For example, `x += y` assigns the result of `x + y` to `x`.
|
||||
* A compound assignment operation that invokes an operator.
|
||||
*
|
||||
* (1) `x += y` invokes the compound assignment operator `+=` (if it exists).
|
||||
* (2) `x += y` invokes the operator `+` and assigns `x + y` to `x`.
|
||||
*
|
||||
* Either an arithmetic assignment operation (`AssignArithmeticOperation`) or a bitwise
|
||||
* assignment operation (`AssignBitwiseOperation`).
|
||||
*/
|
||||
class AssignCallOperation extends AssignOperation, OperatorCall, @assign_op_call_expr {
|
||||
class AssignCallOperation extends AssignOperation, OperatorCall, QualifiableExpr,
|
||||
@assign_op_call_expr
|
||||
{
|
||||
override string toString() { result = AssignOperation.super.toString() }
|
||||
}
|
||||
|
||||
|
||||
@@ -529,6 +529,19 @@ class ExtensionOperatorCall extends OperatorCall {
|
||||
ExtensionOperatorCall() { this.getTarget() instanceof ExtensionOperator }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ExtensionOperatorCall" }
|
||||
|
||||
private predicate isOrdinaryStaticCall() {
|
||||
not exists(Expr e | e = this.getChildExpr(-1) | not e instanceof TypeAccess)
|
||||
}
|
||||
|
||||
override Expr getArgument(int i) {
|
||||
exists(int j | result = this.getChildExpr(j) |
|
||||
i >= 0 and
|
||||
if this.isOrdinaryStaticCall() or this.getTarget() instanceof CompoundAssignmentOperator
|
||||
then j = i
|
||||
else j = i - 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -557,6 +570,58 @@ class MutatorOperatorCall extends OperatorCall {
|
||||
predicate isPostfix() { mutator_invocation_mode(this, 2) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a compound assignment operator, for example `this += other`
|
||||
* on line 7 in
|
||||
*
|
||||
* ```csharp
|
||||
* class A {
|
||||
* public void operator +=(A other) {
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* public void Add(A other) {
|
||||
* this += other;
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class CompoundAssignmentOperatorCall extends AssignCallOperation {
|
||||
CompoundAssignmentOperatorCall() { this.getTarget() instanceof CompoundAssignmentOperator }
|
||||
|
||||
override Expr getArgument(int i) { result = this.getChildExpr(i + 1) and i >= 0 }
|
||||
|
||||
/** Gets the qualifier of this compound assignment operator call. */
|
||||
override Expr getQualifier() { result = this.getChildExpr(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a compound assignment extension operator, for example `s1 *= s2` on
|
||||
* line 9 in
|
||||
*
|
||||
* ```csharp
|
||||
* static class MyExtensions {
|
||||
* extension(string s) {
|
||||
* public void operator *=(string other) { ... }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* class A {
|
||||
* void M(string s1, string s2) {
|
||||
* s1 *= s2;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
class ExtensionCompoundAssignmentOperatorCall extends CompoundAssignmentOperatorCall,
|
||||
ExtensionOperatorCall
|
||||
{
|
||||
override Expr getArgument(int i) { result = ExtensionOperatorCall.super.getArgument(i) }
|
||||
|
||||
override Expr getQualifier() { none() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ExtensionCompoundAssignmentOperatorCall" }
|
||||
}
|
||||
|
||||
private class DelegateLikeCall_ = @delegate_invocation_expr or @function_pointer_invocation_expr;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user