|
|
|
@ -52,6 +52,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -52,6 +52,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
public IReadOnlyList<int> ArgumentToParameterMap; |
|
|
|
|
|
|
|
|
|
public bool AddNamesToPrimitiveValues; |
|
|
|
|
public bool UseImplicitlyTypedOut; |
|
|
|
|
public bool IsExpandedForm; |
|
|
|
|
public int Length => Arguments.Length; |
|
|
|
|
|
|
|
|
@ -62,9 +63,33 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -62,9 +63,33 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
return FirstOptionalArgumentIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public IEnumerable<ResolveResult> GetArgumentResolveResults(int skipCount = 0) |
|
|
|
|
public IList<ResolveResult> GetArgumentResolveResults(int skipCount = 0) |
|
|
|
|
{ |
|
|
|
|
return Arguments.Skip(skipCount).Take(GetActualArgumentCount()).Select(a => a.ResolveResult); |
|
|
|
|
var expectedParameters = ExpectedParameters; |
|
|
|
|
var useImplicitlyTypedOut = UseImplicitlyTypedOut; |
|
|
|
|
|
|
|
|
|
return Arguments |
|
|
|
|
.SelectWithIndex(GetResolveResult) |
|
|
|
|
.Skip(skipCount) |
|
|
|
|
.Take(GetActualArgumentCount()) |
|
|
|
|
.ToArray(); |
|
|
|
|
|
|
|
|
|
ResolveResult GetResolveResult(int index, TranslatedExpression expression) |
|
|
|
|
{ |
|
|
|
|
var param = expectedParameters[index]; |
|
|
|
|
if (useImplicitlyTypedOut && param.IsOut) |
|
|
|
|
return OutVarResolveResult.Instance; |
|
|
|
|
return expression.ResolveResult; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public IList<ResolveResult> GetArgumentResolveResultsDirect(int skipCount = 0) |
|
|
|
|
{ |
|
|
|
|
return Arguments |
|
|
|
|
.Skip(skipCount) |
|
|
|
|
.Take(GetActualArgumentCount()) |
|
|
|
|
.Select(a => a.ResolveResult) |
|
|
|
|
.ToArray(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public IEnumerable<Expression> GetArgumentExpressions(int skipCount = 0) |
|
|
|
@ -87,9 +112,10 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -87,9 +112,10 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
int argumentCount = GetActualArgumentCount(); |
|
|
|
|
var useImplicitlyTypedOut = UseImplicitlyTypedOut; |
|
|
|
|
if (ArgumentNames == null) |
|
|
|
|
{ |
|
|
|
|
return Arguments.Skip(skipCount).Take(argumentCount).Select(arg => arg.Expression); |
|
|
|
|
return Arguments.Skip(skipCount).Take(argumentCount).Select(arg => AddAnnotations(arg.Expression)); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -97,11 +123,23 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -97,11 +123,23 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
return Arguments.Take(argumentCount).Zip(ArgumentNames.Take(argumentCount), |
|
|
|
|
(arg, name) => { |
|
|
|
|
if (name == null) |
|
|
|
|
return arg.Expression; |
|
|
|
|
return AddAnnotations(arg.Expression); |
|
|
|
|
else |
|
|
|
|
return new NamedArgumentExpression(name, arg); |
|
|
|
|
return new NamedArgumentExpression(name, AddAnnotations(arg.Expression)); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Expression AddAnnotations(Expression expression) |
|
|
|
|
{ |
|
|
|
|
if (!useImplicitlyTypedOut) |
|
|
|
|
return expression; |
|
|
|
|
if (expression.GetResolveResult() is ByReferenceResolveResult brrr |
|
|
|
|
&& brrr.IsOut) |
|
|
|
|
{ |
|
|
|
|
expression.AddAnnotation(UseImplicitlyTypedOutAnnotation.Instance); |
|
|
|
|
} |
|
|
|
|
return expression; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public bool CanInferAnonymousTypePropertyNamesFromArguments() |
|
|
|
@ -255,13 +293,14 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -255,13 +293,14 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
{ |
|
|
|
|
return new InvocationExpression(target, argumentList.GetArgumentExpressions()) |
|
|
|
|
.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method, |
|
|
|
|
argumentList.GetArgumentResolveResults().ToList(), isExpandedForm: argumentList.IsExpandedForm)); |
|
|
|
|
argumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (method is VarArgInstanceMethod) |
|
|
|
|
{ |
|
|
|
|
argumentList.FirstOptionalArgumentIndex = -1; |
|
|
|
|
argumentList.AddNamesToPrimitiveValues = false; |
|
|
|
|
argumentList.UseImplicitlyTypedOut = false; |
|
|
|
|
int regularParameterCount = ((VarArgInstanceMethod)method).RegularParameterCount; |
|
|
|
|
var argListArg = new UndocumentedExpression(); |
|
|
|
|
argListArg.UndocumentedExpressionType = UndocumentedExpressionType.ArgList; |
|
|
|
@ -293,7 +332,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -293,7 +332,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
{ |
|
|
|
|
return new InvocationExpression(target, argumentList.GetArgumentExpressions()) |
|
|
|
|
.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method, |
|
|
|
|
argumentList.GetArgumentResolveResults().ToList(), isExpandedForm: argumentList.IsExpandedForm, isDelegateInvocation: true)); |
|
|
|
|
argumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm, isDelegateInvocation: true)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (settings.StringInterpolation && IsInterpolatedStringCreation(method, argumentList) && |
|
|
|
@ -340,7 +379,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -340,7 +379,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
} |
|
|
|
|
var formattableStringType = expressionBuilder.compilation.FindType(KnownTypeCode.FormattableString); |
|
|
|
|
var isrr = new InterpolatedStringResolveResult(expressionBuilder.compilation.FindType(KnownTypeCode.String), |
|
|
|
|
format, argumentList.GetArgumentResolveResults().Skip(1).ToArray()); |
|
|
|
|
format, argumentList.GetArgumentResolveResults(1).ToArray()); |
|
|
|
|
var expr = new InterpolatedStringExpression(); |
|
|
|
|
expr.Content.AddRange(content); |
|
|
|
|
if (method.Name == "Format") |
|
|
|
@ -363,7 +402,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -363,7 +402,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
argumentList.CheckNoNamedOrOptionalArguments(); |
|
|
|
|
return HandleDelegateEqualityComparison(method, argumentList.Arguments) |
|
|
|
|
.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, method, |
|
|
|
|
argumentList.GetArgumentResolveResults().ToList(), isExpandedForm: argumentList.IsExpandedForm)); |
|
|
|
|
argumentList.GetArgumentResolveResults(), isExpandedForm: argumentList.IsExpandedForm)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (method.IsOperator && method.Name == "op_Implicit" && argumentList.Length == 1) |
|
|
|
@ -420,7 +459,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -420,7 +459,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
typeArgumentList.AddRange(method.TypeArguments.Select(expressionBuilder.ConvertType)); |
|
|
|
|
return new InvocationExpression(targetExpr, argumentList.GetArgumentExpressions()) |
|
|
|
|
.WithRR(new CSharpInvocationResolveResult(target.ResolveResult, foundMethod, |
|
|
|
|
argumentList.GetArgumentResolveResults().ToList(), isExpandedForm: argumentList.IsExpandedForm)); |
|
|
|
|
argumentList.GetArgumentResolveResultsDirect(), isExpandedForm: argumentList.IsExpandedForm)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -457,6 +496,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -457,6 +496,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
firstParamIndex: 0, args, null); |
|
|
|
|
argumentList.ArgumentNames = null; |
|
|
|
|
argumentList.AddNamesToPrimitiveValues = false; |
|
|
|
|
argumentList.UseImplicitlyTypedOut = false; |
|
|
|
|
var transform = GetRequiredTransformationsForCall(expectedTargetDetails, method, ref unused, |
|
|
|
|
ref argumentList, CallTransformation.None, out _); |
|
|
|
|
Debug.Assert(transform == CallTransformation.None || transform == CallTransformation.NoOptionalArgumentAllowed); |
|
|
|
@ -755,6 +795,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -755,6 +795,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
list.IsExpandedForm = isExpandedForm; |
|
|
|
|
list.IsPrimitiveValue = isPrimitiveValue; |
|
|
|
|
list.FirstOptionalArgumentIndex = firstOptionalArgumentIndex; |
|
|
|
|
list.UseImplicitlyTypedOut = true; |
|
|
|
|
list.AddNamesToPrimitiveValues = expressionBuilder.settings.NamedArguments && expressionBuilder.settings.NonTrailingNamedArguments; |
|
|
|
|
return list; |
|
|
|
|
} |
|
|
|
@ -787,7 +828,8 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -787,7 +828,8 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, Empty<IType>.Array, |
|
|
|
|
expandedArguments, argumentNames: null, firstOptionalArgumentIndex: -1, out _, |
|
|
|
|
expandedArguments.SelectArray(a => a.ResolveResult), argumentNames: null, |
|
|
|
|
firstOptionalArgumentIndex: -1, out _, |
|
|
|
|
out var bestCandidateIsExpandedForm) == OverloadResolutionErrors.None && bestCandidateIsExpandedForm) |
|
|
|
|
{ |
|
|
|
|
expectedParameters = expandedParameters; |
|
|
|
@ -917,7 +959,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -917,7 +959,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
bool argumentsCasted = false; |
|
|
|
|
OverloadResolutionErrors errors; |
|
|
|
|
while ((errors = IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, typeArguments, |
|
|
|
|
argumentList.Arguments, argumentList.ArgumentNames, argumentList.FirstOptionalArgumentIndex, out foundMethod, |
|
|
|
|
argumentList.GetArgumentResolveResults().ToArray(), argumentList.ArgumentNames, argumentList.FirstOptionalArgumentIndex, out foundMethod, |
|
|
|
|
out var bestCandidateIsExpandedForm)) != OverloadResolutionErrors.None || bestCandidateIsExpandedForm != argumentList.IsExpandedForm) |
|
|
|
|
{ |
|
|
|
|
switch (errors) |
|
|
|
@ -958,6 +1000,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -958,6 +1000,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
appliedRequireTypeArgumentsShortcut = false; |
|
|
|
|
} |
|
|
|
|
argumentsCasted = true; |
|
|
|
|
argumentList.UseImplicitlyTypedOut = false; |
|
|
|
|
CastArguments(argumentList.Arguments, argumentList.ExpectedParameters); |
|
|
|
|
} |
|
|
|
|
else if ((allowedTransforms & CallTransformation.RequireTarget) != 0 && !requireTarget) |
|
|
|
@ -1116,27 +1159,32 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -1116,27 +1159,32 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
OverloadResolutionErrors IsUnambiguousCall(ExpectedTargetDetails expectedTargetDetails, IMethod method, |
|
|
|
|
ResolveResult target, IType[] typeArguments, IList<TranslatedExpression> arguments, |
|
|
|
|
ResolveResult target, IType[] typeArguments, ResolveResult[] arguments, |
|
|
|
|
string[] argumentNames, int firstOptionalArgumentIndex, |
|
|
|
|
out IParameterizedMember foundMember, out bool bestCandidateIsExpandedForm) |
|
|
|
|
{ |
|
|
|
|
foundMember = null; |
|
|
|
|
bestCandidateIsExpandedForm = false; |
|
|
|
|
var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentModule); |
|
|
|
|
var currentTypeDefinition = resolver.CurrentTypeDefinition; |
|
|
|
|
var lookup = new MemberLookup(currentTypeDefinition, currentTypeDefinition.ParentModule); |
|
|
|
|
|
|
|
|
|
Log.WriteLine("IsUnambiguousCall: Performing overload resolution for " + method); |
|
|
|
|
Log.WriteCollection(" Arguments: ", arguments.Select(a => a.ResolveResult)); |
|
|
|
|
Log.WriteCollection(" Arguments: ", arguments); |
|
|
|
|
|
|
|
|
|
argumentNames = firstOptionalArgumentIndex < 0 || argumentNames == null |
|
|
|
|
? argumentNames |
|
|
|
|
: argumentNames.Take(firstOptionalArgumentIndex).ToArray(); |
|
|
|
|
|
|
|
|
|
var or = new OverloadResolution(resolver.Compilation, |
|
|
|
|
firstOptionalArgumentIndex < 0 ? arguments.SelectArray(a => a.ResolveResult) : arguments.Take(firstOptionalArgumentIndex).Select(a => a.ResolveResult).ToArray(), |
|
|
|
|
argumentNames: firstOptionalArgumentIndex < 0 || argumentNames == null ? argumentNames : argumentNames.Take(firstOptionalArgumentIndex).ToArray(), |
|
|
|
|
typeArguments: typeArguments, |
|
|
|
|
arguments, argumentNames, typeArguments, |
|
|
|
|
conversions: expressionBuilder.resolver.conversions); |
|
|
|
|
if (expectedTargetDetails.CallOpCode == OpCode.NewObj) |
|
|
|
|
{ |
|
|
|
|
foreach (IMethod ctor in method.DeclaringType.GetConstructors()) |
|
|
|
|
{ |
|
|
|
|
if (lookup.IsAccessible(ctor, allowProtectedAccess: resolver.CurrentTypeDefinition == method.DeclaringTypeDefinition)) |
|
|
|
|
bool allowProtectedAccess = |
|
|
|
|
resolver.CurrentTypeDefinition == method.DeclaringTypeDefinition; |
|
|
|
|
if (lookup.IsAccessible(ctor, allowProtectedAccess)) |
|
|
|
|
{ |
|
|
|
|
or.AddCandidate(ctor); |
|
|
|
|
} |
|
|
|
@ -1145,12 +1193,12 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -1145,12 +1193,12 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
else if (method.IsOperator) |
|
|
|
|
{ |
|
|
|
|
IEnumerable<IParameterizedMember> operatorCandidates; |
|
|
|
|
if (arguments.Count == 1) |
|
|
|
|
if (arguments.Length == 1) |
|
|
|
|
{ |
|
|
|
|
IType argType = NullableType.GetUnderlyingType(arguments[0].Type); |
|
|
|
|
operatorCandidates = resolver.GetUserDefinedOperatorCandidates(argType, method.Name); |
|
|
|
|
} |
|
|
|
|
else if (arguments.Count == 2) |
|
|
|
|
else if (arguments.Length == 2) |
|
|
|
|
{ |
|
|
|
|
IType lhsType = NullableType.GetUnderlyingType(arguments[0].Type); |
|
|
|
|
IType rhsType = NullableType.GetUnderlyingType(arguments[1].Type); |
|
|
|
@ -1170,7 +1218,8 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -1170,7 +1218,8 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
} |
|
|
|
|
else if (target == null) |
|
|
|
|
{ |
|
|
|
|
var result = resolver.ResolveSimpleName(method.Name, typeArguments, isInvocationTarget: true) as MethodGroupResolveResult; |
|
|
|
|
var result = resolver.ResolveSimpleName(method.Name, typeArguments, isInvocationTarget: true) |
|
|
|
|
as MethodGroupResolveResult; |
|
|
|
|
if (result == null) |
|
|
|
|
return OverloadResolutionErrors.AmbiguousMatch; |
|
|
|
|
or.AddMethodLists(result.MethodsGroupedByDeclaringType.ToArray()); |
|
|
|
@ -1386,13 +1435,14 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -1386,13 +1435,14 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return atce.WithRR(new CSharpInvocationResolveResult( |
|
|
|
|
target, method, argumentList.GetArgumentResolveResults().ToList(), |
|
|
|
|
target, method, argumentList.GetArgumentResolveResults(), |
|
|
|
|
isExpandedForm: argumentList.IsExpandedForm, argumentToParameterMap: argumentList.ArgumentToParameterMap |
|
|
|
|
)); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
while (IsUnambiguousCall(expectedTargetDetails, method, null, Empty<IType>.Array, argumentList.Arguments, |
|
|
|
|
while (IsUnambiguousCall(expectedTargetDetails, method, null, Empty<IType>.Array, |
|
|
|
|
argumentList.GetArgumentResolveResults().ToArray(), |
|
|
|
|
argumentList.ArgumentNames, argumentList.FirstOptionalArgumentIndex, out _, |
|
|
|
|
out var bestCandidateIsExpandedForm) != OverloadResolutionErrors.None || bestCandidateIsExpandedForm != argumentList.IsExpandedForm) |
|
|
|
|
{ |
|
|
|
|