From 8323eb79b876ce106ce831d6d7da60b40cf9a22e Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 22 Jun 2025 08:23:47 +0200 Subject: [PATCH] Add support for newobj ROS(in arg) to TransformParamsArgument. --- ICSharpCode.Decompiler/CSharp/CallBuilder.cs | 79 +++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs index 058eff4e3..5efb802ee 100644 --- a/ICSharpCode.Decompiler/CSharp/CallBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/CallBuilder.cs @@ -1026,25 +1026,14 @@ namespace ICSharpCode.Decompiler.CSharp } private bool TransformParamsArgument(ExpectedTargetDetails expectedTargetDetails, ResolveResult targetResolveResult, - IMethod method, IParameter parameter, TranslatedExpression arg, ref List expectedParameters, + IMethod method, IParameter parameter, TranslatedExpression paramsArgument, ref List expectedParameters, ref List 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(expectedParameters); - var expandedArguments = new List(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()); - } - } + expandedParameters.InsertRange(0, expectedParameters); + expandedArguments.InsertRange(0, arguments); if (IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, Empty.Array, expandedArguments.SelectArray(a => a.ResolveResult), argumentNames: null, firstOptionalArgumentIndex: -1, out _, @@ -1057,30 +1046,46 @@ namespace ICSharpCode.Decompiler.CSharp } return false; - bool CheckArgument(out int len, out IType t) + bool ExtractArguments(out IType elementType, out List parameters, out List arguments) { - len = 0; - t = null; - if (arg.ResolveResult is CSharpInvocationResolveResult csirr && - csirr.Arguments.Count == 0 && csirr.Member is IMethod emptyMethod && - emptyMethod.IsStatic && - "System.Array.Empty" == emptyMethod.FullName && - emptyMethod.TypeArguments.Count == 1) + elementType = null; + parameters = null; + arguments = null; + switch (paramsArgument.ResolveResult) { - t = emptyMethod.TypeArguments[0]; - return true; - } - - if (arg.ResolveResult is ArrayCreateResolveResult acrr && - acrr.SizeArguments.Count == 1 && - acrr.SizeArguments[0].IsCompileTimeConstant && - acrr.SizeArguments[0].ConstantValue is int l) - { - len = l; - t = ((ArrayType)acrr.Type).ElementType; - return true; + case CSharpInvocationResolveResult { Member: IMethod method, Arguments: var args }: + // match System.Array.Empty() + if (args is [] && method is { IsStatic: true, FullName: "System.Array.Empty", TypeArguments: [var type] }) + { + elementType = type; + arguments = new(); + parameters = new(); + return true; + } + if (paramsArgument.Expression is ObjectCreateExpression oce + && method is { IsConstructor: true, DeclaringType: { TypeArguments: [var type2] } declaringType } + && 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(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; } }