@@ -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,58 @@ 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 void Add(A other) {
584+ * 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+ /** Gets the qualifier of this compound assignment operator call. */
595+ Expr getQualifier ( ) { result = this .getChildExpr ( 0 ) }
596+ }
597+
598+ /**
599+ * A call to a compound assignment extension operator, for example `s1 *= s2` on
600+ * line 9 in
601+ *
602+ * ```csharp
603+ * static class MyExtensions {
604+ * extension(string s) {
605+ * public void operator *=(string other) { ... }
606+ * }
607+ * }
608+ *
609+ * class A {
610+ * void M(string s1, string s2) {
611+ * s1 *= s2;
612+ * }
613+ * }
614+ */
615+ class ExtensionCompoundAssignmentOperatorCall extends CompoundAssignmentOperatorCall ,
616+ ExtensionOperatorCall
617+ {
618+ override Expr getArgument ( int i ) { result = ExtensionOperatorCall .super .getArgument ( i ) }
619+
620+ override Expr getQualifier ( ) { none ( ) }
621+
622+ override string getAPrimaryQlClass ( ) { result = "ExtensionCompoundAssignmentOperatorCall" }
623+ }
624+
560625private class DelegateLikeCall_ = @delegate_invocation_expr or @function_pointer_invocation_expr;
561626
562627/**
0 commit comments