diff --git a/Cpp2IL.Core/Model/Contexts/ParameterAnalysisContext.cs b/Cpp2IL.Core/Model/Contexts/ParameterAnalysisContext.cs index 33bf2b24..8b05b999 100644 --- a/Cpp2IL.Core/Model/Contexts/ParameterAnalysisContext.cs +++ b/Cpp2IL.Core/Model/Contexts/ParameterAnalysisContext.cs @@ -93,7 +93,7 @@ public override string ToString() else if(ParameterType.Byref == 1) result.Append("ref "); - result.Append(ParameterTypeContext.Name).Append(" "); + result.Append(CsFileUtils.GetTypeName(ParameterTypeContext.Name)).Append(' '); if (string.IsNullOrEmpty(ParameterName)) result.Append("unnamed_param_").Append(ParamIndex); @@ -101,7 +101,17 @@ public override string ToString() result.Append(ParameterName); if (ParameterAttributes.HasFlag(ParameterAttributes.HasDefault)) - result.Append(" = ").Append(DefaultValue?.ContainedDefaultValue ?? "null"); + { + var defaultValue = DefaultValue!.ContainedDefaultValue; + if (defaultValue is string stringDefaultValue) + defaultValue = $"\"{stringDefaultValue}\""; + else if (defaultValue is bool boolDefaultValue) + defaultValue = boolDefaultValue.ToString().ToLowerInvariant(); + else if (defaultValue is null) + defaultValue = "null"; + + result.Append(" = ").Append(defaultValue); + } return result.ToString(); } diff --git a/Cpp2IL.Core/OutputFormats/DiffableCsOutputFormat.cs b/Cpp2IL.Core/OutputFormats/DiffableCsOutputFormat.cs index 901f54b7..e0da7ceb 100644 --- a/Cpp2IL.Core/OutputFormats/DiffableCsOutputFormat.cs +++ b/Cpp2IL.Core/OutputFormats/DiffableCsOutputFormat.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using Cpp2IL.Core.Api; using Cpp2IL.Core.Extensions; @@ -81,9 +82,9 @@ private static Dictionary BuildOutput(ApplicationAnalysis private static void AppendType(StringBuilder sb, TypeAnalysisContext type, int indent = 0) { - if (type.IsCompilerGeneratedBasedOnCustomAttributes) + // if (type.IsCompilerGeneratedBasedOnCustomAttributes) //Do not output compiler-generated types - return; + // return; //Custom attributes for type. Includes a trailing newline AppendCustomAttributes(sb, type, indent); @@ -175,8 +176,41 @@ private static void AppendField(StringBuilder sb, FieldAnalysisContext field, in sb.Append(CsFileUtils.GetTypeName(field.FieldTypeContext.Name)); sb.Append(' '); sb.Append(field.Name); + + if (field.BackingData?.DefaultValue is {} defaultValue) + { + sb.Append(" = "); + + if (defaultValue is string stringDefaultValue) + sb.Append('"').Append(stringDefaultValue).Append('"'); + else + sb.Append(defaultValue); + } + sb.Append("; //Field offset: 0x"); sb.Append(field.Offset.ToString("X")); + + if ((field.Attributes & FieldAttributes.HasFieldRVA) != 0) + { + sb.Append(" || Has Field RVA: 0x"); + var (dataIndex, _) = LibCpp2IlMain.TheMetadata!.GetFieldDefaultValue(field.BackingData!.Field.FieldIndex); + var pointer = LibCpp2IlMain.TheMetadata!.GetDefaultValueFromIndex(dataIndex); + sb.Append(pointer.ToString("X8")); + + var actualValue = field.BackingData.Field.StaticArrayInitialValue; + if (actualValue is { Length: > 0 }) + { + sb.Append(" || Field RVA Decoded (hex blob): ["); + sb.Append(actualValue[0].ToString("X2")); + for (var i = 1; i < actualValue.Length; i++) + { + var b = actualValue[i]; + sb.Append(' ').Append(b.ToString("X2")); + } + + sb.Append(']'); + } + } sb.AppendLine(); } @@ -285,7 +319,7 @@ private static void AppendAccessor(StringBuilder sb, MethodAnalysisContext acces AppendCustomAttributes(sb, accessor, indent); sb.Append('\t', indent); - sb.Append(CsFileUtils.GetKeyWordsForMethod(accessor, true)); + sb.Append(CsFileUtils.GetKeyWordsForMethod(accessor, true, true)); sb.Append(' '); sb.Append(accessorType); sb.Append(" { } //Length: "); diff --git a/Cpp2IL.Core/Utils/CsFileUtils.cs b/Cpp2IL.Core/Utils/CsFileUtils.cs index 3ac52e37..53dcddab 100644 --- a/Cpp2IL.Core/Utils/CsFileUtils.cs +++ b/Cpp2IL.Core/Utils/CsFileUtils.cs @@ -111,20 +111,26 @@ public static string GetKeyWordsForField(FieldAnalysisContext field) /// /// The method to generate keywords for /// Skip slot-related modifiers like abstract, virtual, override - public static string GetKeyWordsForMethod(MethodAnalysisContext method, bool skipSlotRelated = false) + /// Skip the public and static keywords, as those aren't valid for property accessors + public static string GetKeyWordsForMethod(MethodAnalysisContext method, bool skipSlotRelated = false, bool skipKeywordsInvalidForAccessors = false) { var sb = new StringBuilder(); var attributes = method.Definition!.Attributes; - if (attributes.HasFlag(MethodAttributes.Public)) - sb.Append("public "); - else if (attributes.HasFlag(MethodAttributes.Family)) - sb.Append("protected "); + if (!skipKeywordsInvalidForAccessors) + { + if (attributes.HasFlag(MethodAttributes.Public)) + sb.Append("public "); + else if (attributes.HasFlag(MethodAttributes.Family)) + sb.Append("protected "); + } + if (attributes.HasFlag(MethodAttributes.Assembly)) sb.Append("internal "); else if (attributes.HasFlag(MethodAttributes.Private)) sb.Append("private "); - if (attributes.HasFlag(MethodAttributes.Static)) + + if (!skipKeywordsInvalidForAccessors && attributes.HasFlag(MethodAttributes.Static)) sb.Append("static "); if (method.DeclaringType!.Definition!.Attributes.HasFlag(TypeAttributes.Interface) || skipSlotRelated) @@ -277,6 +283,9 @@ public static string GetTypeName(string originalName) //Generics - remove `1 etc return originalName.Remove(originalName.IndexOf('`'), 2); + if (originalName[^1] == '&') + originalName = originalName[..^1]; //Remove trailing & for ref params + return originalName switch { "Void" => "void", diff --git a/LibCpp2IL/MetadataUsageType.cs b/LibCpp2IL/MetadataUsageType.cs index cd66990b..9b06e61e 100644 --- a/LibCpp2IL/MetadataUsageType.cs +++ b/LibCpp2IL/MetadataUsageType.cs @@ -8,5 +8,6 @@ public enum MetadataUsageType: uint FieldInfo = 4, StringLiteral = 5, MethodRef = 6, + FieldRva = 7, } -} \ No newline at end of file +}