From 2e00285666d38aa6efb024d36966e48febbcb86a Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 4 May 2019 22:44:35 +0200 Subject: [PATCH] Display type information of fixed fields as "Type[Length]" in tree view. --- .../CSharp/CSharpDecompiler.cs | 21 +++++++++++++++++++ .../CSharp/OutputVisitor/CSharpAmbience.cs | 8 ++++++- .../CSharp/Syntax/TypeSystemAstBuilder.cs | 8 +++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 41119a828..00791e127 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -1406,6 +1406,27 @@ namespace ICSharpCode.Decompiler.CSharp return false; } + internal static bool IsFixedField(MetadataReader metadata, FieldDefinitionHandle handle, out IType type, out int elementCount) + { + type = null; + elementCount = 0; + var field = metadata.GetFieldDefinition(handle); + foreach (var h in field.GetCustomAttributes()) { + var customAttribute = metadata.GetCustomAttribute(h); + if (customAttribute.IsKnownAttribute(metadata, KnownAttribute.FixedBuffer)) { + var value = customAttribute.DecodeValue(MetadataExtensions.minimalCorlibTypeProvider); + if (value.FixedArguments.Length == 2) { + if (value.FixedArguments[0].Value is IType trr && value.FixedArguments[1].Value is int length) { + type = trr; + elementCount = length; + return true; + } + } + } + } + return false; + } + EntityDeclaration DoDecompile(IProperty property, DecompileRun decompileRun, ITypeResolveContext decompilationContext) { Debug.Assert(decompilationContext.CurrentMember == property); diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs index 775cff0b0..6064fbd33 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs @@ -137,7 +137,13 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor writer.Space(); writer.WriteToken(Roles.Colon, ":"); writer.Space(); - rt.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); + if (symbol is IField f && CSharpDecompiler.IsFixedField(f.ParentModule.PEFile.Metadata, (System.Reflection.Metadata.FieldDefinitionHandle)f.MetadataToken, out var type, out int elementCount)) { + rt = astBuilder.ConvertType(type); + new IndexerExpression(new TypeReferenceExpression(rt), astBuilder.ConvertConstantValue(f.Compilation.FindType(KnownTypeCode.Int32), elementCount)) + .AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); + } else { + rt.AcceptVisitor(new CSharpOutputVisitor(writer, formattingPolicy)); + } } } diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index 714befab6..c31a53c07 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -176,25 +176,25 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public bool UseCustomEvents { get; set; } /// - /// Controls if unbound type argument names are inserted in the ast or not. + /// Controls whether unbound type argument names are inserted in the ast or not. /// The default value is false. /// public bool ConvertUnboundTypeArguments { get; set;} /// - /// Controls if aliases should be used inside the type name or not. + /// Controls whether aliases should be used inside the type name or not. /// The default value is true. /// public bool UseAliases { get; set; } /// - /// Controls if constants like int.MaxValue are converted to a or . + /// Controls whether constants like int.MaxValue are converted to a or . /// The default value is true. /// public bool UseSpecialConstants { get; set; } /// - /// Controls if integral constants should be printed in hexadecimal format. + /// Controls whether integral constants should be printed in hexadecimal format. /// The default value is false. /// public bool PrintIntegralValuesAsHex { get; set; }