|
|
@ -1026,25 +1026,14 @@ namespace ICSharpCode.Decompiler.CSharp |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private bool TransformParamsArgument(ExpectedTargetDetails expectedTargetDetails, ResolveResult targetResolveResult, |
|
|
|
private bool TransformParamsArgument(ExpectedTargetDetails expectedTargetDetails, ResolveResult targetResolveResult, |
|
|
|
IMethod method, IParameter parameter, TranslatedExpression arg, ref List<IParameter> expectedParameters, |
|
|
|
IMethod method, IParameter parameter, TranslatedExpression paramsArgument, ref List<IParameter> expectedParameters, |
|
|
|
ref List<TranslatedExpression> arguments) |
|
|
|
ref List<TranslatedExpression> arguments) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (CheckArgument(out int length, out IType elementType)) |
|
|
|
var expressionBuilder = this.expressionBuilder; |
|
|
|
|
|
|
|
if (ExtractArguments(out IType elementType, out var expandedParameters, out var expandedArguments)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var expandedParameters = new List<IParameter>(expectedParameters); |
|
|
|
expandedParameters.InsertRange(0, expectedParameters); |
|
|
|
var expandedArguments = new List<TranslatedExpression>(arguments); |
|
|
|
expandedArguments.InsertRange(0, arguments); |
|
|
|
if (length > 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var arrayElements = ((ArrayCreateExpression)arg.Expression).Initializer.Elements.ToArray(); |
|
|
|
|
|
|
|
for (int j = 0; j < length; j++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
expandedParameters.Add(new DefaultParameter(elementType, parameter.Name + j)); |
|
|
|
|
|
|
|
if (j < arrayElements.Length) |
|
|
|
|
|
|
|
expandedArguments.Add(new TranslatedExpression(arrayElements[j])); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
expandedArguments.Add(expressionBuilder.GetDefaultValueExpression(elementType).WithoutILInstruction()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, Empty<IType>.Array, |
|
|
|
if (IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, Empty<IType>.Array, |
|
|
|
expandedArguments.SelectArray(a => a.ResolveResult), argumentNames: null, |
|
|
|
expandedArguments.SelectArray(a => a.ResolveResult), argumentNames: null, |
|
|
|
firstOptionalArgumentIndex: -1, out _, |
|
|
|
firstOptionalArgumentIndex: -1, out _, |
|
|
@ -1057,30 +1046,46 @@ namespace ICSharpCode.Decompiler.CSharp |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
bool CheckArgument(out int len, out IType t) |
|
|
|
bool ExtractArguments(out IType elementType, out List<IParameter> parameters, out List<TranslatedExpression> arguments) |
|
|
|
{ |
|
|
|
{ |
|
|
|
len = 0; |
|
|
|
elementType = null; |
|
|
|
t = null; |
|
|
|
parameters = null; |
|
|
|
if (arg.ResolveResult is CSharpInvocationResolveResult csirr && |
|
|
|
arguments = null; |
|
|
|
csirr.Arguments.Count == 0 && csirr.Member is IMethod emptyMethod && |
|
|
|
switch (paramsArgument.ResolveResult) |
|
|
|
emptyMethod.IsStatic && |
|
|
|
|
|
|
|
"System.Array.Empty" == emptyMethod.FullName && |
|
|
|
|
|
|
|
emptyMethod.TypeArguments.Count == 1) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
t = emptyMethod.TypeArguments[0]; |
|
|
|
case CSharpInvocationResolveResult { Member: IMethod method, Arguments: var args }: |
|
|
|
return true; |
|
|
|
// match System.Array.Empty<T>()
|
|
|
|
} |
|
|
|
if (args is [] && method is { IsStatic: true, FullName: "System.Array.Empty", TypeArguments: [var type] }) |
|
|
|
|
|
|
|
{ |
|
|
|
if (arg.ResolveResult is ArrayCreateResolveResult acrr && |
|
|
|
elementType = type; |
|
|
|
acrr.SizeArguments.Count == 1 && |
|
|
|
arguments = new(); |
|
|
|
acrr.SizeArguments[0].IsCompileTimeConstant && |
|
|
|
parameters = new(); |
|
|
|
acrr.SizeArguments[0].ConstantValue is int l) |
|
|
|
return true; |
|
|
|
{ |
|
|
|
} |
|
|
|
len = l; |
|
|
|
if (paramsArgument.Expression is ObjectCreateExpression oce |
|
|
|
t = ((ArrayType)acrr.Type).ElementType; |
|
|
|
&& method is { IsConstructor: true, DeclaringType: { TypeArguments: [var type2] } declaringType } |
|
|
|
return true; |
|
|
|
&& declaringType.IsKnownType(KnownTypeCode.ReadOnlySpanOfT)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
elementType = type2; |
|
|
|
|
|
|
|
arguments = new() { new TranslatedExpression(oce.Arguments.Single()) }; |
|
|
|
|
|
|
|
parameters = new() { new DefaultParameter(type2, string.Empty) }; |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
case ArrayCreateResolveResult { Type: ArrayType { ElementType: var type3 }, SizeArguments: [{ ConstantValue: int arrayLength }] }: |
|
|
|
|
|
|
|
elementType = type3; |
|
|
|
|
|
|
|
arguments = new(((ArrayCreateExpression)paramsArgument.Expression).Initializer.Elements.Select(e => new TranslatedExpression(e))); |
|
|
|
|
|
|
|
parameters = new List<IParameter>(arrayLength); |
|
|
|
|
|
|
|
for (int i = 0; i < arrayLength; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
parameters.Add(new DefaultParameter(type3, string.Empty)); |
|
|
|
|
|
|
|
if (arguments.Count <= i) |
|
|
|
|
|
|
|
arguments.Add(new TranslatedExpression(expressionBuilder.GetDefaultValueExpression(type3).WithoutILInstruction())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|