Browse Source

Fixed some issues with GetBaseTypes/GetAllBaseTypes.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
b59597ec25
  1. 34
      ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs
  2. 10
      ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
  3. 40
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs

34
ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs

@ -70,7 +70,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.AreEqual(new [] { c }, c.GetAllBaseTypes(context).ToArray()); Assert.AreEqual(new [] { c }, c.GetAllBaseTypes(context).ToArray());
} }
[Test] [Test]
public void ClassDerivingFromTwoInstanciationsOfIEnumerable() public void ClassDerivingFromTwoInstanciationsOfIEnumerable()
{ {
@ -78,14 +77,33 @@ namespace ICSharpCode.NRefactory.TypeSystem
DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C"); DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");
c.BaseTypes.Add(typeof(IEnumerable<int>).ToTypeReference()); c.BaseTypes.Add(typeof(IEnumerable<int>).ToTypeReference());
c.BaseTypes.Add(typeof(IEnumerable<uint>).ToTypeReference()); c.BaseTypes.Add(typeof(IEnumerable<uint>).ToTypeReference());
Assert.AreEqual(new [] { IType[] expected = {
c, c,
c.BaseTypes[0].Resolve(context), c.BaseTypes[0].Resolve(context),
c.BaseTypes[1].Resolve(context), c.BaseTypes[1].Resolve(context),
mscorlib.GetClass(typeof(IEnumerable)), mscorlib.GetClass(typeof(IEnumerable)),
mscorlib.GetClass(typeof(object)) mscorlib.GetClass(typeof(object))
}, };
Assert.AreEqual(expected,
c.GetAllBaseTypes(context).OrderBy(t => t.DotNetName).ToArray()); c.GetAllBaseTypes(context).OrderBy(t => t.DotNetName).ToArray());
} }
[Test]
public void StructImplementingIEquatable()
{
// struct S : IEquatable<S> {}
// don't use a Cecil-loaded struct for this test; we're testing the implicit addition of System.ValueType
DefaultTypeDefinition s = new DefaultTypeDefinition(mscorlib, string.Empty, "S");
s.ClassType = ClassType.Struct;
s.BaseTypes.Add(new ParameterizedType(mscorlib.GetClass(typeof(IEquatable<>)), new[] { s }));
IType[] expected = {
s,
s.BaseTypes[0].Resolve(context),
mscorlib.GetClass(typeof(object)),
mscorlib.GetClass(typeof(ValueType))
};
Assert.AreEqual(expected,
s.GetAllBaseTypes(context).OrderBy(t => t.DotNetName).ToArray());
}
} }
} }

10
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -43,11 +43,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
} }
// Avoid outputting a type more than once - necessary for "diamond" multiple inheritance // Avoid outputting a type more than once - necessary for "diamond" multiple inheritance
// (e.g. C implements I1 and I2, and both interfaces derive from Object) // (e.g. C implements I1 and I2, and both interfaces derive from Object)
if (output.Contains(type)) if (!output.Contains(type)) {
return; output.Add(type);
output.Add(type); foreach (IType baseType in type.GetBaseTypes(context)) {
foreach (IType baseType in type.GetBaseTypes(context)) { CollectAllBaseTypes(baseType, context, activeTypeDefinitions, output);
CollectAllBaseTypes(baseType, context, activeTypeDefinitions, output); }
} }
if (def != null) if (def != null)
activeTypeDefinitions.Pop(); activeTypeDefinitions.Pop();

40
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs

@ -318,30 +318,36 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IEnumerable<IType> GetBaseTypes(ITypeResolveContext context) public IEnumerable<IType> GetBaseTypes(ITypeResolveContext context)
{ {
if (baseTypes == null || baseTypes.Count == 0) { bool hasNonInterface = false;
if (this.FullName == "System.Object") if (baseTypes != null) {
return EmptyList<IType>.Instance; foreach (ITypeReference baseTypeRef in baseTypes) {
IType baseType = baseTypeRef.Resolve(context);
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null || baseTypeDef.ClassType != ClassType.Interface)
hasNonInterface = true;
yield return baseType;
}
}
if (!hasNonInterface && !(this.Name == "Object" && this.Namespace == "System" && this.TypeParameterCount == 0)) {
Type primitiveBaseType;
switch (classType) { switch (classType) {
case ClassType.Enum: case ClassType.Enum:
return GetPrimitiveBaseType(typeof(Enum), context); primitiveBaseType = typeof(Enum);
break;
case ClassType.Struct: case ClassType.Struct:
return GetPrimitiveBaseType(typeof(ValueType), context); primitiveBaseType = typeof(ValueType);
break;
case ClassType.Delegate: case ClassType.Delegate:
return GetPrimitiveBaseType(typeof(Delegate), context); primitiveBaseType = typeof(Delegate);
break;
default: default:
return GetPrimitiveBaseType(typeof(object), context); primitiveBaseType = typeof(object);
break;
} }
IType t = context.GetClass(primitiveBaseType);
if (t != null)
yield return t;
} }
return baseTypes.Select(t => t.Resolve(context)).Where(t => t != SharedTypes.UnknownType);
}
static IEnumerable<IType> GetPrimitiveBaseType(Type type, ITypeResolveContext context)
{
IType t = context.GetClass(type);
if (t != null)
return new [] { t };
else
return EmptyList<IType>.Instance;
} }
public virtual ITypeDefinition GetCompoundClass() public virtual ITypeDefinition GetCompoundClass()

Loading…
Cancel
Save