Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
dca10f8
C#: Add extended_type to the DB scheme.
michaelnebel Feb 4, 2026
c68cd58
C#: Add parameter marker interface, allow a type to a parent for para…
michaelnebel Feb 4, 2026
60bb9a9
C#: Move some populate methods and location writing methods.
michaelnebel Feb 4, 2026
ab505e3
C#: Add class for making synthetic parameter entities.
michaelnebel Feb 4, 2026
edfdc98
C#: Extract extension types and members. Replacing invocations to sta…
michaelnebel Feb 4, 2026
9a4a6cf
C#: Add ExtensionType to the QL library.
michaelnebel Feb 4, 2026
b9f36f3
C#: Add extension callable and accessor classes.
michaelnebel Feb 4, 2026
5e02a86
C#: Add extension call classes.
michaelnebel Feb 4, 2026
e831c80
C#: Replace extension parameter access with the corresponding synthet…
michaelnebel Feb 4, 2026
849823e
C#: Add dispatch logic for calling extensions accessors as methods.
michaelnebel Feb 4, 2026
c040daa
C#: Add extensions test.
michaelnebel Feb 4, 2026
6cbe000
C#: Add PrintAst test for extensions.
michaelnebel Feb 4, 2026
4b6a53b
C#: Add extension data flow test.
michaelnebel Feb 4, 2026
bd3e4d3
C#: Add MaD tests for extensions.
michaelnebel Feb 4, 2026
02e4a8b
C#: Add change-note.
michaelnebel Feb 5, 2026
fe94b3b
C#: Address review comments.
michaelnebel Feb 9, 2026
bcdbd6e
C#: Use the fully qualified name for the extension type when printing…
michaelnebel Feb 9, 2026
d9fea15
C#: Update MaD models for extension members.
michaelnebel Feb 9, 2026
eff9f99
C#: Update test expected output.
michaelnebel Feb 9, 2026
42d2de8
C#: Add DB upgrade script.
michaelnebel Feb 9, 2026
3e914f7
C#: Add DB downgrade script.
michaelnebel Feb 9, 2026
bee1718
QL4QL: Allow Impl classes to implement getAPrimaryQLClass with non Im…
michaelnebel Feb 9, 2026
25b836b
C#: Apply suggestions from code review
michaelnebel Feb 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
C#: Add ExtensionType to the QL library.
  • Loading branch information
michaelnebel committed Feb 5, 2026
commit 9a4a6cfcb8e8a35b8e0c0abec2d57c897094159d
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/Member.qll
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ class Virtualizable extends Overridable, Member, @virtualizable {

/**
* A parameterizable declaration. Either a callable (`Callable`), a delegate
* type (`DelegateType`), or an indexer (`Indexer`).
* type (`DelegateType`), an indexer (`Indexer`), or an extension (`ExtensionType`).
*/
class Parameterizable extends Declaration, @parameterizable {
/** Gets raw parameter `i`, including the `this` parameter at index 0. */
Expand Down
35 changes: 34 additions & 1 deletion csharp/ql/lib/semmle/code/csharp/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
*
* Either a value or reference type (`ValueOrRefType`), the `void` type (`VoidType`),
* a pointer type (`PointerType`), the arglist type (`ArglistType`), an unknown
* type (`UnknownType`), or a type parameter (`TypeParameter`).
* type (`UnknownType`), a type parameter (`TypeParameter`) or
* an extension type (`ExtensionType`).
*/
class Type extends Member, TypeContainer, @type {
/** Gets the name of this type without additional syntax such as `[]` or `*`. */
Expand Down Expand Up @@ -1326,3 +1327,35 @@ class TypeMention extends @type_mention {
/** Gets the location of this type mention. */
Location getLocation() { type_mention_location(this, result) }
}

/**
* A type extension declaration, for example `extension(string s) { ... }` in
*
* ```csharp
* static class MyExtensions {
* extension(string s) { ... }
* ```
*/
class ExtensionType extends Parameterizable, @extension_type {
/**
* Gets the receiver parameter of this extension type, if any.
*/
Parameter getReceiverParameter() { result = this.getParameter(0) }

/**
* Holds if this extension type has a receiver parameter.
*/
predicate hasReceiverParameter() { exists(this.getReceiverParameter()) }

/**
* Gets the type being extended by this extension type.
*/
Type getExtendedType() {
extension_receiver_type(this, result)
or
not extension_receiver_type(this, any(Type t)) and
extension_receiver_type(this, getTypeRef(result))
}

override string getAPrimaryQlClass() { result = "ExtensionType" }
}