C#: Add dispatch logic for calling extensions accessors as methods.

This commit is contained in:
Michael Nebel
2026-02-04 16:25:38 +01:00
parent e831c80a23
commit 849823eff6

View File

@@ -87,7 +87,8 @@ private module Internal {
newtype TDispatchCall =
TDispatchMethodCall(MethodCall mc) {
not isReflectionCall(mc, _, _, _, _) and
not mc.isLateBound()
not mc.isLateBound() and
not isExtensionAccessorCall(mc)
} or
TDispatchAccessorCall(AccessorCall ac) or
TDispatchOperatorCall(OperatorCall oc) { not oc.isLateBound() } or
@@ -110,7 +111,8 @@ private module Internal {
c instanceof ConstructorInitializer
or
c instanceof LocalFunctionCall
}
} or
TDispatchExtensionAccessorCall(MethodCall mc) { isExtensionAccessorCall(mc) }
cached
Expr getCall(DispatchCall dc) { result = dc.(DispatchCallImpl).getCall() }
@@ -142,6 +144,8 @@ private module Internal {
import Cached
private predicate isExtensionAccessorCall(MethodCall mc) { exists(mc.getTargetAccessor()) }
/**
* Holds if `mc` is a reflection call to a method named `name`, where
* `object` is the object on which to invoke the method (`null` if a
@@ -819,6 +823,33 @@ private module Internal {
override Method getAStaticTarget() { result = this.getCall().getTarget() }
}
/**
* A call to an extension accessor method.
*/
private class DispatchExtensionAccessorCall extends DispatchCallImpl,
TDispatchExtensionAccessorCall
{
override MethodCall getCall() { this = TDispatchExtensionAccessorCall(result) }
private Expr getArgumentForParameter(Parameter p) {
this.getCall().getTargetAccessor().getAParameter() = p and
result = this.getCall().getArgument(p.getPosition())
}
override Expr getArgument(int i) {
exists(MethodCall call, Parameter p | call = this.getCall() |
p = call.getTargetAccessor().getParameter(i) and
result = this.getArgumentForParameter(p)
)
}
override Expr getQualifier() { result = this.getCall().getQualifier() }
override Accessor getAStaticTarget() { result = this.getCall().getTargetAccessor() }
override RuntimeCallable getADynamicTarget() { result = this.getAStaticTarget() }
}
/**
* An ordinary operator call.
*