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

SamboyCoding / Cpp2IL / 28718430725

04 Jul 2026 08:17PM UTC coverage: 38.757% (+0.02%) from 38.737%
28718430725

push

github

SamboyCoding
ci: Update all steps

2883 of 8474 branches covered (34.02%)

Branch coverage included in aggregate %.

5409 of 12921 relevant lines covered (41.86%)

206038.82 hits per line

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

62.16
/Cpp2IL.Core/Model/Contexts/GenericInstanceTypeAnalysisContext.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Reflection;
5
using System.Text;
6
using Cpp2IL.Core.Utils;
7
using LibCpp2IL.BinaryStructures;
8

9
namespace Cpp2IL.Core.Model.Contexts;
10

11
public class GenericInstanceTypeAnalysisContext : ReferencedTypeAnalysisContext
12
{
13
    public TypeAnalysisContext GenericType { get; }
976,951✔
14

15
    public List<TypeAnalysisContext> GenericArguments { get; } = [];
2,060,360✔
16

17
    public sealed override TypeAttributes DefaultAttributes => GenericType.DefaultAttributes;
×
18

19
    public sealed override TypeAttributes? OverrideAttributes { get => GenericType.OverrideAttributes; set => GenericType.OverrideAttributes = value; }
×
20

21
    public sealed override string DefaultName => $"{GenericType.DefaultName}<{string.Join(", ", GenericArguments.Select(a => a.DefaultFullName))}>";
×
22

23
    public sealed override string? OverrideName
24
    {
25
        get => $"{GenericType.Name}<{string.Join(", ", GenericArguments.Select(a => a.FullName))}>";
1,623✔
26
        set => throw new NotSupportedException();
×
27
    }
28

29
    public sealed override string DefaultNamespace => GenericType.DefaultNamespace;
612✔
30

31
    public sealed override string? OverrideNamespace
32
    {
33
        get => GenericType.OverrideNamespace;
612✔
34
        set => GenericType.OverrideNamespace = value;
×
35
    }
36

37
    public sealed override TypeAnalysisContext? DefaultBaseType { get; }
×
38

39
    public sealed override Il2CppTypeEnum Type => Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST;
×
40

41
    public sealed override bool IsGenericInstance => true;
×
42

43
    public sealed override bool IsValueType => GenericType.IsValueType; //We don't set a definition so the default implementation cannot determine if we're a value type or not. 
8,920✔
44

45
    // instances being constructed on the current thread, keyed by their cache identity (see GetOrCreate for why)
46
    [ThreadStatic] private static Dictionary<(AssemblyAnalysisContext, Il2CppType), GenericInstanceTypeAnalysisContext>? _underConstruction;
47

48
    private GenericInstanceTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisContext referencedFrom) : base(referencedFrom)
18,133✔
49
    {
50
        var underConstruction = _underConstruction ??= new();
18,133✔
51
        underConstruction[(referencedFrom, rawType)] = this;
18,133✔
52
        try
53
        {
54
            //Generic type has to be a type definition
55
            var gClass = rawType.GetGenericClass();
18,133✔
56
            GenericType = AppContext.ResolveContextForType(gClass.TypeDefinition) ?? throw new($"Could not resolve type {gClass.TypeDefinition.FullName} for generic instance base type");
18,133!
57

58
            GenericArguments.AddRange(gClass.Context.ClassInst!.Types.Select(referencedFrom.ResolveIl2CppType)!);
18,133✔
59

60
            SetDeclaringType();
18,133✔
61
        }
18,133✔
62
        finally
63
        {
64
            underConstruction.Remove((referencedFrom, rawType));
18,133✔
65
        }
18,133✔
66
    }
18,133✔
67

68
    public GenericInstanceTypeAnalysisContext(TypeAnalysisContext genericType, IEnumerable<TypeAnalysisContext> genericArguments, AssemblyAnalysisContext referencedFrom) : base(referencedFrom)
735,691✔
69
    {
70
        GenericType = genericType;
735,691✔
71
        GenericArguments.AddRange(genericArguments);
735,691✔
72
        DefaultBaseType = genericType.BaseType;
735,691✔
73

74
        SetDeclaringType();
735,691✔
75
    }
735,691✔
76

77
    /// <summary>
78
    /// Get or create a <see cref="GenericInstanceTypeAnalysisContext"/> from an <see cref="Il2CppType"/>.
79
    /// </summary>
80
    /// <param name="rawType">The underlying <see cref="Il2CppType"/>.</param>
81
    /// <param name="referencedFrom">The assembly that is referencing this generic instance.</param>
82
    /// <returns>The context for the <paramref name="rawType"/>.</returns>
83
    public static GenericInstanceTypeAnalysisContext GetOrCreate(Il2CppType rawType, AssemblyAnalysisContext referencedFrom)
84
    {
85
        if (rawType.Type != Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST)
187,181!
86
            throw new ArgumentException($"Cannot create {nameof(GenericInstanceTypeAnalysisContext)} from type {rawType.Type}. Expected {Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST}.");
×
87

88
        // A self-referencing generic re-enters here while we're still building it (#469). In this case, the constructing thread gets 
89
        // its own in-progress instance from a thread-local map instead (otherwise it recurses into Lazy.Value, which throws).
90
        if (_underConstruction != null && _underConstruction.TryGetValue((referencedFrom, rawType), out var partial))
187,181!
91
            return partial;
×
92

93
        return referencedFrom.GenericInstanceTypesByIl2CppType
187,181✔
94
            .GetOrAdd(rawType, key => new Lazy<GenericInstanceTypeAnalysisContext>(() => new GenericInstanceTypeAnalysisContext(key, referencedFrom)))
36,266✔
95
            .Value;
187,181✔
96
    }
97

98
    public override string GetCSharpSourceString()
99
    {
100
        var sb = new StringBuilder();
×
101

102
        sb.Append(GenericType.GetCSharpSourceString());
×
103
        sb.Append('<');
×
104
        var first = true;
×
105
        foreach (var genericArgument in GenericArguments)
×
106
        {
107
            if (!first)
×
108
                sb.Append(", ");
×
109
            else
110
                first = false;
×
111

112
            sb.Append(genericArgument.GetCSharpSourceString());
×
113
        }
114

115
        sb.Append('>');
×
116

117
        return sb.ToString();
×
118
    }
119

120
    private void SetDeclaringType()
121
    {
122
        var declaringType = GenericType.DeclaringType;
753,824✔
123
        if (declaringType is null)
753,824✔
124
            return;
566,549✔
125

126
        DeclaringType = declaringType.GenericParameters.Count == 0
187,275✔
127
            ? declaringType
187,275✔
128
            : declaringType.MakeGenericInstanceType(GenericArguments.Take(declaringType.GenericParameters.Count));
187,275✔
129
    }
187,275✔
130
}
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