Skip to content

Commit 5419b5b

Browse files
committed
C#: Add ExtensionType to the QL library.
1 parent e5ebce5 commit 5419b5b

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

csharp/ql/lib/semmle/code/csharp/Member.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ class Virtualizable extends Overridable, Member, @virtualizable {
469469

470470
/**
471471
* A parameterizable declaration. Either a callable (`Callable`), a delegate
472-
* type (`DelegateType`), or an indexer (`Indexer`).
472+
* type (`DelegateType`), an indexer (`Indexer`), or an extension (`ExtensionType`).
473473
*/
474474
class Parameterizable extends Declaration, @parameterizable {
475475
/** Gets raw parameter `i`, including the `this` parameter at index 0. */

csharp/ql/lib/semmle/code/csharp/Type.qll

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
1717
*
1818
* Either a value or reference type (`ValueOrRefType`), the `void` type (`VoidType`),
1919
* a pointer type (`PointerType`), the arglist type (`ArglistType`), an unknown
20-
* type (`UnknownType`), or a type parameter (`TypeParameter`).
20+
* type (`UnknownType`), a type parameter (`TypeParameter`) or
21+
* an extension type (`ExtensionType`).
2122
*/
2223
class Type extends Member, TypeContainer, @type {
2324
/** Gets the name of this type without additional syntax such as `[]` or `*`. */
@@ -1326,3 +1327,35 @@ class TypeMention extends @type_mention {
13261327
/** Gets the location of this type mention. */
13271328
Location getLocation() { type_mention_location(this, result) }
13281329
}
1330+
1331+
/**
1332+
* A type extension declaration, for example `extension(string s) { ... }` in
1333+
*
1334+
* ```csharp
1335+
* static class MyExtensions {
1336+
* extension(string s) { ... }
1337+
* ```
1338+
*/
1339+
class ExtensionType extends Parameterizable, @extension_type {
1340+
/**
1341+
* Gets the receiver parameter of this extension type, if any.
1342+
*/
1343+
Parameter getReceiverParameter() { result = this.getParameter(0) }
1344+
1345+
/**
1346+
* Holds if this extension type has a receiver parameter.
1347+
*/
1348+
predicate hasReceiverParameter() { exists(this.getReceiverParameter()) }
1349+
1350+
/**
1351+
* Gets the type being extended by this extension type.
1352+
*/
1353+
Type getExtendedType() {
1354+
extension_receiver_type(this, result)
1355+
or
1356+
not extension_receiver_type(this, any(Type t)) and
1357+
extension_receiver_type(this, getTypeRef(result))
1358+
}
1359+
1360+
override string getAPrimaryQlClass() { result = "ExtensionType" }
1361+
}

0 commit comments

Comments
 (0)