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

SamboyCoding / Cpp2IL / 10648892934

31 Aug 2024 11:02PM UTC coverage: 29.103% (-0.02%) from 29.124%
10648892934

push

github

SamboyCoding
Core: Support "v29.2"'s isUnmanagedCallersOnly the *correct* way

1227 of 5825 branches covered (21.06%)

Branch coverage included in aggregate %.

1 of 7 new or added lines in 2 files covered. (14.29%)

30 existing lines in 2 files now uncovered.

3314 of 9778 relevant lines covered (33.89%)

104609.41 hits per line

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

0.0
/Cpp2IL.Core/Utils/AsmResolver/AsmResolverAssemblyPopulator.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using AsmResolver;
5
using AsmResolver.DotNet;
6
using AsmResolver.DotNet.Signatures;
7
using AsmResolver.PE.DotNet.Metadata.Tables;
8
using Cpp2IL.Core.Model.Contexts;
9
using Cpp2IL.Core.Model.CustomAttributes;
10
using LibCpp2IL.BinaryStructures;
11
using LibCpp2IL.Metadata;
12
using LibCpp2IL.Reflection;
13

14
namespace Cpp2IL.Core.Utils.AsmResolver;
15

16
public static class AsmResolverAssemblyPopulator
17
{
18
    public static bool IsTypeContextModule(TypeAnalysisContext typeCtx)
19
    {
20
        return typeCtx.Name.StartsWith("<Module>") || typeCtx.FullName.StartsWith("<Module>");
×
21
    }
22

23
    public static void ConfigureHierarchy(AssemblyAnalysisContext asmCtx)
24
    {
25
        foreach (var typeCtx in asmCtx.Types)
×
26
        {
27
            if (IsTypeContextModule(typeCtx))
×
28
                continue;
29

30
            var il2CppTypeDef = typeCtx.Definition;
×
31
            var typeDefinition = typeCtx.GetExtraData<TypeDefinition>("AsmResolverType") ?? throw new($"AsmResolver type not found in type analysis context for {typeCtx.FullName}");
×
32

33
            var importer = typeDefinition.Module!.Assembly!.GetImporter();
×
34

35
            //Type generic params.
36
            if (il2CppTypeDef != null)
×
37
                PopulateGenericParamsForType(il2CppTypeDef, typeDefinition);
×
38

39
            //Set base type
40
            if (typeCtx.OverrideBaseType is { } overrideBaseType)
×
41
            {
42
                var baseTypeDef = overrideBaseType.GetExtraData<TypeDefinition>("AsmResolverType") ?? throw new($"{typeCtx} declares override base type {overrideBaseType} which has not had an AsmResolver type generated for it.");
×
43
                typeDefinition.BaseType = importer.ImportType(baseTypeDef);
×
44
            }
45
            else if (il2CppTypeDef?.RawBaseType is { } parent)
×
46
                typeDefinition.BaseType = importer.ImportType(AsmResolverUtils.ImportReferenceFromIl2CppType(typeDefinition.Module, parent));
×
47

48
            //Set interfaces
49
            if (il2CppTypeDef != null)
×
50
                foreach (var interfaceType in il2CppTypeDef.RawInterfaces)
×
51
                    typeDefinition.Interfaces.Add(new(importer.ImportType(AsmResolverUtils.ImportReferenceFromIl2CppType(typeDefinition.Module, interfaceType))));
×
52
        }
53
    }
×
54

55
    private static void PopulateGenericParamsForType(Il2CppTypeDefinition cppTypeDefinition, TypeDefinition ilTypeDefinition)
56
    {
57
        if (cppTypeDefinition.GenericContainer == null)
×
58
            return;
×
59

60
        var importer = ilTypeDefinition.Module!.Assembly!.GetImporter();
×
61

62
        foreach (var param in cppTypeDefinition.GenericContainer.GenericParameters)
×
63
        {
64
            // if(parentParams.Any(p => p.Name == param.Name))
65
            //     continue;
66

67
            if (!AsmResolverUtils.GenericParamsByIndexNew.TryGetValue(param.Index, out var p))
×
68
            {
69
                p = new GenericParameter(param.Name, (GenericParameterAttributes)param.flags);
×
70
                AsmResolverUtils.GenericParamsByIndexNew[param.Index] = p;
×
71

72
                ilTypeDefinition.GenericParameters.Add(p);
×
73

74
                param.ConstraintTypes!
×
75
                    .Select(c => new GenericParameterConstraint(importer.ImportTypeIfNeeded(AsmResolverUtils.ImportReferenceFromIl2CppType(ilTypeDefinition.Module, c))))
×
76
                    .ToList()
×
77
                    .ForEach(p.Constraints.Add);
×
78
            }
79
            else if (!ilTypeDefinition.GenericParameters.Contains(p))
×
80
                ilTypeDefinition.GenericParameters.Add(p);
×
81
        }
82
    }
×
83

84
    private static TypeSignature GetTypeSigFromAttributeArg(AssemblyDefinition parentAssembly, BaseCustomAttributeParameter parameter) =>
85
        parameter switch
×
86
        {
×
87
            CustomAttributePrimitiveParameter primitiveParameter => AsmResolverUtils.GetPrimitiveTypeDef(primitiveParameter.PrimitiveType).ToTypeSignature(),
×
88
            CustomAttributeEnumParameter enumParameter => AsmResolverUtils.GetTypeSignatureFromIl2CppType(parentAssembly.ManifestModule!, enumParameter.EnumType ?? throw new("Enum type not found for " + enumParameter)),
×
89
            BaseCustomAttributeTypeParameter => TypeDefinitionsAsmResolver.Type.ToTypeSignature(),
×
90
            CustomAttributeArrayParameter arrayParameter => AsmResolverUtils.GetPrimitiveTypeDef(arrayParameter.ArrType).ToTypeSignature().MakeSzArrayType(),
×
91
            _ => throw new ArgumentException("Unknown custom attribute parameter type: " + parameter.GetType().FullName)
×
92
        };
×
93

94
    private static CustomAttributeArgument BuildArrayArgument(AssemblyDefinition parentAssembly, CustomAttributeArrayParameter arrayParameter)
95
    {
96
#if !DEBUG
97
        try
98
#endif
99
        {
100
            if (arrayParameter.IsNullArray)
×
101
                return BuildEmptyArrayArgument(parentAssembly, arrayParameter);
×
102

103
            var typeSig = GetTypeSigFromAttributeArg(parentAssembly, arrayParameter);
×
104

105
            var isObjectArray = arrayParameter.ArrType == Il2CppTypeEnum.IL2CPP_TYPE_OBJECT;
×
106

107
            var arrayElements = arrayParameter.ArrayElements.Select(e =>
×
108
            {
×
109
                var rawValue = e switch
×
110
                {
×
111
                    CustomAttributePrimitiveParameter primitiveParameter => primitiveParameter.PrimitiveValue,
×
112
                    CustomAttributeEnumParameter enumParameter => enumParameter.UnderlyingPrimitiveParameter.PrimitiveValue,
×
113
                    BaseCustomAttributeTypeParameter type => (object?)type.TypeContext?.ToTypeSignature(parentAssembly.ManifestModule!),
×
114
                    CustomAttributeNullParameter => null,
×
115
                    _ => throw new("Not supported array element type: " + e.GetType().FullName)
×
116
                };
×
117

×
118
                if (isObjectArray)
×
119
                    //Object params have to be boxed
×
120
                    return new BoxedArgument(GetTypeSigFromAttributeArg(parentAssembly, e), rawValue);
×
121

×
122
                return rawValue;
×
123
            }).ToArray();
×
124

125
            return new(typeSig, arrayElements);
×
126
        }
127
#if !DEBUG
128
        catch (Exception e)
×
129
        {
130
            throw new("Failed to build array argument for " + arrayParameter, e);
×
131
        }
132
#endif
133
    }
×
134

135
    private static CustomAttributeArgument BuildEmptyArrayArgument(AssemblyDefinition parentAssembly, CustomAttributeArrayParameter arrayParameter)
136
    {
137
        //Need to resolve the type of the array because it's not in the blob and AsmResolver needs it.
138

139
        var typeSig = arrayParameter.Kind switch
×
140
        {
×
141
            CustomAttributeParameterKind.ConstructorParam => arrayParameter.Owner.Constructor.Parameters[arrayParameter.Index].ToTypeSignature(parentAssembly.ManifestModule!),
×
142
            CustomAttributeParameterKind.Property => arrayParameter.Owner.Properties[arrayParameter.Index].Property.ToTypeSignature(parentAssembly.ManifestModule!),
×
143
            CustomAttributeParameterKind.Field => arrayParameter.Owner.Fields[arrayParameter.Index].Field.ToTypeSignature(parentAssembly.ManifestModule!),
×
144
            CustomAttributeParameterKind.ArrayElement => throw new("Array element cannot be an array (or at least, not implemented!)"),
×
145
            _ => throw new("Unknown array parameter kind: " + arrayParameter.Kind)
×
146
        };
×
147

148
        return new(typeSig) { IsNullArray = true };
×
149
    }
150

151
    private static CustomAttributeArgument FromAnalyzedAttributeArgument(AssemblyDefinition parentAssembly, BaseCustomAttributeParameter parameter)
152
    {
153
#if !DEBUG
154
        try
155
#endif
156
        {
157
            return parameter switch
×
158
            {
×
159
                CustomAttributePrimitiveParameter primitiveParameter => new(GetTypeSigFromAttributeArg(parentAssembly, primitiveParameter), primitiveParameter.PrimitiveValue),
×
160
                CustomAttributeEnumParameter enumParameter => new(GetTypeSigFromAttributeArg(parentAssembly, enumParameter), enumParameter.UnderlyingPrimitiveParameter.PrimitiveValue),
×
161
                BaseCustomAttributeTypeParameter typeParameter => new(TypeDefinitionsAsmResolver.Type.ToTypeSignature(), typeParameter.TypeContext?.ToTypeSignature(parentAssembly.ManifestModule!)),
×
162
                CustomAttributeArrayParameter arrayParameter => BuildArrayArgument(parentAssembly, arrayParameter),
×
163
                _ => throw new ArgumentException("Unknown custom attribute parameter type: " + parameter.GetType().FullName)
×
164
            };
×
165
        }
166
#if !DEBUG
167
        catch (Exception e)
×
168
        {
169
            throw new("Failed to build custom attribute argument for " + parameter, e);
×
170
        }
171
#endif
172
    }
×
173

174
    private static CustomAttributeNamedArgument FromAnalyzedAttributeField(AssemblyDefinition parentAssembly, CustomAttributeField field)
175
        => new(CustomAttributeArgumentMemberType.Field, field.Field.FieldName, GetTypeSigFromAttributeArg(parentAssembly, field.Value), FromAnalyzedAttributeArgument(parentAssembly, field.Value));
×
176

177
    private static CustomAttributeNamedArgument FromAnalyzedAttributeProperty(AssemblyDefinition parentAssembly, CustomAttributeProperty property)
178
        => new(CustomAttributeArgumentMemberType.Property, property.Property.Name, GetTypeSigFromAttributeArg(parentAssembly, property.Value), FromAnalyzedAttributeArgument(parentAssembly, property.Value));
×
179

180
    private static CustomAttribute? ConvertCustomAttribute(AnalyzedCustomAttribute analyzedCustomAttribute, AssemblyDefinition assemblyDefinition)
181
    {
182
        var ctor = analyzedCustomAttribute.Constructor.GetExtraData<MethodDefinition>("AsmResolverMethod") ?? throw new($"Found a custom attribute with no AsmResolver constructor: {analyzedCustomAttribute}");
×
183

184
        CustomAttributeSignature signature;
185
        var numNamedArgs = analyzedCustomAttribute.Fields.Count + analyzedCustomAttribute.Properties.Count;
×
186

187
#if !DEBUG
188
        try
189
#endif
190
        {
191
            if (!analyzedCustomAttribute.HasAnyParameters && numNamedArgs == 0)
×
192
                signature = new();
×
193
            else if (analyzedCustomAttribute.IsSuitableForEmission)
×
194
            {
195
                if (numNamedArgs == 0)
×
196
                {
197
                    //Only fixed arguments.
198
                    signature = new(analyzedCustomAttribute.ConstructorParameters.Select(p => FromAnalyzedAttributeArgument(assemblyDefinition, p)));
×
199
                }
200
                else
201
                {
202
                    //Has named arguments.
203
                    signature = new(
×
204
                        analyzedCustomAttribute.ConstructorParameters.Select(p => FromAnalyzedAttributeArgument(assemblyDefinition, p)),
×
205
                        analyzedCustomAttribute.Fields
×
206
                            .Select(f => FromAnalyzedAttributeField(assemblyDefinition, f))
×
207
                            .Concat(analyzedCustomAttribute.Properties.Select(p => FromAnalyzedAttributeProperty(assemblyDefinition, p)))
×
208
                    );
×
209
                }
210
            }
211
            else
212
            {
213
                return null;
×
214
            }
215
        }
×
216
#if !DEBUG
217
        catch (Exception e)
×
218
        {
219
            throw new("Failed to build custom attribute signature for " + analyzedCustomAttribute, e);
×
220
        }
221
#endif
222

223
        var importedCtor = assemblyDefinition.GetImporter().ImportMethod(ctor);
×
224

225
        var newAttribute = new CustomAttribute((ICustomAttributeType)importedCtor, signature);
×
226
        return newAttribute;
×
227
    }
×
228

229
    private static void CopyCustomAttributes(HasCustomAttributes source, IList<CustomAttribute> destination)
230
    {
231
        if (source.CustomAttributes == null)
×
232
            return;
×
233

234
        var assemblyDefinition = source.CustomAttributeAssembly.GetExtraData<AssemblyDefinition>("AsmResolverAssembly") ?? throw new("AsmResolver assembly not found in assembly analysis context for " + source.CustomAttributeAssembly);
×
235

236
#if !DEBUG
237
        try
238
#endif
239
        {
240
            foreach (var analyzedCustomAttribute in source.CustomAttributes)
×
241
            {
242
                var asmResolverCustomAttribute = ConvertCustomAttribute(analyzedCustomAttribute, assemblyDefinition);
×
243
                if (asmResolverCustomAttribute != null)
×
244
                    destination.Add(asmResolverCustomAttribute);
×
245
            }
246
        }
×
247
#if !DEBUG
248
        catch (Exception e)
×
249
        {
250
            throw new("Failed to copy custom attributes for " + source, e);
×
251
        }
252
#endif
253
    }
×
254

255
    public static void PopulateCustomAttributes(AssemblyAnalysisContext asmContext)
256
    {
257
#if !DEBUG
258
        try
259
#endif
260
        {
261
            CopyCustomAttributes(asmContext, asmContext.GetExtraData<AssemblyDefinition>("AsmResolverAssembly")!.CustomAttributes);
×
262

263
            foreach (var type in asmContext.Types)
×
264
            {
265
                if (IsTypeContextModule(type))
×
266
                    continue;
267

268
                CopyCustomAttributes(type, type.GetExtraData<TypeDefinition>("AsmResolverType")!.CustomAttributes);
×
269

270
                foreach (var method in type.Methods)
×
271
                {
272
                    var methodDef = method.GetExtraData<MethodDefinition>("AsmResolverMethod")!;
×
273
                    CopyCustomAttributes(method, methodDef.CustomAttributes);
×
274

275
                    var parameterDefinitions = methodDef.ParameterDefinitions;
×
276
                    foreach (var parameterAnalysisContext in method.Parameters)
×
277
                    {
278
                        CopyCustomAttributes(parameterAnalysisContext, parameterDefinitions[parameterAnalysisContext.ParamIndex].CustomAttributes);
×
279
                    }
280
                }
281

282
                foreach (var field in type.Fields)
×
283
                    CopyCustomAttributes(field, field.GetExtraData<FieldDefinition>("AsmResolverField")!.CustomAttributes);
×
284

285
                foreach (var property in type.Properties)
×
286
                    CopyCustomAttributes(property, property.GetExtraData<PropertyDefinition>("AsmResolverProperty")!.CustomAttributes);
×
287

288
                foreach (var eventDefinition in type.Events)
×
289
                    CopyCustomAttributes(eventDefinition, eventDefinition.GetExtraData<EventDefinition>("AsmResolverEvent")!.CustomAttributes);
×
290
            }
291
        }
×
292
#if !DEBUG
293
        catch (Exception e)
×
294
        {
295
            throw new($"Failed to populate custom attributes in {asmContext}", e);
×
296
        }
297
#endif
298
    }
×
299

300
    public static void CopyDataFromIl2CppToManaged(AssemblyAnalysisContext asmContext)
301
    {
302
        var managedAssembly = asmContext.GetExtraData<AssemblyDefinition>("AsmResolverAssembly") ?? throw new("AsmResolver assembly not found in assembly analysis context for " + asmContext);
×
303

304
        foreach (var typeContext in asmContext.Types)
×
305
        {
306
            if (IsTypeContextModule(typeContext))
×
307
                continue;
308

309
            var managedType = typeContext.GetExtraData<TypeDefinition>("AsmResolverType") ?? throw new($"AsmResolver type not found in type analysis context for {typeContext.Definition?.FullName}");
×
310
            // CopyCustomAttributes(typeContext, managedType.CustomAttributes);
311

312
#if !DEBUG
313
            try
314
#endif
315
            {
316
                CopyIl2CppDataToManagedType(typeContext, managedType);
×
317
            }
×
318
#if !DEBUG
319
            catch (Exception e)
×
320
            {
321
                throw new Exception($"Failed to process type {managedType.FullName} (module {managedType.Module?.Name}, declaring type {managedType.DeclaringType?.FullName}) in {asmContext.Definition.AssemblyName.Name}", e);
×
322
            }
323
#endif
324
        }
325
    }
×
326

327
    private static void CopyIl2CppDataToManagedType(TypeAnalysisContext typeContext, TypeDefinition ilTypeDefinition)
328
    {
329
        var importer = ilTypeDefinition.Module!.Assembly!.GetImporter();
×
330

331
        CopyFieldsInType(importer, typeContext, ilTypeDefinition);
×
332

333
        CopyMethodsInType(importer, typeContext, ilTypeDefinition);
×
334

335
        CopyPropertiesInType(importer, typeContext, ilTypeDefinition);
×
336

337
        CopyEventsInType(importer, typeContext, ilTypeDefinition);
×
338
    }
×
339

340
    private static void CopyFieldsInType(ReferenceImporter importer, TypeAnalysisContext typeContext, TypeDefinition ilTypeDefinition)
341
    {
342
        foreach (var fieldContext in typeContext.Fields)
×
343
        {
344
            var fieldInfo = fieldContext.BackingData;
×
345

346
            var fieldTypeSig = importer.ImportTypeSignature(fieldContext.ToTypeSignature(importer.TargetModule));
×
347

348
            var managedField = new FieldDefinition(fieldContext.FieldName, (FieldAttributes)fieldContext.Attributes, fieldTypeSig);
×
349

350
            if (fieldInfo != null)
×
351
            {
352
                //Field default values
353
                if (managedField.HasDefault && fieldInfo.Field.DefaultValue?.Value is { } constVal)
×
354
                    managedField.Constant = AsmResolverConstants.GetOrCreateConstant(constVal);
×
355

356
                //Field Initial Values (used for allocation of Array Literals)
357
                if (managedField.HasFieldRva)
×
358
                    managedField.FieldRva = new DataSegment(fieldInfo.Field.StaticArrayInitialValue);
×
359

360
                if (ilTypeDefinition.IsExplicitLayout)
×
361
                    //Copy field offset
362
                    managedField.FieldOffset = fieldInfo.FieldOffset;
×
363
            }
364

365
            fieldContext.PutExtraData("AsmResolverField", managedField);
×
366

367
            ilTypeDefinition.Fields.Add(managedField);
×
368
        }
369
    }
×
370

371
    private static void CopyMethodsInType(ReferenceImporter importer, TypeAnalysisContext typeContext, TypeDefinition ilTypeDefinition)
372
    {
373
        foreach (var methodCtx in typeContext.Methods)
×
374
        {
375
            var methodDef = methodCtx.Definition;
×
376

377
            var rawReturnType = methodDef != null ? methodDef.RawReturnType! : LibCpp2IlReflection.GetTypeFromDefinition(methodCtx.InjectedReturnType!.Definition ?? throw new("Injected methods with injected return types not supported at the moment."))!;
×
378
            var returnType = importer.ImportTypeSignature(AsmResolverUtils.GetTypeSignatureFromIl2CppType(importer.TargetModule, rawReturnType));
×
379

380
            var paramData = methodCtx.Parameters;
×
381
            var parameterTypes = new TypeSignature[paramData.Count];
×
382
            var parameterDefinitions = new ParameterDefinition[paramData.Count];
×
383
            foreach (var parameterAnalysisContext in methodCtx.Parameters)
×
384
            {
385
                var i = parameterAnalysisContext.ParamIndex;
×
386
                parameterTypes[i] = importer.ImportTypeSignature(parameterAnalysisContext.ParameterTypeContext.ToTypeSignature(importer.TargetModule));
×
387

388
                var sequence = (ushort)(i + 1); //Add one because sequence 0 is the return type
×
389
                parameterDefinitions[i] = new(sequence, parameterAnalysisContext.Name, (ParameterAttributes)parameterAnalysisContext.ParameterAttributes);
×
390

391
                if (parameterAnalysisContext.DefaultValue is not { } defaultValueData)
×
392
                    continue;
393

394
                if (defaultValueData?.ContainedDefaultValue is { } constVal)
×
395
                    parameterDefinitions[i].Constant = AsmResolverConstants.GetOrCreateConstant(constVal);
×
396
                else if (defaultValueData is { dataIndex: -1 })
×
397
                {
398
                    //Literal null
399
                    parameterDefinitions[i].Constant = AsmResolverConstants.Null;
×
400
                }
401
            }
402

403

404
            var signature = methodCtx.IsStatic ? MethodSignature.CreateStatic(returnType, parameterTypes) : MethodSignature.CreateInstance(returnType, parameterTypes);
×
405

406
            var managedMethod = new MethodDefinition(methodCtx.MethodName, (MethodAttributes)methodCtx.Attributes, signature);
×
407

408
            if (methodCtx.Definition != null)
×
409
            {
NEW
410
                managedMethod.ImplAttributes = (MethodImplAttributes)methodCtx.Definition.MethodImplAttributes;
×
NEW
411
                if (methodCtx.Definition.IsUnmanagedCallersOnly && typeContext.AppContext.SystemTypes.UnmanagedCallersOnlyAttributeType != null)
×
412
                {
NEW
413
                    var unmanagedCallersOnlyType = typeContext.AppContext.SystemTypes.UnmanagedCallersOnlyAttributeType.GetExtraData<TypeDefinition>("AsmResolverType");
×
NEW
414
                    if(unmanagedCallersOnlyType != null)
×
NEW
415
                        managedMethod.CustomAttributes.Add(new CustomAttribute((ICustomAttributeType)importer.ImportMethod(unmanagedCallersOnlyType.GetConstructor()!), new()));
×
416
                }
417

418
            }
419

420
            //Add parameter definitions if we have them so we get names, defaults, out params, etc
421
            foreach (var parameterDefinition in parameterDefinitions)
×
422
            {
423
                managedMethod.ParameterDefinitions.Add(parameterDefinition);
×
424
            }
425

426
            //Handle generic parameters.
427
            methodDef?.GenericContainer?.GenericParameters.ToList()
×
428
                .ForEach(p =>
×
429
                {
×
430
                    if (AsmResolverUtils.GenericParamsByIndexNew.TryGetValue(p.Index, out var gp))
×
431
                    {
×
432
                        if (!managedMethod.GenericParameters.Contains(gp))
×
433
                            managedMethod.GenericParameters.Add(gp);
×
434

×
435
                        return;
×
436
                    }
×
437

×
438
                    gp = new(p.Name, (GenericParameterAttributes)p.flags);
×
439

×
440
                    if (!managedMethod.GenericParameters.Contains(gp))
×
441
                        managedMethod.GenericParameters.Add(gp);
×
442

×
443
                    p.ConstraintTypes!
×
444
                        .Select(c => new GenericParameterConstraint(importer.ImportTypeIfNeeded(AsmResolverUtils.ImportReferenceFromIl2CppType(ilTypeDefinition.Module!, c))))
×
445
                        .ToList()
×
446
                        .ForEach(gp.Constraints.Add);
×
447
                });
×
448

449

450
            methodCtx.PutExtraData("AsmResolverMethod", managedMethod);
×
451
            ilTypeDefinition.Methods.Add(managedMethod);
×
452
        }
453
    }
×
454

455
    private static void CopyPropertiesInType(ReferenceImporter importer, TypeAnalysisContext typeContext, TypeDefinition ilTypeDefinition)
456
    {
457
        foreach (var propertyCtx in typeContext.Properties)
×
458
        {
459
            var propertyDef = propertyCtx.Definition;
×
460

461
            var propertyTypeSig = importer.ImportTypeSignature(AsmResolverUtils.GetTypeSignatureFromIl2CppType(importer.TargetModule, propertyDef.RawPropertyType!));
×
462
            var propertySignature = propertyDef.IsStatic
×
463
                ? PropertySignature.CreateStatic(propertyTypeSig)
×
464
                : PropertySignature.CreateInstance(propertyTypeSig);
×
465

466
            var managedProperty = new PropertyDefinition(propertyCtx.Name, (PropertyAttributes)propertyDef.attrs, propertySignature);
×
467

468
            var managedGetter = propertyCtx.Getter?.GetExtraData<MethodDefinition>("AsmResolverMethod");
×
469
            var managedSetter = propertyCtx.Setter?.GetExtraData<MethodDefinition>("AsmResolverMethod");
×
470

471
            if (managedGetter != null)
×
472
                managedProperty.Semantics.Add(new(managedGetter, MethodSemanticsAttributes.Getter));
×
473

474
            if (managedSetter != null)
×
475
                managedProperty.Semantics.Add(new(managedSetter, MethodSemanticsAttributes.Setter));
×
476

477
            //Indexer parameters
478
            if (managedGetter != null && managedGetter.Parameters.Count > 0)
×
479
            {
480
                foreach (var parameter in managedGetter.Parameters)
×
481
                {
482
                    propertySignature.ParameterTypes.Add(parameter.ParameterType);
×
483
                }
484
            }
485
            else if (managedSetter != null && managedSetter.Parameters.Count > 1)
×
486
            {
487
                //value parameter is always last
488
                for (var i = 0; i < managedSetter.Parameters.Count - 1; i++)
×
489
                {
490
                    var parameter = managedSetter.Parameters[i];
×
491
                    propertySignature.ParameterTypes.Add(parameter.ParameterType);
×
492
                }
493
            }
494

495
            propertyCtx.PutExtraData("AsmResolverProperty", managedProperty);
×
496

497
            ilTypeDefinition.Properties.Add(managedProperty);
×
498
        }
499
    }
×
500

501
    private static void CopyEventsInType(ReferenceImporter importer, TypeAnalysisContext cppTypeDefinition, TypeDefinition ilTypeDefinition)
502
    {
503
        foreach (var eventCtx in cppTypeDefinition.Events)
×
504
        {
505
            var eventDef = eventCtx.Definition;
×
506

507
            var eventType = importer.ImportTypeIfNeeded(AsmResolverUtils.ImportReferenceFromIl2CppType(ilTypeDefinition.Module!, eventDef.RawType!));
×
508

509
            var managedEvent = new EventDefinition(eventCtx.Name, (EventAttributes)eventDef.EventAttributes, eventType);
×
510

511
            var managedAdder = eventCtx.Adder?.GetExtraData<MethodDefinition>("AsmResolverMethod");
×
512
            var managedRemover = eventCtx.Remover?.GetExtraData<MethodDefinition>("AsmResolverMethod");
×
513
            var managedInvoker = eventCtx.Invoker?.GetExtraData<MethodDefinition>("AsmResolverMethod");
×
514

515
            if (managedAdder != null)
×
516
                managedEvent.Semantics.Add(new(managedAdder, MethodSemanticsAttributes.AddOn));
×
517

518
            if (managedRemover != null)
×
519
                managedEvent.Semantics.Add(new(managedRemover, MethodSemanticsAttributes.RemoveOn));
×
520

521
            if (managedInvoker != null)
×
522
                managedEvent.Semantics.Add(new(managedInvoker, MethodSemanticsAttributes.Fire));
×
523

524
            eventCtx.PutExtraData("AsmResolverEvent", managedEvent);
×
525

526
            ilTypeDefinition.Events.Add(managedEvent);
×
527
        }
528
    }
×
529
}
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

© 2026 Coveralls, Inc