Browse Source

Fixed references to enum values nested within generic types.

pull/252/head
Daniel Grunwald 14 years ago
parent
commit
9376ece056
  1. 12
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 8
      ICSharpCode.Decompiler/Tests/Generics.cs
  3. 2
      ICSharpCode.Decompiler/Tests/TestRunner.cs

12
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -1501,13 +1501,13 @@ namespace ICSharpCode.Decompiler.Ast
{ // cannot rely on type.IsValueType, it's not set for typerefs (but is set for typespecs) { // cannot rely on type.IsValueType, it's not set for typerefs (but is set for typespecs)
TypeDefinition enumDefinition = type.Resolve(); TypeDefinition enumDefinition = type.Resolve();
if (enumDefinition != null && enumDefinition.IsEnum) { if (enumDefinition != null && enumDefinition.IsEnum) {
TypeCode enumBaseTypeCode = TypeCode.Int32;
foreach (FieldDefinition field in enumDefinition.Fields) { foreach (FieldDefinition field in enumDefinition.Fields) {
if (field.IsStatic && object.Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false), val)) if (field.IsStatic && object.Equals(CSharpPrimitiveCast.Cast(TypeCode.Int64, field.Constant, false), val))
return ConvertType(enumDefinition).Member(field.Name).WithAnnotation(field); return ConvertType(type).Member(field.Name).WithAnnotation(field);
else if (!field.IsStatic && field.IsRuntimeSpecialName) else if (!field.IsStatic && field.IsRuntimeSpecialName)
type = field.FieldType; // use primitive type of the enum enumBaseTypeCode = TypeAnalysis.GetTypeCode(field.FieldType); // use primitive type of the enum
} }
TypeCode enumBaseTypeCode = TypeAnalysis.GetTypeCode(type);
if (IsFlagsEnum(enumDefinition)) { if (IsFlagsEnum(enumDefinition)) {
long enumValue = val; long enumValue = val;
Expression expr = null; Expression expr = null;
@ -1534,7 +1534,7 @@ namespace ICSharpCode.Decompiler.Ast
continue; // skip None enum value continue; // skip None enum value
if ((fieldValue & enumValue) == fieldValue) { if ((fieldValue & enumValue) == fieldValue) {
var fieldExpression = ConvertType(enumDefinition).Member(field.Name).WithAnnotation(field); var fieldExpression = ConvertType(type).Member(field.Name).WithAnnotation(field);
if (expr == null) if (expr == null)
expr = fieldExpression; expr = fieldExpression;
else else
@ -1543,7 +1543,7 @@ namespace ICSharpCode.Decompiler.Ast
enumValue &= ~fieldValue; enumValue &= ~fieldValue;
} }
if ((fieldValue & negatedEnumValue) == fieldValue) { if ((fieldValue & negatedEnumValue) == fieldValue) {
var fieldExpression = ConvertType(enumDefinition).Member(field.Name).WithAnnotation(field); var fieldExpression = ConvertType(type).Member(field.Name).WithAnnotation(field);
if (negatedExpr == null) if (negatedExpr == null)
negatedExpr = fieldExpression; negatedExpr = fieldExpression;
else else
@ -1561,7 +1561,7 @@ namespace ICSharpCode.Decompiler.Ast
return new UnaryOperatorExpression(UnaryOperatorType.BitNot, negatedExpr); return new UnaryOperatorExpression(UnaryOperatorType.BitNot, negatedExpr);
} }
} }
return new Ast.PrimitiveExpression(CSharpPrimitiveCast.Cast(enumBaseTypeCode, val, false)).CastTo(ConvertType(enumDefinition)); return new Ast.PrimitiveExpression(CSharpPrimitiveCast.Cast(enumBaseTypeCode, val, false)).CastTo(ConvertType(type));
} }
} }
TypeCode code = TypeAnalysis.GetTypeCode(type); TypeCode code = TypeAnalysis.GetTypeCode(type);

8
ICSharpCode.Decompiler/Tests/Generics.cs

@ -29,6 +29,12 @@ public static class Generics
public Y Item2; public Y Item2;
} }
public enum NestedEnum
{
A,
B
}
private T[] arr; private T[] arr;
public MyArray(int capacity) public MyArray(int capacity)
@ -75,11 +81,13 @@ public static class Generics
} }
} }
private const Generics.MyArray<string>.NestedEnum enumVal = Generics.MyArray<string>.NestedEnum.A;
private static Type type1 = typeof(List<>); private static Type type1 = typeof(List<>);
private static Type type2 = typeof(Generics.MyArray<>); private static Type type2 = typeof(Generics.MyArray<>);
private static Type type3 = typeof(List<>.Enumerator); private static Type type3 = typeof(List<>.Enumerator);
private static Type type4 = typeof(Generics.MyArray<>.NestedClass<>); private static Type type4 = typeof(Generics.MyArray<>.NestedClass<>);
private static Type type5 = typeof(List<int>[]); private static Type type5 = typeof(List<int>[]);
private static Type type6 = typeof(Generics.MyArray<>.NestedEnum);
public static void MethodWithConstraint<T, S>() where T : class, S where S : ICloneable, new() public static void MethodWithConstraint<T, S>() where T : class, S where S : ICloneable, new()
{ {

2
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -158,7 +158,7 @@ namespace ICSharpCode.Decompiler.Tests
{ {
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } }); CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters(); CompilerParameters options = new CompilerParameters();
options.CompilerOptions = "/unsafe"; options.CompilerOptions = "/unsafe /o-";
options.ReferencedAssemblies.Add("System.Core.dll"); options.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = provider.CompileAssemblyFromSource(options, code); CompilerResults results = provider.CompileAssemblyFromSource(options, code);
try { try {

Loading…
Cancel
Save