You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
if (!TryInterpretMethodCall(r, m, paramExprs, paramValues, parentArgs, useFec, ref instance))
2918
2918
return false;
2919
2919
}
2920
-
else if (operandExpr is InvocationExpression i &&
2921
-
i.Expression is ConstantExpression cd &&
2922
-
cd.Value is FactoryDelegate d)
2920
+
else if (operandExpr is InvocationExpression invokeExpr &&
2921
+
invokeExpr.Expression is ConstantExpression cd && cd.Value is FactoryDelegate facDel)
2923
2922
{
2924
2923
// The majority of cases the delegate will be a well known `FactoryDelegate` - so calling it directly
2925
-
if (i.Arguments[0] == FactoryDelegateCompiler.ResolverContextParamExpr)
2926
-
result = d(r);
2927
-
else if (i.Arguments[0] == ResolverContext.RootOrSelfExpr)
2928
-
result = d(r.Root ?? r);
2929
-
else if (TryInterpret(r, i.Arguments[0], paramExprs, paramValues, parentArgs, useFec,
2930
-
out var resolver))
2931
-
result = d((IResolverContext)resolver);
2924
+
var rArg = invokeExpr.Arguments[0]; // todo: @perf optimize for a OneArgumentInvocationExpression
2925
+
if (rArg == FactoryDelegateCompiler.ResolverContextParamExpr)
2926
+
result = facDel(r);
2927
+
else if (rArg == ResolverContext.RootOrSelfExpr)
2928
+
result = facDel(r.Root ?? r);
2929
+
else if (TryInterpret(r, rArg, paramExprs, paramValues, parentArgs, useFec, out var resolver))
2930
+
result = facDel((IResolverContext)resolver);
2932
2931
else return false;
2933
2932
return true;
2934
2933
}
@@ -3006,6 +3005,18 @@ i.Expression is ConstantExpression cd &&
3006
3005
{
3007
3006
var invokeExpr = (InvocationExpression)expr;
3008
3007
var delegateExpr = invokeExpr.Expression;
3008
+
if (delegateExpr is ConstantExpression dc && dc.Value is FactoryDelegate facDel)
3009
+
{
3010
+
var rArg = invokeExpr.Arguments[0]; // todo: @perf optimize for a OneArgumentInvocationExpression
3011
+
if (rArg == FactoryDelegateCompiler.ResolverContextParamExpr)
3012
+
result = facDel(r);
3013
+
else if (rArg == ResolverContext.RootOrSelfExpr)
3014
+
result = facDel(r.Root ?? r);
3015
+
else if (TryInterpret(r, rArg, paramExprs, paramValues, parentArgs, useFec, out var resolver))
3016
+
result = facDel((IResolverContext)resolver);
3017
+
else return false;
3018
+
return true;
3019
+
}
3009
3020
3010
3021
// The Invocation of Func is used for splitting the big object graphs
3011
3022
// so we can ignore this split and go directly to the body
@@ -3015,23 +3026,20 @@ i.Expression is ConstantExpression cd &&
3015
3026
#if !SUPPORTS_DELEGATE_METHOD
3016
3027
return false;
3017
3028
#else
3018
-
if (!TryInterpret(r, delegateExpr, paramExprs, paramValues, parentArgs, useFec, out var delegateObj)) // todo: @perf avoid calling the TryInterpret for the known constant of FactoryDelegate
3029
+
if (!TryInterpret(r, delegateExpr, paramExprs, paramValues, parentArgs, useFec, out var delegateObj))
3019
3030
return false;
3020
3031
3021
3032
var lambda = (Delegate)delegateObj;
3022
3033
var argExprs = invokeExpr.Arguments.ToListOrSelf(); // todo: @perf recognize the OneArgumentInvocationExpression
3023
3034
if (argExprs.Count == 0)
3024
3035
result = lambda.GetMethodInfo().Invoke(lambda.Target, ArrayTools.Empty<object>());
3025
-
else
3036
+
else // it does not make sense to avoid array allocating for the single argument because we still need to pass array to the Invoke call
3026
3037
{
3027
-
var args = new object[argExprs.Count]; // todo: @perf avoid allocating for the single argument
3038
+
var args = new object[argExprs.Count];
3028
3039
for (var i = 0; i < args.Length; i++)
3029
-
if (!TryInterpret(r, argExprs[i], paramExprs, paramValues, parentArgs, useFec, out args[i])) // todo: @perf simplify for the single argument `r` of ResolverContext for FactoryDelegate
3040
+
if (!TryInterpret(r, argExprs[i], paramExprs, paramValues, parentArgs, useFec, out args[i]))
3030
3041
return false;
3031
-
if (lambda is FactoryDelegate fd)
3032
-
result = fd.Invoke((IResolverContext)args[0]);
3033
-
else
3034
-
result = lambda.GetMethodInfo().Invoke(lambda.Target, args);
3042
+
result = lambda.GetMethodInfo().Invoke(lambda.Target, args);
Copy file name to clipboardExpand all lines: test/DryIoc.IssuesTests/GHIssue315_Combining_RegisterDelegate_with_TrackingDisposableTransients_rule_throws_TargetParameterCountException.cs
0 commit comments