• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SamboyCoding / Cpp2IL / 15173156024

21 May 2025 09:41PM UTC coverage: 34.291% (+0.2%) from 34.062%
15173156024

Pull #462

github

web-flow
Merge 01e84d727 into 5807d2b6c
Pull Request #462: Support overriding anything

1801 of 6646 branches covered (27.1%)

Branch coverage included in aggregate %.

133 of 243 new or added lines in 35 files covered. (54.73%)

5 existing lines in 5 files now uncovered.

4201 of 10857 relevant lines covered (38.69%)

186186.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.13
/Cpp2IL.Core/Model/Contexts/ConcreteGenericMethodAnalysisContext.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Reflection;
4
using Cpp2IL.Core.Utils;
5
using LibCpp2IL;
6
using LibCpp2IL.Reflection;
7

8
namespace Cpp2IL.Core.Model.Contexts;
9

10
public class ConcreteGenericMethodAnalysisContext : MethodAnalysisContext
11
{
12
    public readonly AssemblyAnalysisContext DeclaringAsm;
13
    public readonly Cpp2IlMethodRef? MethodRef;
14
    public readonly MethodAnalysisContext BaseMethodContext;
15

16
    /// <summary>
17
    /// The generic parameters for the <see cref="BaseMethodContext"/> declaring type.
18
    /// </summary>
19
    /// <remarks>
20
    /// If not empty, <see cref="MethodAnalysisContext.DeclaringType"/> is a <see cref="GenericInstanceTypeAnalysisContext"/>.
21
    /// </remarks>
NEW
22
    public IReadOnlyList<TypeAnalysisContext> TypeGenericParameters { get; }
×
23

24
    /// <summary>
25
    /// The generic parameters for the <see cref="BaseMethodContext"/>.
26
    /// </summary>
27
    /// <remarks>
28
    /// These may be empty if <see cref="BaseMethodContext"/> has no generic parameters or if <see cref="IsPartialInstantiation"/>.
29
    /// </remarks>
30
    public IReadOnlyList<TypeAnalysisContext> MethodGenericParameters { get; }
325✔
31

32
    /// <summary>
33
    /// If true, this is a generic method on a <see cref="GenericInstanceTypeAnalysisContext"/>, but it does not specify any <see cref="MethodGenericParameters"/>.
34
    /// </summary>
NEW
35
    public bool IsPartialInstantiation => MethodGenericParameters.Count == 0 && BaseMethodContext.GenericParameters.Count > 0;
×
36

37
    public sealed override ulong UnderlyingPointer => MethodRef?.GenericVariantPtr ?? default;
894,204✔
38

39
    public override string DefaultName => BaseMethodContext.DefaultName;
325✔
40

NEW
41
    public override TypeAnalysisContext DefaultReturnType { get; }
×
42

43
    public override string? OverrideName { get => BaseMethodContext.OverrideName; set => BaseMethodContext.OverrideName = value; }
325✔
44

NEW
45
    public override MethodAttributes DefaultAttributes => BaseMethodContext.DefaultAttributes;
×
46

NEW
47
    public override MethodAttributes? OverrideAttributes { get => BaseMethodContext.OverrideAttributes; set => BaseMethodContext.OverrideAttributes = value; }
×
48

NEW
49
    public override MethodImplAttributes DefaultImplAttributes => BaseMethodContext.DefaultImplAttributes;
×
50

NEW
51
    public override MethodImplAttributes? OverrideImplAttributes { get => BaseMethodContext.OverrideImplAttributes; set => BaseMethodContext.OverrideImplAttributes = value; }
×
52

53
    public override AssemblyAnalysisContext CustomAttributeAssembly => BaseMethodContext.CustomAttributeAssembly;
×
54

55
    public ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef methodRef, ApplicationAnalysisContext context)
56
        : this(methodRef, ResolveDeclaringAssembly(methodRef, context))
298,308✔
57
    {
58
    }
298,308✔
59

60
    private ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef methodRef, AssemblyAnalysisContext declaringAssembly)
61
        : this(
298,308✔
62
              methodRef,
298,308✔
63
              ResolveBaseMethod(methodRef, declaringAssembly.GetTypeByDefinition(methodRef.DeclaringType)!),
298,308✔
64
              ResolveDeclaringType(methodRef, declaringAssembly),
298,308✔
65
              ResolveTypeArray(methodRef.TypeGenericParams, declaringAssembly),
298,308✔
66
              ResolveTypeArray(methodRef.MethodGenericParams, declaringAssembly),
298,308✔
67
              declaringAssembly)
298,308✔
68
    {
69
    }
298,308✔
70

71
    /// <summary>
72
    /// Generically instantiate a method.
73
    /// </summary>
74
    /// <param name="baseMethod">The method definition on which this instantiation is based.</param>
75
    /// <param name="typeGenericParameters">The type parameters for the declaring type, if any. These must always be specified.</param>
76
    /// <param name="methodGenericParameters">
77
    /// The type parameters for the base method, if any.
78
    /// These may be omitted (<see cref="IsPartialInstantiation"/> == <see langword="true"/>).
79
    /// </param>
80
    public ConcreteGenericMethodAnalysisContext(MethodAnalysisContext baseMethod, IEnumerable<TypeAnalysisContext> typeGenericParameters, IEnumerable<TypeAnalysisContext> methodGenericParameters)
81
        : this(baseMethod, [.. typeGenericParameters], [.. methodGenericParameters])
330✔
82
    {
83
    }
330✔
84

