@@ -267,9 +267,33 @@ class Call extends Expr, @call {
267267class MethodCall extends Call , QualifiableExpr , LateBindableExpr , @method_invocation_expr {
268268 override Method getTarget ( ) { expr_call ( this , result ) }
269269
270+ /**
271+ * Gets the accessor that was used to generate this method, if any. For example, the
272+ * method call `MyExtensions.get_FirstChar(s)` on line 9 is generated from the property
273+ * accessor `get_FirstChar` on line 3 in
274+ *
275+ * ```csharp
276+ * static class MyExtensions {
277+ * extension(string s) {
278+ * public char FirstChar { get { ... } }
279+ * }
280+ * }
281+ *
282+ * class A {
283+ * char M(string s) {
284+ * return MyExtensions.get_FirstChar(s);
285+ * }
286+ * }
287+ */
288+ Accessor getTargetAccessor ( ) { expr_call ( this , result ) }
289+
270290 override Method getQualifiedDeclaration ( ) { result = this .getTarget ( ) }
271291
272- override string toString ( ) { result = "call to method " + concat ( this .getTarget ( ) .getName ( ) ) }
292+ override string toString ( ) {
293+ if exists ( this .getTargetAccessor ( ) )
294+ then result = "call to extension accessor " + concat ( this .getTargetAccessor ( ) .getName ( ) )
295+ else result = "call to method " + concat ( this .getTarget ( ) .getName ( ) )
296+ }
273297
274298 override string getAPrimaryQlClass ( ) { result = "MethodCall" }
275299
@@ -479,6 +503,30 @@ class OperatorCall extends Call, LateBindableExpr, @operator_invocation_expr {
479503 override string getAPrimaryQlClass ( ) { result = "OperatorCall" }
480504}
481505
506+ /**
507+ * A call to an extension operator, for example `3 * s` on
508+ * line 9 in
509+ *
510+ * ```csharp
511+ * static class MyExtensions {
512+ * extension(string s) {
513+ * public static string operator *(int i, string s) { ... }
514+ * }
515+ * }
516+ *
517+ * class A {
518+ * string M(string s) {
519+ * return 3 * s;
520+ * }
521+ * }
522+ * ```
523+ */
524+ class ExtensionOperatorCall extends OperatorCall {
525+ ExtensionOperatorCall ( ) { this .getTarget ( ) instanceof ExtensionOperator }
526+
527+ override string getAPrimaryQlClass ( ) { result = "ExtensionOperatorCall" }
528+ }
529+
482530/**
483531 * A call to a user-defined mutator operator, for example `a++` on
484532 * line 7 in
@@ -658,6 +706,44 @@ class IndexerCall extends AccessorCall, IndexerAccessExpr {
658706 override string getAPrimaryQlClass ( ) { result = "IndexerCall" }
659707}
660708
709+ /**
710+ * A call to an extension property accessor (via the property), for example
711+ * `s.FirstChar` on line 9 in
712+ *
713+ * ```csharp
714+ * static class MyExtensions {
715+ * extension(string s) {
716+ * public char FirstChar { get { ... } }
717+ * }
718+ * }
719+ *
720+ * class A {
721+ * char M(string s) {
722+ * return s.FirstChar;
723+ * }
724+ * }
725+ * ```
726+ */
727+ class ExtensionPropertyCall extends PropertyCall {
728+ private ExtensionProperty prop ;
729+
730+ ExtensionPropertyCall ( ) { this .getProperty ( ) = prop }
731+
732+ override Expr getArgument ( int i ) {
733+ if prop .isStatic ( )
734+ then result = super .getArgument ( i )
735+ else (
736+ // Shift arguments as the qualifier is an explicit argument in the getter/setter.
737+ i = 0 and
738+ result = this .getQualifier ( )
739+ or
740+ result = super .getArgument ( i - 1 )
741+ )
742+ }
743+
744+ override string getAPrimaryQlClass ( ) { result = "ExtensionPropertyCall" }
745+ }
746+
661747/**
662748 * A call to an event accessor, for example the call to `add_Click`
663749 * (defined on line 5) on line 12 in
0 commit comments