From 9d19b33ec0e8f9ad83738f42afabe54d419114a8 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 26 Jan 2019 15:31:47 +0100 Subject: [PATCH] Fix #1394: Fields marked 'specialname' are excluded from the type system --- .../TypeSystem/TypeSystemLoaderTests.cs | 10 +++++++++- ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs | 4 +++- .../Implementation/MetadataTypeDefinition.cs | 2 +- ILSpy/TreeNodes/TypeTreeNode.cs | 12 +++++++++--- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs index 2b23df55a..dc7d6bad1 100644 --- a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs +++ b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs @@ -488,9 +488,17 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem public void EnumFieldsTest() { var e = GetTypeDefinition(typeof(MyEnum)); - IField[] fields = e.Fields.ToArray(); + IField valueField = e.Fields.First(); + IField[] fields = e.Fields.Skip(1).ToArray(); Assert.AreEqual(5, fields.Length); + Assert.AreEqual("value__", valueField.Name); + Assert.AreEqual(GetTypeDefinition(typeof(short)), valueField.Type); + Assert.AreEqual(Accessibility.Public, valueField.Accessibility); + Assert.AreEqual(null, valueField.GetConstantValue()); + Assert.IsFalse(valueField.IsConst); + Assert.IsFalse(valueField.IsStatic); + foreach (IField f in fields) { Assert.IsTrue(f.IsStatic); Assert.IsTrue(f.IsConst); diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 60c9f518b..d61c36f75 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -951,6 +951,8 @@ namespace ICSharpCode.Decompiler.CSharp } foreach (var field in typeDef.Fields) { if (!field.MetadataToken.IsNil && !MemberIsHidden(module.PEFile, field.MetadataToken, settings)) { + if (typeDef.Kind == TypeKind.Enum && !field.IsConst) + continue; var memberDecl = DoDecompile(field, decompileRun, decompilationContext.WithCurrentMember(field)); typeDecl.Members.Add(memberDecl); } @@ -1262,7 +1264,7 @@ namespace ICSharpCode.Decompiler.CSharp Debug.Assert(decompilationContext.CurrentMember == field); try { var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); - if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum) { + if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum && field.IsConst) { var enumDec = new EnumMemberDeclaration { Name = field.Name }; object constantValue = field.GetConstantValue(); if (constantValue != null) { diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs index d053a6bdb..f4bd17efb 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs @@ -162,7 +162,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation foreach (FieldDefinitionHandle h in fieldCollection) { var field = metadata.GetFieldDefinition(h); var attr = field.Attributes; - if (module.IsVisible(attr) && (attr & FieldAttributes.SpecialName) == 0) { + if (module.IsVisible(attr)) { fieldList.Add(module.GetDefinition(h)); } } diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index 6f1c394ec..3ef91c411 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -79,10 +79,16 @@ namespace ICSharpCode.ILSpy.TreeNodes foreach (var nestedType in TypeDefinition.NestedTypes.OrderBy(t => t.Name, NaturalStringComparer.Instance)) { this.Children.Add(new TypeTreeNode(nestedType, ParentAssemblyNode)); } - foreach (var field in TypeDefinition.Fields.OrderBy(f => f.Name, NaturalStringComparer.Instance)) { - this.Children.Add(new FieldTreeNode(field)); + if (TypeDefinition.Kind == TypeKind.Enum) { + // if the type is an enum, it's better to not sort by field name. + foreach (var field in TypeDefinition.Fields) { + this.Children.Add(new FieldTreeNode(field)); + } + } else { + foreach (var field in TypeDefinition.Fields.OrderBy(f => f.Name, NaturalStringComparer.Instance)) { + this.Children.Add(new FieldTreeNode(field)); + } } - foreach (var property in TypeDefinition.Properties.OrderBy(p => p.Name, NaturalStringComparer.Instance)) { this.Children.Add(new PropertyTreeNode(property)); }