diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
index 4e54821c74..52078704c8 100644
--- a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
+++ b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
@@ -44,4 +44,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase
public string this[int index] { get { return "Test"; } }
}
+
+ public enum MyEnum : short
+ {
+ First,
+ Second,
+ Flag1 = 0x10,
+ Flag2 = 0x20,
+ CombinedFlags = Flag1 | Flag2
+ }
}
diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
index 5764434bfe..758af7e85e 100644
--- a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
+++ b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
@@ -181,5 +181,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.IsFalse(p.CanSet);
Assert.AreEqual(Accessibility.None, p.SetterAccessibility);
}
+
+ [Test]
+ public void EnumTest()
+ {
+ var e = testCasePC.GetClass(typeof(MyEnum));
+ Assert.AreEqual(ClassType.Enum, e.ClassType);
+ Assert.AreEqual(false, e.IsReferenceType);
+ Assert.AreEqual("System.Int16", e.BaseTypes[0].Resolve(ctx).DotNetName);
+ Assert.AreEqual(new[] { "System.Enum" }, e.GetBaseTypes(ctx).Select(t => t.DotNetName).ToArray());
+ }
}
}
diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs b/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
index 54e1ce763e..98a228d963 100644
--- a/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
@@ -378,7 +378,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
return new ErrorResolveResult(targetType);
} else if (targetType.IsEnum()) {
- throw new NotImplementedException();
+ code = ReflectionHelper.GetTypeCode(targetType.GetEnumUnderlyingType(context));
+ if (code >= TypeCode.SByte && code <= TypeCode.UInt64) {
+ try {
+ return new ConstantResolveResult(targetType, Convert.ChangeType(expression.ConstantValue, code, CultureInfo.InvariantCulture));
+ } catch (InvalidCastException) {
+ return new ErrorResolveResult(targetType);
+ }
+ }
}
}
return new ResolveResult(targetType);
diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
index f4abb6c8ee..780c3f0b80 100644
--- a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
@@ -456,12 +456,21 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
// set base classes
- if (typeDefinition.BaseType != null) {
- BaseTypes.Add(loader.ReadTypeReference(typeDefinition.BaseType, entity: this));
- }
- if (typeDefinition.HasInterfaces) {
- foreach (TypeReference iface in typeDefinition.Interfaces) {
- BaseTypes.Add(loader.ReadTypeReference(iface, entity: this));
+ if (typeDefinition.IsEnum) {
+ foreach (FieldDefinition enumField in typeDefinition.Fields) {
+ if (!enumField.IsStatic) {
+ BaseTypes.Add(loader.ReadTypeReference(enumField.FieldType, entity: this));
+ break;
+ }
+ }
+ } else {
+ if (typeDefinition.BaseType != null) {
+ BaseTypes.Add(loader.ReadTypeReference(typeDefinition.BaseType, entity: this));
+ }
+ if (typeDefinition.HasInterfaces) {
+ foreach (TypeReference iface in typeDefinition.Interfaces) {
+ BaseTypes.Add(loader.ReadTypeReference(iface, entity: this));
+ }
}
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
index 3d65b15a19..a55a760f3e 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
@@ -88,7 +88,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("type");
return type is ITypeDefinition && type.TypeParameterCount > 0;
}
+ #endregion
+ #region IsEnum / GetEnumUnderlyingType
///
/// Gets whether the type is an enumeration type.
///
@@ -99,6 +101,26 @@ namespace ICSharpCode.NRefactory.TypeSystem
ITypeDefinition def = type.GetDefinition();
return def != null && def.ClassType == ClassType.Enum;
}
+
+ ///
+ /// Gets the underlying type for this enum type.
+ ///
+ public static IType GetEnumUnderlyingType(this IType enumType, ITypeResolveContext context)
+ {
+ if (enumType == null)
+ throw new ArgumentNullException("enumType");
+ if (context == null)
+ throw new ArgumentNullException("context");
+ ITypeDefinition def = enumType.GetDefinition();
+ if (def != null && def.ClassType == ClassType.Enum) {
+ if (def.BaseTypes.Count == 1)
+ return def.BaseTypes[0].Resolve(context);
+ else
+ return context.GetClass(typeof(int)) ?? SharedTypes.UnknownType;
+ } else {
+ throw new ArgumentException("enumType must be an enum");
+ }
+ }
#endregion
}
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
index 0456d008fa..dbacbdd78c 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
@@ -319,7 +319,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IEnumerable GetBaseTypes(ITypeResolveContext context)
{
bool hasNonInterface = false;
- if (baseTypes != null) {
+ if (baseTypes != null && this.ClassType != ClassType.Enum) {
foreach (ITypeReference baseTypeRef in baseTypes) {
IType baseType = baseTypeRef.Resolve(context);
ITypeDefinition baseTypeDef = baseType.GetDefinition();