85
    private ConcreteGenericMethodAnalysisContext(MethodAnalysisContext baseMethod, TypeAnalysisContext[] typeGenericParameters, TypeAnalysisContext[] methodGenericParameters)
86
        : this(
330!
87
              null,
330✔
88
              baseMethod,
330✔
89
              typeGenericParameters.Length > 0 ? baseMethod.DeclaringType!.MakeGenericInstanceType(typeGenericParameters) : baseMethod.DeclaringType!,
330✔
90
              typeGenericParameters,
330✔
91
              methodGenericParameters,
330✔
92
              baseMethod.CustomAttributeAssembly)
330✔
93
    {
94
        if (baseMethod.DeclaringType!.GenericParameters.Count != typeGenericParameters.Length)
330!
95
            throw new ArgumentException("The number of type generic parameters must match the number of generic parameters on the declaring type.");
×
96

97
        if (methodGenericParameters.Length > 0 && baseMethod.GenericParameters.Count != methodGenericParameters.Length)
330!
98
            throw new ArgumentException("The number of method generic parameters must match the number of generic parameters on the base method.");
×
99
    }
330✔
100

101
    private ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef? methodRef, MethodAnalysisContext baseMethodContext, TypeAnalysisContext declaringType, TypeAnalysisContext[] typeGenericParameters, TypeAnalysisContext[] methodGenericParameters, AssemblyAnalysisContext declaringAssembly)
102
        : base(null, declaringType)
298,638✔
103
    {
104
        MethodRef = methodRef;
298,638✔
105
        DeclaringAsm = declaringAssembly;
298,638✔
106
        BaseMethodContext = baseMethodContext;
298,638✔
107

108
        TypeGenericParameters = typeGenericParameters;
298,638✔
109
        MethodGenericParameters = methodGenericParameters;
298,638✔
110

111
        // For the purpose of generic instantiation, we need an array of method generic parameters, even if none are provided.
112
        if (methodGenericParameters.Length == 0 && baseMethodContext.GenericParameters.Count > 0)
298,638✔
113
            methodGenericParameters = baseMethodContext.GenericParameters.ToArray();
5✔
114

115
        for (var i = 0; i < BaseMethodContext.Parameters.Count; i++)
1,228,522✔
116
        {
117
            var parameter = BaseMethodContext.Parameters[i];
315,623✔
118
            var instantiatedType = GenericInstantiation.Instantiate(
315,623✔
119
                parameter.ParameterType,
315,623✔
120
                typeGenericParameters,
315,623✔
121
                methodGenericParameters);
315,623✔
122

123
            Parameters.Add(new ConcreteGenericParameterAnalysisContext(parameter, instantiatedType, this));
315,623✔
124
        }
125

126
        DefaultReturnType = GenericInstantiation.Instantiate(BaseMethodContext.ReturnType, typeGenericParameters, methodGenericParameters);
298,638✔
127

128
        if (UnderlyingPointer != 0)
298,638✔
129
            rawMethodBody = AppContext.InstructionSet.GetRawBytesForMethod(this, false);
297,258✔
130
    }
298,638✔
131

132
    private static AssemblyAnalysisContext ResolveDeclaringAssembly(Cpp2IlMethodRef methodRef, ApplicationAnalysisContext context)
133
    {
134
        return context.GetAssemblyByName(methodRef.DeclaringType.DeclaringAssembly!.Name!)
298,308!
135
               ?? throw new($"Unable to resolve declaring assembly {methodRef.DeclaringType.DeclaringAssembly.Name} for generic method {methodRef}");
298,308✔
136
    }
137

138
    private static TypeAnalysisContext ResolveDeclaringType(Cpp2IlMethodRef methodRef, AssemblyAnalysisContext declaringAssembly)
139
    {
140
        var baseType = declaringAssembly.AppContext.ResolveContextForType(methodRef.DeclaringType)
298,308!
141
                       ?? throw new($"Unable to resolve declaring type {methodRef.DeclaringType.FullName} for generic method {methodRef}");
298,308✔
142

143
        if (methodRef.TypeGenericParams.Length == 0)
298,308✔
144
            return baseType;
43,716✔
145

146
        var genericParams = ResolveTypeArray(methodRef.TypeGenericParams, declaringAssembly);
254,592✔
147

148
        return new GenericInstanceTypeAnalysisContext(baseType, genericParams, declaringAssembly);
254,592✔
149
    }
150

151
    private static TypeAnalysisContext[] ResolveTypeArray(Il2CppTypeReflectionData[] array, AssemblyAnalysisContext declaringAssembly)
152
    {
153
        if (array.Length == 0)
851,208✔
154
            return [];
294,366✔
155

156
        var ret = new TypeAnalysisContext[array.Length];
556,842✔
157
        for (var i = 0; i < array.Length; i++)
2,552,904✔
158
        {
159
            ret[i] = array[i].ToContext(declaringAssembly)
719,610!
160
                     ?? throw new($"Unable to resolve generic parameter {array[i]} for generic method.");
719,610✔
161
        }
162

163
        return ret;
556,842✔
164
    }
165

166
    private static MethodAnalysisContext ResolveBaseMethod(Cpp2IlMethodRef methodRef, TypeAnalysisContext declaringType)
167
    {
168
        return declaringType.GetMethod(methodRef.BaseMethod)
298,308!
169
               ?? throw new($"Unable to resolve base method {methodRef.BaseMethod} for generic method {methodRef}");
298,308✔
170
    }
171
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc