diff --git a/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs b/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs index c4555cb8..b0c99e91 100644 --- a/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs +++ b/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Reflection; namespace Cpp2IL.Core.Model.Contexts; @@ -23,24 +24,76 @@ public InjectedMethodAnalysisContext( string name, TypeAnalysisContext returnType, MethodAttributes attributes, - TypeAnalysisContext[] injectedParameterTypes, - string[]? injectedParameterNames = null, - ParameterAttributes[]? injectedParameterAttributes = null, - MethodImplAttributes defaultImplAttributes = MethodImplAttributes.Managed) : base(null, parent) + IEnumerable injectedParameterTypes, + IEnumerable? injectedParameterNames = null, + IEnumerable? injectedParameterAttributes = null, + MethodImplAttributes implAttributes = MethodImplAttributes.Managed) : this(parent, name, returnType, attributes, GetParameters(injectedParameterTypes, injectedParameterNames, injectedParameterAttributes), implAttributes) + { + } + + public InjectedMethodAnalysisContext( + TypeAnalysisContext parent, + string name, + TypeAnalysisContext returnType, + MethodAttributes attributes, + IEnumerable<(TypeAnalysisContext Type, string? Name, ParameterAttributes Attributes)> parameters, + MethodImplAttributes implAttributes = MethodImplAttributes.Managed) : base(null, parent) { DefaultName = name; DefaultReturnType = returnType; DefaultAttributes = attributes; - for (var i = 0; i < injectedParameterTypes.Length; i++) + var i = 0; + foreach (var (parameterType, parameterName, parameterAttributes) in parameters) { - var injectedParameterType = injectedParameterTypes[i]; - var injectedParameterName = injectedParameterNames?[i]; - var injectedParameterAttribute = injectedParameterAttributes?[i] ?? ParameterAttributes.None; - - Parameters.Add(new InjectedParameterAnalysisContext(injectedParameterName, injectedParameterType, injectedParameterAttribute, i, this)); + Parameters.Add(new InjectedParameterAnalysisContext(parameterName, parameterType, parameterAttributes, i, this)); + i++; } - DefaultImplAttributes = defaultImplAttributes; + DefaultImplAttributes = implAttributes; + } + + private static IEnumerable<(TypeAnalysisContext Type, string? Name, ParameterAttributes Attributes)> GetParameters( + IEnumerable parameterTypes, + IEnumerable? parameterNames = null, + IEnumerable? parameterAttributes = null) + { + var typeEnumerator = parameterTypes.GetEnumerator(); + var nameEnumerator = parameterNames?.GetEnumerator(); + var attributeEnumerator = parameterAttributes?.GetEnumerator(); + if (nameEnumerator != null) + { + if (attributeEnumerator != null) + { + while (typeEnumerator.MoveNext() && nameEnumerator.MoveNext() && attributeEnumerator.MoveNext()) + { + yield return (typeEnumerator.Current, nameEnumerator.Current, attributeEnumerator.Current); + } + } + else + { + while (typeEnumerator.MoveNext() && nameEnumerator.MoveNext()) + { + yield return (typeEnumerator.Current, nameEnumerator.Current, ParameterAttributes.None); + } + } + } + else + { + if (attributeEnumerator != null) + { + while (typeEnumerator.MoveNext() && attributeEnumerator.MoveNext()) + { + yield return (typeEnumerator.Current, null, attributeEnumerator.Current); + } + } + else + { + while (typeEnumerator.MoveNext()) + { + yield return (typeEnumerator.Current, null, ParameterAttributes.None); + } + } + } } } diff --git a/Cpp2IL.Core/Model/Contexts/InjectedTypeAnalysisContext.cs b/Cpp2IL.Core/Model/Contexts/InjectedTypeAnalysisContext.cs index 549a2bc1..b4d0a09f 100644 --- a/Cpp2IL.Core/Model/Contexts/InjectedTypeAnalysisContext.cs +++ b/Cpp2IL.Core/Model/Contexts/InjectedTypeAnalysisContext.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Reflection; namespace Cpp2IL.Core.Model.Contexts; @@ -22,7 +23,7 @@ public InjectedTypeAnalysisContext(AssemblyAnalysisContext containingAssembly, s DefaultAttributes = typeAttributes; } - public InjectedMethodAnalysisContext InjectMethodContext(string methodName, TypeAnalysisContext returnType, MethodAttributes attributes, params TypeAnalysisContext[] args) + public InjectedMethodAnalysisContext InjectMethodContext(string methodName, TypeAnalysisContext returnType, MethodAttributes attributes, params IEnumerable args) { var method = new InjectedMethodAnalysisContext(this, methodName, returnType, attributes, args); Methods.Add(method); diff --git a/Cpp2IL.Core/Model/MultiAssemblyInjectedType.cs b/Cpp2IL.Core/Model/MultiAssemblyInjectedType.cs index 9a431ac0..0fb783d4 100644 --- a/Cpp2IL.Core/Model/MultiAssemblyInjectedType.cs +++ b/Cpp2IL.Core/Model/MultiAssemblyInjectedType.cs @@ -9,10 +9,10 @@ public class MultiAssemblyInjectedType(InjectedTypeAnalysisContext[] injectedTyp { public InjectedTypeAnalysisContext[] InjectedTypes { get; } = injectedTypes; - public Dictionary InjectMethodToAllAssemblies(string name, TypeAnalysisContext returnType, MethodAttributes attributes, params TypeAnalysisContext[] args) + public Dictionary InjectMethodToAllAssemblies(string name, TypeAnalysisContext returnType, MethodAttributes attributes, params IEnumerable args) => InjectedTypes.ToDictionary(t => t.DeclaringAssembly, t => t.InjectMethodContext(name, returnType, attributes, args)); - public Dictionary InjectConstructor(bool isStatic, params TypeAnalysisContext[] args) + public Dictionary InjectConstructor(bool isStatic, params IEnumerable args) { var attributes = isStatic ? MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Static