@@ -221,6 +221,23 @@ class Callable extends Parameterizable, ExprOrStmtParent, @callable {
221221
222222 /** Gets a `Call` that has this callable as a target. */
223223 Call getACall ( ) { this = result .getTarget ( ) }
224+
225+ /** Holds if this callable is declared in an extension type. */
226+ predicate isInExtension ( ) { this .getDeclaringType ( ) instanceof ExtensionType }
227+ }
228+
229+ /**
230+ * A callable that is declared as an extension.
231+ *
232+ * Either an extension method (`ExtensionMethod`), an extension operator
233+ * (`ExtensionOperator`) or an extension accessor (`ExtensionAccessor`).
234+ */
235+ abstract class ExtensionCallable extends Callable {
236+ /** Gets the type being extended by this method. */
237+ pragma [ noinline]
238+ Type getExtendedType ( ) { result = this .getDeclaringType ( ) .( ExtensionType ) .getExtendedType ( ) }
239+
240+ override string getAPrimaryQlClass ( ) { result = "ExtensionCallable" }
224241}
225242
226243/**
@@ -267,8 +284,11 @@ class Method extends Callable, Virtualizable, Attributable, @method {
267284
268285 override Location getALocation ( ) { method_location ( this .getUnboundDeclaration ( ) , result ) }
269286
287+ /** Holds if this method is a classic extension method. */
288+ predicate isClassicExtensionMethod ( ) { this .getParameter ( 0 ) .hasExtensionMethodModifier ( ) }
289+
270290 /** Holds if this method is an extension method. */
271- predicate isExtensionMethod ( ) { this .getParameter ( 0 ) . hasExtensionMethodModifier ( ) }
291+ predicate isExtensionMethod ( ) { this .isClassicExtensionMethod ( ) or this . isInExtension ( ) }
272292
273293 /** Gets the type of the `params` parameter of this method, if any. */
274294 Type getParamsType ( ) {
@@ -296,24 +316,46 @@ class Method extends Callable, Virtualizable, Attributable, @method {
296316}
297317
298318/**
299- * An extension method, for example
319+ * An extension method.
320+ *
321+ * Either a classic extension method (`ClassicExtensionMethod`) or an extension
322+ * type extension method (`ExtensionTypeExtensionMethod`).
323+ */
324+ abstract class ExtensionMethod extends ExtensionCallable , Method {
325+ override string getAPrimaryQlClass ( ) { result = "ExtensionMethod" }
326+ }
327+
328+ /**
329+ * An extension method, for example
300330 *
301331 * ```csharp
302332 * static bool IsDefined(this Widget w) {
303333 * ...
304334 * }
305335 * ```
306336 */
307- class ExtensionMethod extends Method {
308- ExtensionMethod ( ) { this .isExtensionMethod ( ) }
309-
310- override predicate isStatic ( ) { any ( ) }
337+ class ClassicExtensionMethod extends ExtensionMethod {
338+ ClassicExtensionMethod ( ) { this .isClassicExtensionMethod ( ) }
311339
312- /** Gets the type being extended by this method. */
313340 pragma [ noinline]
314- Type getExtendedType ( ) { result = this .getParameter ( 0 ) .getType ( ) }
341+ override Type getExtendedType ( ) { result = this .getParameter ( 0 ) .getType ( ) }
315342
316- override string getAPrimaryQlClass ( ) { result = "ExtensionMethod" }
343+ override predicate isStatic ( ) { any ( ) }
344+ }
345+
346+ /**
347+ * An extension method declared in an extension type, for example `IsNullOrEmpty` in
348+ *
349+ * ```csharp
350+ * static class MyExtensions {
351+ * extension(string s) {
352+ * public bool IsNullOrEmpty() { ... }
353+ * }
354+ * }
355+ * ```
356+ */
357+ class ExtensionTypeExtensionMethod extends ExtensionMethod {
358+ ExtensionTypeExtensionMethod ( ) { this .isInExtension ( ) }
317359}
318360
319361/**
@@ -536,6 +578,21 @@ class RecordCloneMethod extends Method {
536578 }
537579}
538580
581+ /**
582+ * An extension operator, for example `*` in
583+ *
584+ * ```csharp
585+ * static class MyExtensions {
586+ * extension(string s) {
587+ * public static string operator *(int s1, string s2) { ... }
588+ * }
589+ * }
590+ * ```
591+ */
592+ class ExtensionOperator extends ExtensionCallable , Operator {
593+ ExtensionOperator ( ) { this .isInExtension ( ) }
594+ }
595+
539596/**
540597 * A user-defined unary operator - an operator taking one operand.
541598 *
0 commit comments