|
|
|
@ -1031,9 +1031,56 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -1031,9 +1031,56 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (typeDecl.ClassType == ClassType.Enum) { |
|
|
|
|
switch (DetectBestEnumValueDisplayMode(typeDef)) { |
|
|
|
|
case EnumValueDisplayMode.FirstOnly: |
|
|
|
|
foreach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>().Skip(1)) { |
|
|
|
|
enumMember.Initializer = null; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case EnumValueDisplayMode.None: |
|
|
|
|
foreach (var enumMember in typeDecl.Members.OfType<EnumMemberDeclaration>()) { |
|
|
|
|
enumMember.Initializer = null; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case EnumValueDisplayMode.All: |
|
|
|
|
// nothing needs to be changed.
|
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
throw new ArgumentOutOfRangeException(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return typeDecl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum EnumValueDisplayMode |
|
|
|
|
{ |
|
|
|
|
None, |
|
|
|
|
All, |
|
|
|
|
FirstOnly |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EnumValueDisplayMode DetectBestEnumValueDisplayMode(ITypeDefinition typeDef) |
|
|
|
|
{ |
|
|
|
|
if (typeDef.GetAttribute(new TopLevelTypeName("System", "FlagsAttribute")) != null) |
|
|
|
|
return EnumValueDisplayMode.All; |
|
|
|
|
bool first = true; |
|
|
|
|
long firstValue = 0, previousValue = 0; |
|
|
|
|
foreach (var field in typeDef.Fields) { |
|
|
|
|
var fieldDef = typeSystem.GetCecil(field) as FieldDefinition; |
|
|
|
|
if (!(fieldDef != null && !MemberIsHidden(fieldDef, settings))) continue; |
|
|
|
|
long currentValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false); |
|
|
|
|
if (first) { |
|
|
|
|
firstValue = currentValue; |
|
|
|
|
first = false; |
|
|
|
|
} else if (previousValue + 1 != currentValue) { |
|
|
|
|
return EnumValueDisplayMode.All; |
|
|
|
|
} |
|
|
|
|
previousValue = currentValue; |
|
|
|
|
} |
|
|
|
|
return firstValue == 0 ? EnumValueDisplayMode.None : EnumValueDisplayMode.FirstOnly; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static readonly Syntax.Attribute obsoleteAttributePattern = new Syntax.Attribute() { |
|
|
|
|
Type = new TypePattern(typeof(ObsoleteAttribute)), |
|
|
|
|
Arguments = { |
|
|
|
@ -1217,26 +1264,17 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -1217,26 +1264,17 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
Debug.Assert(decompilationContext.CurrentMember == field); |
|
|
|
|
var typeSystemAstBuilder = CreateAstBuilder(decompilationContext); |
|
|
|
|
if (decompilationContext.CurrentTypeDefinition.Kind == TypeKind.Enum && field.ConstantValue != null) { |
|
|
|
|
var index = decompilationContext.CurrentTypeDefinition.Members.IndexOf(field); |
|
|
|
|
long previousValue = -1; |
|
|
|
|
if (index > 0) { |
|
|
|
|
var previousMember = (IField)decompilationContext.CurrentTypeDefinition.Members[index - 1]; |
|
|
|
|
previousValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, previousMember.ConstantValue, false); |
|
|
|
|
} |
|
|
|
|
var enumDec = new EnumMemberDeclaration { Name = field.Name }; |
|
|
|
|
long initValue = (long)CSharpPrimitiveCast.Cast(TypeCode.Int64, field.ConstantValue, false); |
|
|
|
|
if (decompilationContext.CurrentTypeDefinition.Attributes.Any(a => a.AttributeType.FullName == "System.FlagsAttribute")) { |
|
|
|
|
enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue); |
|
|
|
|
if (enumDec.Initializer is PrimitiveExpression primitive) |
|
|
|
|
primitive.SetValue(initValue, $"0x{initValue:X}"); |
|
|
|
|
} else if (previousValue + 1 != initValue) { |
|
|
|
|
enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue); |
|
|
|
|
if (enumDec.Initializer is PrimitiveExpression primitive && initValue > 9 && ((initValue & (initValue - 1)) == 0 || (initValue & (initValue + 1)) == 0)) { |
|
|
|
|
primitive.SetValue(initValue, $"0x{initValue:X}"); |
|
|
|
|
} |
|
|
|
|
enumDec.Initializer = typeSystemAstBuilder.ConvertConstantValue(decompilationContext.CurrentTypeDefinition.EnumUnderlyingType, field.ConstantValue); |
|
|
|
|
if (enumDec.Initializer is PrimitiveExpression primitive |
|
|
|
|
&& (decompilationContext.CurrentTypeDefinition.Attributes.Any(a => a.AttributeType.FullName == "System.FlagsAttribute") |
|
|
|
|
|| (initValue > 9 && ((initValue & (initValue - 1)) == 0 || (initValue & (initValue + 1)) == 0)))) |
|
|
|
|
{ |
|
|
|
|
primitive.SetValue(initValue, $"0x{initValue:X}"); |
|
|
|
|
} |
|
|
|
|
enumDec.Attributes.AddRange(field.Attributes.Select(a => new AttributeSection(typeSystemAstBuilder.ConvertAttribute(a)))); |
|
|
|
|
enumDec.AddAnnotation(new Semantics.MemberResolveResult(null, field)); |
|
|
|
|
enumDec.AddAnnotation(new MemberResolveResult(null, field)); |
|
|
|
|
return enumDec; |
|
|
|
|
} |
|
|
|
|
typeSystemAstBuilder.UseSpecialConstants = !field.DeclaringType.Equals(field.ReturnType); |
|
|
|
|