mirror of
https://github.com/github/codeql.git
synced 2026-02-12 05:01:06 +01:00
C#: Add extension callable and accessor classes.
This commit is contained in:
@@ -221,6 +221,23 @@ class Callable extends Parameterizable, ExprOrStmtParent, @callable {
|
||||
|
||||
/** Gets a `Call` that has this callable as a target. */
|
||||
Call getACall() { this = result.getTarget() }
|
||||
|
||||
/** Holds if this callable is declared in an extension type. */
|
||||
predicate isInExtension() { this.getDeclaringType() instanceof ExtensionType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A callable that is declared as an extension.
|
||||
*
|
||||
* Either an extension method (`ExtensionMethod`), an extension operator
|
||||
* (`ExtensionOperator`) or an extension accessor (`ExtensionAccessor`).
|
||||
*/
|
||||
abstract class ExtensionCallable extends Callable {
|
||||
/** Gets the type being extended by this method. */
|
||||
pragma[noinline]
|
||||
Type getExtendedType() { result = this.getDeclaringType().(ExtensionType).getExtendedType() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ExtensionCallable" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,8 +284,11 @@ class Method extends Callable, Virtualizable, Attributable, @method {
|
||||
|
||||
override Location getALocation() { method_location(this.getUnboundDeclaration(), result) }
|
||||
|
||||
/** Holds if this method is a classic extension method. */
|
||||
predicate isClassicExtensionMethod() { this.getParameter(0).hasExtensionMethodModifier() }
|
||||
|
||||
/** Holds if this method is an extension method. */
|
||||
predicate isExtensionMethod() { this.getParameter(0).hasExtensionMethodModifier() }
|
||||
predicate isExtensionMethod() { this.isClassicExtensionMethod() or this.isInExtension() }
|
||||
|
||||
/** Gets the type of the `params` parameter of this method, if any. */
|
||||
Type getParamsType() {
|
||||
@@ -296,7 +316,17 @@ class Method extends Callable, Virtualizable, Attributable, @method {
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension method, for example
|
||||
* An extension method.
|
||||
*
|
||||
* Either a classic extension method (`ClassicExtensionMethod`) or an extension
|
||||
* type extension method (`ExtensionTypeExtensionMethod`).
|
||||
*/
|
||||
abstract class ExtensionMethod extends ExtensionCallable, Method {
|
||||
override string getAPrimaryQlClass() { result = "ExtensionMethod" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension method, for example
|
||||
*
|
||||
* ```csharp
|
||||
* static bool IsDefined(this Widget w) {
|
||||
@@ -304,16 +334,28 @@ class Method extends Callable, Virtualizable, Attributable, @method {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class ExtensionMethod extends Method {
|
||||
ExtensionMethod() { this.isExtensionMethod() }
|
||||
class ClassicExtensionMethod extends ExtensionMethod {
|
||||
ClassicExtensionMethod() { this.isClassicExtensionMethod() }
|
||||
|
||||
pragma[noinline]
|
||||
override Type getExtendedType() { result = this.getParameter(0).getType() }
|
||||
|
||||
override predicate isStatic() { any() }
|
||||
}
|
||||
|
||||
/** Gets the type being extended by this method. */
|
||||
pragma[noinline]
|
||||
Type getExtendedType() { result = this.getParameter(0).getType() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ExtensionMethod" }
|
||||
/**
|
||||
* An extension method declared in an extension type, for example `IsNullOrEmpty` in
|
||||
*
|
||||
* ```csharp
|
||||
* static class MyExtensions {
|
||||
* extension(string s) {
|
||||
* public bool IsNullOrEmpty() { ... }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class ExtensionTypeExtensionMethod extends ExtensionMethod {
|
||||
ExtensionTypeExtensionMethod() { this.isInExtension() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -536,6 +578,21 @@ class RecordCloneMethod extends Method {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension operator, for example `*` in
|
||||
*
|
||||
* ```csharp
|
||||
* static class MyExtensions {
|
||||
* extension(string s) {
|
||||
* public static string operator *(int s1, string s2) { ... }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class ExtensionOperator extends ExtensionCallable, Operator {
|
||||
ExtensionOperator() { this.isInExtension() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A user-defined unary operator - an operator taking one operand.
|
||||
*
|
||||
|
||||
@@ -260,6 +260,21 @@ class Property extends DeclarationWithGetSetAccessors, @property {
|
||||
override string getAPrimaryQlClass() { result = "Property" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension property, for example `FirstChar` in
|
||||
*
|
||||
* ```csharp
|
||||
* static class MyExtensions {
|
||||
* extension(string s) {
|
||||
* public char FirstChar { get { ... } }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class ExtensionProperty extends Property {
|
||||
ExtensionProperty() { this.getDeclaringType() instanceof ExtensionType }
|
||||
}
|
||||
|
||||
/**
|
||||
* An indexer, for example `string this[int i]` on line 2 in
|
||||
*
|
||||
@@ -413,6 +428,22 @@ class Accessor extends Callable, Modifiable, Attributable, Overridable, @callabl
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension accessor. Either a getter (`Getter`) or a setter (`Setter`) of an
|
||||
* extension property, for example `get` in
|
||||
*
|
||||
* ```csharp
|
||||
* static class MyExtensions {
|
||||
* extension(string s) {
|
||||
* public char FirstChar { get { ... } }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class ExtensionAccessor extends ExtensionCallable, Accessor {
|
||||
ExtensionAccessor() { this.getDeclaringType() instanceof ExtensionType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `get` accessor, for example `get { return p; }` in
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user