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

SamboyCoding / Cpp2IL / 15052278841

15 May 2025 06:16PM UTC coverage: 34.038% (-0.4%) from 34.453%
15052278841

push

github

SamboyCoding
Support injecting anything
* Nested types
* Events
* Properties
* Assemblies

Support additional metadata in injected assemblies

Make setter for TypeAnalysisContext::OverrideBaseType public

TypeAnalysisContext::InterfaceContexts as list rather than array

Fix sign bug

Support generic parameters on type contexts and method contexts

Make GenericParameterTypeAnalysisContext instances unique

Revert change to Il2CppGenericParameter::Index

Use attributes to determine if injected methods are static
* Also add hide by sig attribute for injected constructors

Support overrides on injected methods

In ControlFlowGraphOutputFormat, exclude injected assemblies

Ensure injected assemblies can't delete existing assemblies

Backing field on .NET Standard for injected method overrides

Implement requested change

1774 of 6622 branches covered (26.79%)

Branch coverage included in aggregate %.

147 of 196 new or added lines in 27 files covered. (75.0%)

53 existing lines in 2 files now uncovered.

4155 of 10797 relevant lines covered (38.48%)

188267.61 hits per line

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

66.2
/Cpp2IL.Core/Extensions/AccessibilityExtensions.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Reflection;
5
using Cpp2IL.Core.Model.Contexts;
6
using LibCpp2IL.Metadata;
7

8
namespace Cpp2IL.Core.Extensions;
9

