CLI: Merge some options into --must-compile
This commit is contained in:
@@ -21,15 +21,12 @@ namespace Il2CppInspector
|
|||||||
// Namespace prefixes whose contents should be skipped
|
// Namespace prefixes whose contents should be skipped
|
||||||
public List<string> ExcludedNamespaces { get; set; }
|
public List<string> ExcludedNamespaces { get; set; }
|
||||||
|
|
||||||
// Suppress types, fields and methods with the CompilerGenerated attribute; suppress the attribute itself from property getters and setters
|
// Make adjustments to ensure that the generated code compiles
|
||||||
public bool SuppressGenerated { get; set; }
|
public bool MustCompile { get; set; }
|
||||||
|
|
||||||
// Suppress binary metadata in code comments
|
// Suppress binary metadata in code comments
|
||||||
public bool SuppressMetadata { get; set; }
|
public bool SuppressMetadata { get; set; }
|
||||||
|
|
||||||
// Comment out custom attributes with non-optional constructor arguments
|
|
||||||
public bool CommentAttributes { get; set; }
|
|
||||||
|
|
||||||
private const string CGAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute";
|
private const string CGAttribute = "System.Runtime.CompilerServices.CompilerGeneratedAttribute";
|
||||||
private const string FBAttribute = "System.Runtime.CompilerServices.FixedBufferAttribute";
|
private const string FBAttribute = "System.Runtime.CompilerServices.FixedBufferAttribute";
|
||||||
private const string ExtAttribute = "System.Runtime.CompilerServices.ExtensionAttribute";
|
private const string ExtAttribute = "System.Runtime.CompilerServices.ExtensionAttribute";
|
||||||
@@ -188,7 +185,7 @@ namespace Il2CppInspector
|
|||||||
text.Append(asm.CustomAttributes.Where(a => a.AttributeType.FullName != ExtAttribute)
|
text.Append(asm.CustomAttributes.Where(a => a.AttributeType.FullName != ExtAttribute)
|
||||||
.Except(excludedAttributes ?? new List<CustomAttributeData>())
|
.Except(excludedAttributes ?? new List<CustomAttributeData>())
|
||||||
.OrderBy(a => a.AttributeType.Name)
|
.OrderBy(a => a.AttributeType.Name)
|
||||||
.ToString(new Scope { Current = null, Namespaces = namespaces }, attributePrefix: "assembly: ", emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
.ToString(new Scope { Current = null, Namespaces = namespaces }, attributePrefix: "assembly: ", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
if (asm.CustomAttributes.Any())
|
if (asm.CustomAttributes.Any())
|
||||||
text.Append("\n");
|
text.Append("\n");
|
||||||
}
|
}
|
||||||
@@ -197,7 +194,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
private string generateType(TypeInfo type, IEnumerable<string> namespaces, string prefix = "") {
|
private string generateType(TypeInfo type, IEnumerable<string> namespaces, string prefix = "") {
|
||||||
// Don't output compiler-generated types if desired
|
// Don't output compiler-generated types if desired
|
||||||
if (SuppressGenerated && type.GetCustomAttributes(CGAttribute).Any())
|
if (MustCompile && type.GetCustomAttributes(CGAttribute).Any())
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
var codeBlocks = new Dictionary<string, string>();
|
var codeBlocks = new Dictionary<string, string>();
|
||||||
@@ -213,7 +210,7 @@ namespace Il2CppInspector
|
|||||||
sb.Clear();
|
sb.Clear();
|
||||||
if (!type.IsEnum) {
|
if (!type.IsEnum) {
|
||||||
foreach (var field in type.DeclaredFields) {
|
foreach (var field in type.DeclaredFields) {
|
||||||
if (SuppressGenerated && field.GetCustomAttributes(CGAttribute).Any())
|
if (MustCompile && field.GetCustomAttributes(CGAttribute).Any())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (field.IsNotSerialized)
|
if (field.IsNotSerialized)
|
||||||
@@ -221,7 +218,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
sb.Append(field.CustomAttributes.Where(a => a.AttributeType.FullName != FBAttribute).OrderBy(a => a.AttributeType.Name)
|
sb.Append(field.CustomAttributes.Where(a => a.AttributeType.FullName != FBAttribute).OrderBy(a => a.AttributeType.Name)
|
||||||
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
sb.Append(prefix + "\t");
|
sb.Append(prefix + "\t");
|
||||||
sb.Append(field.GetModifierString());
|
sb.Append(field.GetModifierString());
|
||||||
|
|
||||||
@@ -253,7 +250,7 @@ namespace Il2CppInspector
|
|||||||
foreach (var prop in type.DeclaredProperties) {
|
foreach (var prop in type.DeclaredProperties) {
|
||||||
// Attributes
|
// Attributes
|
||||||
sb.Append(prop.CustomAttributes.OrderBy(a => a.AttributeType.Name)
|
sb.Append(prop.CustomAttributes.OrderBy(a => a.AttributeType.Name)
|
||||||
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
|
|
||||||
// The access mask enum values go from 1 (private) to 6 (public) in order from most to least restrictive
|
// The access mask enum values go from 1 (private) to 6 (public) in order from most to least restrictive
|
||||||
var getAccess = (prop.GetMethod?.Attributes ?? 0) & MethodAttributes.MemberAccessMask;
|
var getAccess = (prop.GetMethod?.Attributes ?? 0) & MethodAttributes.MemberAccessMask;
|
||||||
@@ -268,13 +265,13 @@ namespace Il2CppInspector
|
|||||||
// Indexer
|
// Indexer
|
||||||
else
|
else
|
||||||
sb.Append("this[" + string.Join(", ", primary.DeclaredParameters.SkipLast(getAccess >= setAccess? 0 : 1)
|
sb.Append("this[" + string.Join(", ", primary.DeclaredParameters.SkipLast(getAccess >= setAccess? 0 : 1)
|
||||||
.Select(p => p.GetParameterString(scope, !SuppressMetadata, CommentAttributes))) + "] { ");
|
.Select(p => p.GetParameterString(scope, !SuppressMetadata, MustCompile))) + "] { ");
|
||||||
|
|
||||||
sb.Append((prop.CanRead? prop.GetMethod.CustomAttributes.Where(a => !SuppressGenerated || a.AttributeType.FullName != CGAttribute)
|
sb.Append((prop.CanRead? prop.GetMethod.CustomAttributes.Where(a => !MustCompile || a.AttributeType.FullName != CGAttribute)
|
||||||
.ToString(scope, inline: true, emitPointer: !SuppressMetadata, mustCompile: CommentAttributes)
|
.ToString(scope, inline: true, emitPointer: !SuppressMetadata, mustCompile: MustCompile)
|
||||||
+ (getAccess < setAccess? prop.GetMethod.GetAccessModifierString() : "") + "get; " : "")
|
+ (getAccess < setAccess? prop.GetMethod.GetAccessModifierString() : "") + "get; " : "")
|
||||||
+ (prop.CanWrite? prop.SetMethod.CustomAttributes.Where(a => !SuppressGenerated || a.AttributeType.FullName != CGAttribute)
|
+ (prop.CanWrite? prop.SetMethod.CustomAttributes.Where(a => !MustCompile || a.AttributeType.FullName != CGAttribute)
|
||||||
.ToString(scope, inline: true, emitPointer: !SuppressMetadata, mustCompile: CommentAttributes)
|
.ToString(scope, inline: true, emitPointer: !SuppressMetadata, mustCompile: MustCompile)
|
||||||
+ (setAccess < getAccess? prop.SetMethod.GetAccessModifierString() : "") + "set; " : "") + "}");
|
+ (setAccess < getAccess? prop.SetMethod.GetAccessModifierString() : "") + "set; " : "") + "}");
|
||||||
if (!SuppressMetadata) {
|
if (!SuppressMetadata) {
|
||||||
if ((prop.CanRead && prop.GetMethod.VirtualAddress != null) || (prop.CanWrite && prop.SetMethod.VirtualAddress != null))
|
if ((prop.CanRead && prop.GetMethod.VirtualAddress != null) || (prop.CanWrite && prop.SetMethod.VirtualAddress != null))
|
||||||
@@ -294,7 +291,7 @@ namespace Il2CppInspector
|
|||||||
foreach (var evt in type.DeclaredEvents) {
|
foreach (var evt in type.DeclaredEvents) {
|
||||||
// Attributes
|
// Attributes
|
||||||
sb.Append(evt.CustomAttributes.OrderBy(a => a.AttributeType.Name)
|
sb.Append(evt.CustomAttributes.OrderBy(a => a.AttributeType.Name)
|
||||||
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
|
|
||||||
string modifiers = evt.AddMethod?.GetModifierString(scope);
|
string modifiers = evt.AddMethod?.GetModifierString(scope);
|
||||||
sb.Append($"{prefix}\t{modifiers}event {evt.EventHandlerType.GetScopedCSharpName(scope)} {evt.Name} {{\n");
|
sb.Append($"{prefix}\t{modifiers}event {evt.EventHandlerType.GetScopedCSharpName(scope)} {evt.Name} {{\n");
|
||||||
@@ -318,7 +315,7 @@ namespace Il2CppInspector
|
|||||||
foreach (var method in type.DeclaredConstructors) {
|
foreach (var method in type.DeclaredConstructors) {
|
||||||
// Attributes
|
// Attributes
|
||||||
sb.Append(method.CustomAttributes.OrderBy(a => a.AttributeType.Name)
|
sb.Append(method.CustomAttributes.OrderBy(a => a.AttributeType.Name)
|
||||||
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
|
|
||||||
sb.Append($"{prefix}\t{method.GetModifierString(scope)}{method.DeclaringType.UnmangledBaseName}{method.GetTypeParametersString(scope)}(");
|
sb.Append($"{prefix}\t{method.GetModifierString(scope)}{method.DeclaringType.UnmangledBaseName}{method.GetTypeParametersString(scope)}(");
|
||||||
sb.Append(method.GetParametersString(scope, !SuppressMetadata) + ")" + (method.IsAbstract? ";" : @" {}"));
|
sb.Append(method.GetParametersString(scope, !SuppressMetadata) + ")" + (method.IsAbstract? ";" : @" {}"));
|
||||||
@@ -346,7 +343,7 @@ namespace Il2CppInspector
|
|||||||
// TODO: DefaultMemberAttribute should be output if it is present and the type does not have an indexer, otherwise suppressed
|
// TODO: DefaultMemberAttribute should be output if it is present and the type does not have an indexer, otherwise suppressed
|
||||||
// See https://docs.microsoft.com/en-us/dotnet/api/system.reflection.defaultmemberattribute?view=netframework-4.8
|
// See https://docs.microsoft.com/en-us/dotnet/api/system.reflection.defaultmemberattribute?view=netframework-4.8
|
||||||
sb.Append(type.CustomAttributes.Where(a => a.AttributeType.FullName != DMAttribute && a.AttributeType.FullName != ExtAttribute)
|
sb.Append(type.CustomAttributes.Where(a => a.AttributeType.FullName != DMAttribute && a.AttributeType.FullName != ExtAttribute)
|
||||||
.OrderBy(a => a.AttributeType.Name).ToString(scope, prefix, emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
.OrderBy(a => a.AttributeType.Name).ToString(scope, prefix, emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
|
|
||||||
// Roll-up multicast delegates to use the 'delegate' syntactic sugar
|
// Roll-up multicast delegates to use the 'delegate' syntactic sugar
|
||||||
if (type.IsClass && type.IsSealed && type.BaseType?.FullName == "System.MulticastDelegate") {
|
if (type.IsClass && type.IsSealed && type.BaseType?.FullName == "System.MulticastDelegate") {
|
||||||
@@ -354,7 +351,7 @@ namespace Il2CppInspector
|
|||||||
|
|
||||||
var del = type.GetMethod("Invoke");
|
var del = type.GetMethod("Invoke");
|
||||||
// IL2CPP doesn't seem to retain return type attributes
|
// IL2CPP doesn't seem to retain return type attributes
|
||||||
//sb.Append(del.ReturnType.CustomAttributes.ToString(prefix, "return: ", emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
//sb.Append(del.ReturnType.CustomAttributes.ToString(prefix, "return: ", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
if (del.RequiresUnsafeContext)
|
if (del.RequiresUnsafeContext)
|
||||||
sb.Append("unsafe ");
|
sb.Append("unsafe ");
|
||||||
sb.Append($"delegate {del.ReturnType.GetScopedCSharpName(scope)} {type.CSharpTypeDeclarationName}(");
|
sb.Append($"delegate {del.ReturnType.GetScopedCSharpName(scope)} {type.CSharpTypeDeclarationName}(");
|
||||||
@@ -403,14 +400,14 @@ namespace Il2CppInspector
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string generateMethod(MethodInfo method, Scope scope, string prefix) {
|
private string generateMethod(MethodInfo method, Scope scope, string prefix) {
|
||||||
if (SuppressGenerated && method.GetCustomAttributes(CGAttribute).Any())
|
if (MustCompile && method.GetCustomAttributes(CGAttribute).Any())
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
var writer = new StringBuilder();
|
var writer = new StringBuilder();
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
writer.Append(method.CustomAttributes.Where(a => a.AttributeType.FullName != ExtAttribute).OrderBy(a => a.AttributeType.Name)
|
writer.Append(method.CustomAttributes.Where(a => a.AttributeType.FullName != ExtAttribute).OrderBy(a => a.AttributeType.Name)
|
||||||
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: CommentAttributes));
|
.ToString(scope, prefix + "\t", emitPointer: !SuppressMetadata, mustCompile: MustCompile));
|
||||||
|
|
||||||
// IL2CPP doesn't seem to retain return type attributes
|
// IL2CPP doesn't seem to retain return type attributes
|
||||||
//writer.Append(method.ReturnType.CustomAttributes.ToString(prefix + "\t", "return: ", emitPointer: !SuppressMetadata));
|
//writer.Append(method.ReturnType.CustomAttributes.ToString(prefix + "\t", "return: ", emitPointer: !SuppressMetadata));
|
||||||
|
|||||||
@@ -49,11 +49,8 @@ namespace Il2CppInspector
|
|||||||
[Option('n', "suppress-metadata", Required = false, HelpText = "Diff tidying: suppress method pointers, field offsets and type indices from C# output. Useful for comparing two versions of a binary for changes with a diff tool", Default = false)]
|
[Option('n', "suppress-metadata", Required = false, HelpText = "Diff tidying: suppress method pointers, field offsets and type indices from C# output. Useful for comparing two versions of a binary for changes with a diff tool", Default = false)]
|
||||||
public bool SuppressMetadata { get; set; }
|
public bool SuppressMetadata { get; set; }
|
||||||
|
|
||||||
[Option('g', "suppress-cg", Required = false, HelpText = "Compilation tidying: Suppress generation of C# code for items with CompilerGenerated attribute", Default = false)]
|
[Option('k', "must-compile", Required = false, HelpText = "Compilation tidying: try really hard to make code that compiles. Suppress generation of code for items with CompilerGenerated attribute. Comment out attributes without parameterless constructors or all-optional constructor arguments")]
|
||||||
public bool SuppressCompilerGenerated { get; set; }
|
public bool MustCompile { get; set; }
|
||||||
|
|
||||||
[Option('a', "comment-attributes", Required = false, HelpText = "Compilation tidying: comment out attributes without parameterless constructors or all-optional constructor arguments")]
|
|
||||||
public bool CommentParameterizedAttributeConstructors { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int Main(string[] args) =>
|
public static int Main(string[] args) =>
|
||||||
@@ -90,9 +87,8 @@ namespace Il2CppInspector
|
|||||||
// C# signatures output
|
// C# signatures output
|
||||||
var writer = new Il2CppCSharpDumper(model) {
|
var writer = new Il2CppCSharpDumper(model) {
|
||||||
ExcludedNamespaces = options.ExcludedNamespaces.ToList(),
|
ExcludedNamespaces = options.ExcludedNamespaces.ToList(),
|
||||||
SuppressGenerated = options.SuppressCompilerGenerated,
|
|
||||||
SuppressMetadata = options.SuppressMetadata,
|
SuppressMetadata = options.SuppressMetadata,
|
||||||
CommentAttributes = options.CommentParameterizedAttributeConstructors
|
MustCompile = options.MustCompile
|
||||||
};
|
};
|
||||||
|
|
||||||
var imageSuffix = i++ > 0 ? "-" + (i - 1) : "";
|
var imageSuffix = i++ > 0 ? "-" + (i - 1) : "";
|
||||||
|
|||||||
@@ -56,9 +56,8 @@ namespace Il2CppInspector
|
|||||||
foreach (var il2cpp in inspectors)
|
foreach (var il2cpp in inspectors)
|
||||||
new Il2CppCSharpDumper(new Il2CppModel(il2cpp)) {
|
new Il2CppCSharpDumper(new Il2CppModel(il2cpp)) {
|
||||||
ExcludedNamespaces = excludedNamespaces,
|
ExcludedNamespaces = excludedNamespaces,
|
||||||
SuppressGenerated = true,
|
|
||||||
SuppressMetadata = false,
|
SuppressMetadata = false,
|
||||||
CommentAttributes = true
|
MustCompile = true
|
||||||
}.WriteSingleFile(testPath + @"\test-result" + (i++ > 0 ? "-" + (i - 1) : "") + ".cs");
|
}.WriteSingleFile(testPath + @"\test-result" + (i++ > 0 ? "-" + (i - 1) : "") + ".cs");
|
||||||
|
|
||||||
// Compare test result with expected result
|
// Compare test result with expected result
|
||||||
|
|||||||
Reference in New Issue
Block a user