From ee2bf2d209eaffd252858ce1bc1c857ee4ab682e Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 4 Oct 2012 17:49:44 +0200 Subject: [PATCH] Fix method-group conversions involving extension methods. --- .../Resolver/CSharpConversions.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs index 152fa8e8eb..d75e4de3f0 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpConversions.cs @@ -926,7 +926,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver IMethod method = (IMethod)or.GetBestCandidateWithSubstitutedTypeArguments(); var thisRR = rr.TargetResult as ThisResolveResult; bool isVirtual = method.IsOverridable && !(thisRR != null && thisRR.CausesNonVirtualInvocation); - if (IsDelegateCompatible(method, invoke)) + bool isValid = !or.IsAmbiguous && IsDelegateCompatible(method, invoke, or.IsExtensionMethodInvocation); + if (isValid) return Conversion.MethodGroupConversion(method, isVirtual); else return Conversion.InvalidMethodGroupConversion(method, isVirtual); @@ -941,16 +942,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// The method to test for compatibility /// The invoke method of the delegate - public bool IsDelegateCompatible(IMethod m, IMethod invoke) + /// Gets whether m is accessed using extension method syntax. + /// If this parameter is true, the first parameter of will be ignored. + bool IsDelegateCompatible(IMethod m, IMethod invoke, bool isExtensionMethodInvocation) { if (m == null) throw new ArgumentNullException("m"); if (invoke == null) throw new ArgumentNullException("invoke"); - if (m.Parameters.Count != invoke.Parameters.Count) + int firstParameterInM = isExtensionMethodInvocation ? 1 : 0; + if (m.Parameters.Count - firstParameterInM != invoke.Parameters.Count) return false; - for (int i = 0; i < m.Parameters.Count; i++) { - var pm = m.Parameters[i]; + for (int i = 0; i < invoke.Parameters.Count; i++) { + var pm = m.Parameters[firstParameterInM + i]; var pd = invoke.Parameters[i]; // ret/out must match if (pm.IsRef != pd.IsRef || pm.IsOut != pd.IsOut)