10
internal static class AccessibilityExtensions
11
{
12
    public static bool IsAccessibleTo(this TypeAnalysisContext referenceType, TypeAnalysisContext referencingType)
13
    {
14
        if (referenceType == referencingType)
9✔
15
            return true;
1✔
16

17
        var declaringTypesHierarchy = referenceType.GetTypeAndDeclaringTypes().ToArray();
8✔
18
        var inheritsFromIndex = declaringTypesHierarchy.IndexOf(t => referencingType.IsAssignableTo(t));
19✔
19
        var declaringTypeIndex = Array.IndexOf(declaringTypesHierarchy, referencingType);
8✔
20

21
        if (referenceType.DeclaringAssembly == referencingType.DeclaringAssembly /*or internals visible*/)
8✔
22
        {
23
            for (var i = 0; i < declaringTypesHierarchy.Length; i++)
16✔
24
            {
25
                if (i == declaringTypeIndex - 1)
5✔
26
                {
27
                    //All nested classes are accesible to their immediate declaring type.
28
                }
29
                else if (i == inheritsFromIndex - 1)
4!
30
                {
31
                    if (declaringTypesHierarchy[i].GetVisibility() is TypeAttributes.NestedPrivate)
×
32
                    {
33
                        return false;
×
34
                    }
35
                }
36
                else
37
                {
38
                    if (declaringTypesHierarchy[i].GetVisibility() is TypeAttributes.NestedPrivate or TypeAttributes.NestedFamily or TypeAttributes.NestedFamANDAssem)
4✔
39
                    {
40
                        return false;
1✔
41
                    }
42
                }
43
            }
44

45
            return true;
3✔
46
        }
47
        else if (referenceType.DeclaringAssembly.IsDependencyOf(referencingType.DeclaringAssembly))
4✔
48
        {
49
            for (var i = 0; i < declaringTypesHierarchy.Length; i++)
8✔
50
            {
51
                if (i == declaringTypeIndex - 1)
3✔
52
                {
53
                    //All nested classes are accesible to their immediate declaring type.
54
                }
55
                else if (i == inheritsFromIndex - 1)
3!
56
                {
57
                    if (declaringTypesHierarchy[i].GetVisibility() is TypeAttributes.NotPublic or TypeAttributes.NestedPrivate or TypeAttributes.NestedAssembly or TypeAttributes.NestedFamANDAssem)
×
58
                    {
59
                        return false;
×
60
                    }
61
                }
62
                else
63
                {
64
                    if (declaringTypesHierarchy[i].GetVisibility() is TypeAttributes.NotPublic or TypeAttributes.NestedPrivate or TypeAttributes.NestedFamily or TypeAttributes.NestedAssembly or TypeAttributes.NestedFamANDAssem or TypeAttributes.NestedFamORAssem)
3✔
65
                    {
66
                        return false;
2✔
67
                    }
68
                }
69
            }
70

71
            return true;
1✔
72
        }
73

74
        return false;
1✔
75
    }
76

77
    public static bool IsAssignableTo(this TypeAnalysisContext derivedType, TypeAnalysisContext baseType)
78
    {
79
        if (baseType.IsInterface)
11!
80
        {
81
            return derivedType.IsAssignableToInterface(baseType);
×
82
        }
83
        else
84
        {
85
            return derivedType.InheritsFrom(baseType);
11✔
86
        }
87
    }
88

89
    private static int IndexOf<T>(this IEnumerable<T> enumerable, Func<T, bool> selector)
90
    {
91
        var index = 0;
8✔
92
        foreach (var item in enumerable)
37✔
93
        {
94
            if (selector(item))
11✔
95
            {
96
                return index;
1✔
97
            }
98

99
            index++;
10✔
100
        }
101

102
        return -1;
7✔
103
    }
1✔
104

105
    private static IEnumerable<TypeAnalysisContext> GetTypeAndDeclaringTypes(this TypeAnalysisContext type)
106
    {
107
        var current = type;
8✔
108
        while (current != null)
19✔
109
        {
110
            yield return current;
11✔
111
            current = current.DeclaringType;
11✔
112
        }
113
    }
8✔
114

115
    private static TypeAttributes GetVisibility(this TypeAnalysisContext type) => type.TypeAttributes & TypeAttributes.VisibilityMask;
7✔
116

117
    private static bool InheritsFrom(this TypeAnalysisContext derivedType, TypeAnalysisContext baseType)
118
    {
119
        var current = derivedType;
11✔
120
        while (current != null)
35✔
121
        {
122
            if (current == baseType)
25✔
123
                return true;
1✔
124
            current = current.BaseType;
24✔
125
        }
126

127
        return false;
10✔
128
    }
129

130
    private static bool IsAssignableToInterface(this TypeAnalysisContext derivedType, TypeAnalysisContext baseInterface)
131
    {
132
        if (derivedType == baseInterface)
×
133
            return true;
×
134

135
        foreach (var @interface in derivedType.InterfaceContexts)
×
136
        {
137
            if (@interface.IsAssignableToInterface(baseInterface))
×
138
                return true;
×
139
        }
140

141
        return false;
×
UNCOV
142
    }
×
143

144
    private static bool IsDependencyOf(this AssemblyAnalysisContext referencedAssembly, AssemblyAnalysisContext referencingAssembly)
145
    {
146
        if (referencingAssembly.Definition is null)
4!
147
        {
148
            // Injected assemblies can access everything
NEW
149
            return true;
×
150
        }
151
        if (referencedAssembly.Definition is null)
4!
152
        {
153
            // Injected assemblies cannot be accessed by metadata assemblies
NEW
154
            return false;
×
155
        }
156
        return referencedAssembly.Definition.IsDependencyOf(referencingAssembly.Definition);
4✔
157
    }
158

159
    private static bool IsDependencyOf(this Il2CppAssemblyDefinition referencedAssembly, Il2CppAssemblyDefinition referencingAssembly)
160
    {
161
        if (Array.IndexOf(referencingAssembly.ReferencedAssemblies, referencedAssembly) >= 0)
4✔
162
            return true;
3✔
163

164
        if (Array.IndexOf(referencedAssembly.ReferencedAssemblies, referencingAssembly) >= 0)
1!
165
            return false;
1✔
166

167
        return referencingAssembly.CollectAllDependencies().Contains(referencedAssembly);
×
168
    }
169

170
    private static HashSet<Il2CppAssemblyDefinition> CollectAllDependencies(this Il2CppAssemblyDefinition referencingAssembly)
171
    {
172
        var dependencies = new HashSet<Il2CppAssemblyDefinition> { referencingAssembly };
×
173
        referencingAssembly.CollectAllDependencies(dependencies);
×
174
        return dependencies;
×
175
    }
176

177
    private static void CollectAllDependencies(this Il2CppAssemblyDefinition referencingAssembly, HashSet<Il2CppAssemblyDefinition> dependencies)
178
    {
179
        foreach (var dependency in referencingAssembly.ReferencedAssemblies)
×
180
        {
181
            //Assemblies can have circular references
182
            if (dependencies.Add(dependency))
×
183
            {
184
                dependency.CollectAllDependencies(dependencies);
×
185
            }
186
        }
187
    }
×
188
}
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