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

SamboyCoding / Cpp2IL / 15036337752

15 May 2025 04:03AM UTC coverage: 34.393% (-0.4%) from 34.826%
15036337752

Pull #451

github

web-flow
Merge a4fcb53c9 into e93c0fecc
Pull Request #451: Support injecting anything

1786 of 6584 branches covered (27.13%)

Branch coverage included in aggregate %.

139 of 186 new or added lines in 26 files covered. (74.73%)

53 existing lines in 2 files now uncovered.

4167 of 10725 relevant lines covered (38.85%)

189585.86 hits per line

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

0.89
/Cpp2IL.Core/OutputFormats/IsilDumpOutputFormat.cs
1
using System;
2
using System.Collections.Generic;
3
using System.IO;
4
using System.Linq;
5
using System.Text;
6
using Cpp2IL.Core.Api;
7
using Cpp2IL.Core.Extensions;
8
using Cpp2IL.Core.Logging;
9
using Cpp2IL.Core.Model.Contexts;
10
using Cpp2IL.Core.Utils;
11

12
namespace Cpp2IL.Core.OutputFormats;
13

14
public class IsilDumpOutputFormat : Cpp2IlOutputFormat
15
{
16
    public override string OutputFormatId => "isil";
1✔
17
    public override string OutputFormatName => "ISIL Dump";
×
18

19
    public override void DoOutput(ApplicationAnalysisContext context, string outputRoot)
20
    {
21
        outputRoot = Path.Combine(outputRoot, "IsilDump");
×
22

23
        var numAssemblies = context.Assemblies.Count;
×
24
        var i = 1;
×
25
        foreach (var assembly in context.Assemblies)
×
26
        {
NEW
27
            Logger.InfoNewline($"Processing assembly {i++} of {numAssemblies}: {assembly.Name}", "IsilOutputFormat");
×
28

29
            var assemblyNameClean = assembly.CleanAssemblyName;
×
30

31
            MiscUtils.ExecuteParallel(assembly.Types, type =>
×
32
            {
×
33
                if (type is InjectedTypeAnalysisContext)
×
34
                    return;
×
35

×
36
                if (type.Methods.Count == 0)
×
37
                    return;
×
38

×
39
                var typeDump = new StringBuilder();
×
40

×
41
                typeDump.Append("Type: ").AppendLine(type.Definition!.FullName).AppendLine();
×
42

×
43
                foreach (var method in type.Methods)
×
44
                {
×
45
                    if (method is InjectedMethodAnalysisContext)
×
46
                        continue;
×
47

×
48
                    typeDump.Append("Method: ").AppendLine(method.Definition!.HumanReadableSignature).AppendLine();
×
49

×
50
                    try
×
51
                    {
×
52
                        typeDump.AppendLine("Disassembly:");
×
53
                        typeDump.Append('\t').AppendLine(context.InstructionSet.PrintAssembly(method).Replace("\n", "\n\t"));
×
54

×
55
                        typeDump.AppendLine().AppendLine("ISIL:");
×
56

×
57
                        method.Analyze();
×
58

×
59
                        if (method.ConvertedIsil == null || method.ConvertedIsil.Count == 0)
×
60
                        {
×
61
                            typeDump.AppendLine("No ISIL was generated");
×
62
                            continue;
×
63
                        }
×
64

×
65
                        foreach (var isilInsn in method.ConvertedIsil)
×
66
                        {
×
67
                            typeDump.Append('\t').Append(isilInsn).AppendLine();
×
68
                        }
×
69

×
70
                        method.ReleaseAnalysisData();
×
71

×
72
                        typeDump.AppendLine();
×
73
                    }
×
74
                    catch (Exception e)
×
75
                    {
×
76
                        typeDump.Append("Method threw an exception while analyzing - ").AppendLine(e.ToString()).AppendLine();
×
77
                    }
×
78
                }
×
79

×
80
                WriteTypeDump(outputRoot, type, typeDump.ToString(), assemblyNameClean);
×
81
            });
×
82
        }
83
    }
×
84

85
    private static string GetFilePathForType(string outputRoot, TypeAnalysisContext type, string assemblyNameClean)
86
    {
87
        //Get root assembly directory
88
        var assemblyDir = Path.Combine(outputRoot, assemblyNameClean);
×
89

90
        //If type is nested, we should use namespace of ultimate declaring type, which could be an arbitrary depth
91
        //E.g. rewired has a type Rewired.Data.Mapping.HardwareJoystickMap, which contains a nested class Platform_Linux_Base, which contains MatchingCriteria, which contains ElementCount.
92
        var ultimateDeclaringType = type;
×
93
        while (ultimateDeclaringType.DeclaringType != null)
×
94
            ultimateDeclaringType = ultimateDeclaringType.DeclaringType;
×
95

96
        var namespaceSplit = ultimateDeclaringType.Namespace!.Split('.');
×
97
        namespaceSplit = namespaceSplit
×
98
            .Peek(n => MiscUtils.InvalidPathChars.ForEach(c => n = n.Replace(c, '_')))
×
99
            .Select(n => MiscUtils.InvalidPathElements.Contains(n) ? $"__illegalwin32name_{n}__" : n)
×
100
            .ToArray();
×
101

102
        //Ok so we have the namespace directory. Now we need to join all the declaring type hierarchy together for a filename.
103
        var declaringTypeHierarchy = new List<string>();
×
104
        var declaringType = type.DeclaringType;
×
105
        while (declaringType != null)
×
106
        {
107
            declaringTypeHierarchy.Add(declaringType.Name!);
×
108
            declaringType = declaringType.DeclaringType;
×
109
        }
110

111
        //Reverse so we have top-level type first.
112
        declaringTypeHierarchy.Reverse();
×
113

114
        //Join the hierarchy together with _NestedType_ separators
115
        string filename;
116
        if (declaringTypeHierarchy.Count > 0)
×
117
            filename = $"{string.Join("_NestedType_", declaringTypeHierarchy)}_NestedType_{type.Name}.txt";
×
118
        else
119
            filename = $"{type.Name}.txt";
×
120

121
        //Get directory from assembly root + namespace
122
        var directory = Path.Combine(namespaceSplit.Prepend(assemblyDir).ToArray());
×
123
        if (!Directory.Exists(directory))
×
124
            Directory.CreateDirectory(directory);
×
125

126
        //Clean up the filename
127
        MiscUtils.InvalidPathChars.ForEach(c => filename = filename.Replace(c, '_'));
×
128

129
        //Combine the directory and filename
130
        return Path.Combine(directory, filename);
×
131
    }
132

133
    private static void WriteTypeDump(string outputRoot, TypeAnalysisContext type, string typeDump, string assemblyNameClean)
134
    {
135
        var file = GetFilePathForType(outputRoot, type, assemblyNameClean);
×
136
        File.WriteAllText(file, typeDump);
×
137
    }
×
138
}
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