From 3098461b0e8759005103cec2fa09555af0cf54d0 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 20 Sep 2017 21:03:11 +0200 Subject: [PATCH] Add support for ctors to IsUnambiguousCall --- .../CSharp/ExpressionBuilder.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 5126bf07d..68eb7c4af 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1267,15 +1267,20 @@ namespace ICSharpCode.Decompiler.CSharp OverloadResolutionErrors IsUnambiguousCall(ILInstruction inst, TranslatedExpression target, IMethod method, IType[] typeArguments, IList arguments) { - // TODO : MemberLookup does not support ctors. (target is null in that case! -> NullArgumentException is thrown) - if (inst.OpCode == OpCode.NewObj) - return OverloadResolutionErrors.None; var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentAssembly); - var result = lookup.Lookup(target.ResolveResult, method.Name, EmptyList.Instance, true) as MethodGroupResolveResult; - if (result == null) - return OverloadResolutionErrors.AmbiguousMatch; var or = new OverloadResolution(resolver.Compilation, arguments.SelectArray(a => a.ResolveResult), typeArguments: typeArguments); - or.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray()); + if (inst is NewObj newObj) { + foreach (IMethod ctor in newObj.Method.DeclaringType.GetConstructors()) { + if (lookup.IsAccessible(ctor, allowProtectedAccess: resolver.CurrentTypeDefinition == newObj.Method.DeclaringTypeDefinition)) { + or.AddCandidate(ctor); + } + } + } else { + var result = lookup.Lookup(target.ResolveResult, method.Name, EmptyList.Instance, true) as MethodGroupResolveResult; + if (result == null) + return OverloadResolutionErrors.AmbiguousMatch; + or.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray()); + } if (or.BestCandidateErrors != OverloadResolutionErrors.None) return or.BestCandidateErrors; if (!IsAppropriateCallTarget(method, or.GetBestCandidateWithSubstitutedTypeArguments(), inst.OpCode == OpCode.CallVirt))