@@ -117,6 +117,62 @@ class AssignableRead extends AssignableAccess {
117117 AssignableRead getANextRead ( ) { result .getControlFlowNode ( ) = this .getAnAdjacentReadSameVar ( ) }
118118}
119119
120+ private newtype TMutationOperationAssignment =
121+ TBuiltInMutationOperation ( MutatorOperation mo ) or
122+ TUserMutatorOperatorCall ( MutatorOperatorCall moc ) {
123+ not moc instanceof InstanceMutatorOperatorCall
124+ }
125+
126+ /**
127+ * A mutation operation that implicitly assigns the result to its operand. For example, `a++` in
128+ * line 7 in
129+ *
130+ * ```csharp
131+ * class A {
132+ * public static A operator++(A a) {
133+ * return a;
134+ * }
135+ *
136+ * public static A Increment(A a) {
137+ * return a++;
138+ * }
139+ * }
140+ * ```
141+ */
142+ private class MutationOperationAssignment extends TMutationOperationAssignment {
143+ string toString ( ) { none ( ) }
144+
145+ Expr getOperand ( ) { none ( ) }
146+
147+ Expr getMutationOperation ( ) { none ( ) }
148+ }
149+
150+ private class BuiltInMutationOperation extends MutationOperationAssignment ,
151+ TBuiltInMutationOperation
152+ {
153+ private MutatorOperation mo ;
154+
155+ BuiltInMutationOperation ( ) { this = TBuiltInMutationOperation ( mo ) }
156+
157+ override string toString ( ) { result = mo .toString ( ) }
158+
159+ override Expr getOperand ( ) { result = mo .getOperand ( ) }
160+
161+ override Expr getMutationOperation ( ) { result = mo }
162+ }
163+
164+ private class UserMutatorOperatorCall extends MutationOperationAssignment , TUserMutatorOperatorCall {
165+ private MutatorOperatorCall moc ;
166+
167+ UserMutatorOperatorCall ( ) { this = TUserMutatorOperatorCall ( moc ) }
168+
169+ override string toString ( ) { result = moc .toString ( ) }
170+
171+ override Expr getOperand ( ) { result = moc .getArgument ( 0 ) }
172+
173+ override Expr getMutationOperation ( ) { result = moc }
174+ }
175+
120176/**
121177 * An access to an assignable that updates the underlying value. Either a
122178 * variable write (`VariableWrite`), a property write (`PropertyWrite`),
@@ -262,7 +318,8 @@ module AssignableInternal {
262318 or
263319 def = TOutRefDefinition ( any ( AssignableAccess aa | result = aa .getParent ( ) ) )
264320 or
265- def = TMutationDefinition ( result )
321+ def =
322+ TMutationDefinition ( any ( MutationOperationAssignment moa | result = moa .getMutationOperation ( ) ) )
266323 or
267324 def = TLocalVariableDefinition ( result )
268325 or
@@ -299,7 +356,7 @@ module AssignableInternal {
299356 or
300357 aa .( RefArg ) .isPotentialAssignment ( )
301358 } or
302- TMutationDefinition ( MutatorOperation mo ) or
359+ TMutationDefinition ( MutationOperationAssignment mo ) or
303360 TLocalVariableDefinition ( LocalVariableDeclExpr lvde ) {
304361 not lvde .hasInitializer ( ) and
305362 not exists ( getTupleSource ( TTupleAssignmentDefinition ( _, lvde ) ) ) and
@@ -372,7 +429,7 @@ module AssignableInternal {
372429 or
373430 def = TOutRefDefinition ( result )
374431 or
375- def = TMutationDefinition ( any ( MutatorOperation mo | mo .getOperand ( ) = result ) )
432+ def = TMutationDefinition ( any ( MutationOperationAssignment mo | mo .getOperand ( ) = result ) )
376433 or
377434 def = TAddressOfDefinition ( any ( AddressOfExpr aoe | aoe .getOperand ( ) = result ) )
378435 or
@@ -645,14 +702,25 @@ module AssignableDefinitions {
645702 * A definition by mutation, for example `x++`.
646703 */
647704 class MutationDefinition extends AssignableDefinition , TMutationDefinition {
648- MutatorOperation mo ;
705+ MutationOperationAssignment moa ;
706+
707+ MutationDefinition ( ) { this = TMutationDefinition ( moa ) }
708+
709+ /**
710+ * DEPRECATED: Use `getMutationOperation()` instead.
711+ *
712+ * Gets the underlying mutator operation.
713+ */
714+ deprecated MutatorOperation getMutatorOperation ( ) { moa = TBuiltInMutationOperation ( result ) }
649715
650- MutationDefinition ( ) { this = TMutationDefinition ( mo ) }
716+ /**
717+ * Gets the underlying mutation operation.
718+ */
719+ Expr getMutationOperation ( ) { result = moa .getMutationOperation ( ) }
651720
652- /** Gets the underlying mutator operation. */
653- MutatorOperation getMutatorOperation ( ) { result = mo }
721+ override Expr getSource ( ) { result = this .getMutationOperation ( ) }
654722
655- override string toString ( ) { result = mo .toString ( ) }
723+ override string toString ( ) { result = moa .toString ( ) }
656724 }
657725
658726 /**
0 commit comments