@@ -529,6 +529,19 @@ class ExtensionOperatorCall extends OperatorCall {
529529 ExtensionOperatorCall ( ) { this .getTarget ( ) instanceof ExtensionOperator }
530530
531531 override string getAPrimaryQlClass ( ) { result = "ExtensionOperatorCall" }
532+
533+ private predicate isOrdinaryStaticCall ( ) {
534+ not exists ( Expr e | e = this .getChildExpr ( - 1 ) | not e instanceof TypeAccess )
535+ }
536+
537+ override Expr getArgument ( int i ) {
538+ exists ( int j | result = this .getChildExpr ( j ) |
539+ i >= 0 and
540+ if this .isOrdinaryStaticCall ( ) or this .getTarget ( ) instanceof CompoundAssignmentOperator
541+ then j = i
542+ else j = i - 1
543+ )
544+ }
532545}
533546
534547/**
@@ -557,6 +570,57 @@ class MutatorOperatorCall extends OperatorCall {
557570 predicate isPostfix ( ) { mutator_invocation_mode ( this , 2 ) }
558571}
559572
573+ /**
574+ * A call to a compound assignment operator, for example `this += other`
575+ * on line 7 in
576+ *
577+ * ```csharp
578+ * class A {
579+ * public void operator +=(A other) {
580+ * ...
581+ * }
582+ *
583+ * public A Add(A other) {
584+ * return this += other;
585+ * }
586+ * }
587+ * ```
588+ */
589+ class CompoundAssignmentOperatorCall extends AssignCallOperation {
590+ CompoundAssignmentOperatorCall ( ) { this .getTarget ( ) instanceof CompoundAssignmentOperator }
591+
592+ override Expr getArgument ( int i ) { result = this .getChildExpr ( i + 1 ) and i >= 0 }
593+
594+ Expr getQualifier ( ) { result = this .getChildExpr ( 0 ) }
595+ }
596+
597+ /**
598+ * A call to a compound assignment extension operator, for example `s1 *= s2` on
599+ * line 9 in
600+ *
601+ * ```csharp
602+ * static class MyExtensions {
603+ * extension(string s) {
604+ * public void operator *=(string other) { ... }
605+ * }
606+ * }
607+ *
608+ * class A {
609+ * void M(string s1, string s2) {
610+ * s1 *= s2;
611+ * }
612+ * }
613+ */
614+ class ExtensionCompoundAssignmentOperatorCall extends CompoundAssignmentOperatorCall ,
615+ ExtensionOperatorCall
616+ {
617+ override Expr getArgument ( int i ) { result = ExtensionOperatorCall .super .getArgument ( i ) }
618+
619+ override Expr getQualifier ( ) { none ( ) }
620+
621+ override string getAPrimaryQlClass ( ) { result = "ExtensionCompoundAssignmentOperatorCall" }
622+ }
623+
560624private class DelegateLikeCall_ = @delegate_invocation_expr or @function_pointer_invocation_expr;
561625
562626/**
0 commit comments