C#: Add compound assignment operator QL classes.

This commit is contained in:
Michael Nebel
2026-04-22 15:41:04 +02:00
parent 13e8976494
commit 2729bfe379
2 changed files with 255 additions and 4 deletions

View File

@@ -611,7 +611,8 @@ class ExtensionOperator extends ExtensionCallableImpl, Operator {
class UnaryOperator extends Operator {
UnaryOperator() {
this.getNumberOfParameters() = 1 and
not this instanceof ConversionOperator
not this instanceof ConversionOperator and
not this instanceof CompoundAssignmentOperator
}
}
@@ -784,7 +785,7 @@ class TrueOperator extends UnaryOperator {
* A user-defined binary operator.
*
* Either an addition operator (`AddOperator`), a checked addition operator
* (`CheckedAddOperator`) a subtraction operator (`SubOperator`), a checked
* (`CheckedAddOperator`), a subtraction operator (`SubOperator`), a checked
* subtraction operator (`CheckedSubOperator`), a multiplication operator
* (`MulOperator`), a checked multiplication operator (`CheckedMulOperator`),
* a division operator (`DivOperator`), a checked division operator
@@ -795,10 +796,16 @@ class TrueOperator extends UnaryOperator {
* operator(`UnsignedRightShiftOperator`), an equals operator (`EQOperator`),
* a not equals operator (`NEOperator`), a lesser than operator (`LTOperator`),
* a greater than operator (`GTOperator`), a less than or equals operator
* (`LEOperator`), or a greater than or equals operator (`GEOperator`).
* (`LEOperator`), a greater than or equals operator (`GEOperator`), or
* a compound assignment operator (`CompoundAssignmentOperator`).
*/
class BinaryOperator extends Operator {
BinaryOperator() { this.getNumberOfParameters() = 2 }
BinaryOperator() {
this.getNumberOfParameters() = 2
or
// Instance compound assignment operators only have one parameter.
this.getNumberOfParameters() = 1 and not this.isStatic()
}
}
/**
@@ -1184,6 +1191,249 @@ class CheckedExplicitConversionOperator extends ConversionOperator {
override string getAPrimaryQlClass() { result = "CheckedExplicitConversionOperator" }
}
abstract private class CompoundAssignmentOperatorImpl extends BinaryOperator { }
/**
* A user-defined compound assignment operator.
*
* Either an addition operator (`AddCompoundAssignmentOperator`), a checked addition operator
* (`CheckedAddCompoundAssignmentOperator`), a subtraction operator (`SubCompoundAssignmentOperator`), a checked
* subtraction operator (`CheckedSubCompoundAssignmentOperator`), a multiplication operator
* (`MulCompoundAssignmentOperator`), a checked multiplication operator (`CheckedMulCompoundAssignmentOperator`),
* a division operator (`DivCompoundAssignmentOperator`), a checked division operator
* (`CheckedDivCompoundAssignmentOperator`), a remainder operator (`RemCompoundAssignmentOperator`), an and
* operator (`AndCompoundAssignmentOperator`), an or operator (`OrCompoundAssignmentOperator`), an xor
* operator (`XorCompoundAssignmentOperator`), a left shift operator (`LeftShiftCompoundAssignmentOperator`),
* a right shift operator (`RightShiftCompoundAssignmentOperator`), or an unsigned right shift
* operator(`UnsignedRightShiftCompoundAssignmentOperator`).
*/
final class CompoundAssignmentOperator = CompoundAssignmentOperatorImpl;
/**
* A user-defined compound assignment addition operator (`+=`), for example
*
* ```csharp
* public void operator checked +=(Widget w) {
* ...
* }
* ```
*/
class AddCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
AddCompoundAssignmentOperator() { this.getName() = "+=" }
override string getAPrimaryQlClass() { result = "AddCompoundAssignmentOperator" }
}
/**
* A user-defined checked compound assignment addition operator (`checked +=`), for example
*
* ```csharp
* public void operator checked +=(Widget w) {
* ...
* }
* ```
*/
class CheckedAddCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
CheckedAddCompoundAssignmentOperator() { this.getName() = "checked +=" }
override string getAPrimaryQlClass() { result = "CheckedAddCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment subtraction operator (`-=`), for example
*
* ```csharp
* public void operator -=(Widget w) {
* ...
* }
* ```
*/
class SubCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
SubCompoundAssignmentOperator() { this.getName() = "-=" }
override string getAPrimaryQlClass() { result = "SubCompoundAssignmentOperator" }
}
/**
* A user-defined checked compound assignment subtraction operator (`checked -=`), for example
*
* ```csharp
* public void operator checked -=(Widget w) {
* ...
* }
* ```
*/
class CheckedSubCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
CheckedSubCompoundAssignmentOperator() { this.getName() = "checked -=" }
override string getAPrimaryQlClass() { result = "CheckedSubCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment multiplication operator (`*=`), for example
*
* ```csharp
* public void operator *=(Widget w) {
* ...
* }
* ```
*/
class MulCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
MulCompoundAssignmentOperator() { this.getName() = "*=" }
override string getAPrimaryQlClass() { result = "MulCompoundAssignmentOperator" }
}
/**
* A user-defined checked compound assignment multiplication operator (`checked *=`), for example
*
* ```csharp
* public void operator checked *=(Widget w) {
* ...
* }
* ```
*/
class CheckedMulCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
CheckedMulCompoundAssignmentOperator() { this.getName() = "checked *=" }
override string getAPrimaryQlClass() { result = "CheckedMulCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment division operator (`/=`), for example
*
* ```csharp
* public void operator /=(Widget w) {
* ...
* }
* ```
*/
class DivCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
DivCompoundAssignmentOperator() { this.getName() = "/=" }
override string getAPrimaryQlClass() { result = "DivCompoundAssignmentOperator" }
}
/**
* A user-defined checked compound assignment division operator (`checked /=`), for example
*
* ```csharp
* public void operator checked /=(Widget w) {
* ...
* }
* ```
*/
class CheckedDivCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
CheckedDivCompoundAssignmentOperator() { this.getName() = "checked /=" }
override string getAPrimaryQlClass() { result = "CheckedDivCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment remainder operator (`%=`), for example
*
* ```csharp
* public void operator %=(Widget w) {
* ...
* }
* ```
*/
class RemCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
RemCompoundAssignmentOperator() { this.getName() = "%=" }
override string getAPrimaryQlClass() { result = "RemCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment and operator (`&=`), for example
*
* ```csharp
* public void operator &=(Widget w) {
* ...
* }
* ```
*/
class AndCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
AndCompoundAssignmentOperator() { this.getName() = "&=" }
override string getAPrimaryQlClass() { result = "AndCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment or operator (`|=`), for example
*
* ```csharp
* public void operator |=(Widget w) {
* ...
* }
* ```
*/
class OrCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
OrCompoundAssignmentOperator() { this.getName() = "|=" }
override string getAPrimaryQlClass() { result = "OrCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment xor operator (`^=`), for example
*
* ```csharp
* public void operator ^=(Widget w) {
* ...
* }
* ```
*/
class XorCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
XorCompoundAssignmentOperator() { this.getName() = "^=" }
override string getAPrimaryQlClass() { result = "XorCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment left shift operator (`<<=`), for example
*
* ```csharp
* public void operator <<=(Widget w) {
* ...
* }
* ```
*/
class LeftShiftCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
LeftShiftCompoundAssignmentOperator() { this.getName() = "<<=" }
override string getAPrimaryQlClass() { result = "LeftShiftCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment right shift operator (`>>=`), for example
*
* ```csharp
* public void operator >>=(Widget w) {
* ...
* }
* ```
*/
class RightShiftCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
RightShiftCompoundAssignmentOperator() { this.getName() = ">>=" }
override string getAPrimaryQlClass() { result = "RightShiftCompoundAssignmentOperator" }
}
/**
* A user-defined compound assignment unsigned right shift operator (`>>>=`), for example
*
* ```csharp
* public void operator >>>=(Widget w) {
* ...
* }
* ```
*/
class UnsignedRightShiftCompoundAssignmentOperator extends CompoundAssignmentOperatorImpl {
UnsignedRightShiftCompoundAssignmentOperator() { this.getName() = ">>>=" }
override string getAPrimaryQlClass() { result = "UnsignedRightShiftCompoundAssignmentOperator" }
}
/**
* A local function, defined within the scope of another callable.
* For example, `Fac` on lines 2--4 in

View File

@@ -1334,6 +1334,7 @@ class TypeMention extends @type_mention {
* ```csharp
* static class MyExtensions {
* extension(string s) { ... }
* }
* ```
*/
class ExtensionType extends Parameterizable, @extension_type {