Browse Source

Implemented ITypeParameter.EffectiveInterfaceSet

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
211c6a1b05
  1. 2
      ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs
  2. 85
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs
  3. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs

2
ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs

@ -107,7 +107,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -107,7 +107,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Gets the effective interface set of this type parameter.
/// </summary>
IList<IType> EffectiveInterfaceSet { get; }
ICollection<IType> EffectiveInterfaceSet { get; }
/// <summary>
/// Gets if the type parameter has the 'new()' constraint.

85
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs

@ -94,48 +94,73 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -94,48 +94,73 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public IType EffectiveBaseClass {
get {
if (effectiveBaseClass == null)
effectiveBaseClass = CalculateEffectiveBaseClass();
if (effectiveBaseClass == null) {
// protect against cyclic type parameters
using (var busyLock = BusyManager.Enter(this)) {
if (!busyLock.Success)
return SpecialType.UnknownType; // don't cache this error
effectiveBaseClass = CalculateEffectiveBaseClass();
}
}
return effectiveBaseClass;
}
}
IType CalculateEffectiveBaseClass()
{
// protect against cyclic type parameters
using (var busyLock = BusyManager.Enter(this)) {
if (!busyLock.Success)
return SpecialType.UnknownType;
if (HasValueTypeConstraint)
return this.Compilation.FindType(KnownTypeCode.ValueType);
List<IType> classTypeConstraints = new List<IType>();
foreach (IType constraint in this.DirectBaseTypes) {
if (constraint.Kind == TypeKind.Class) {
classTypeConstraints.Add(constraint);
} else if (constraint.Kind == TypeKind.TypeParameter) {
IType baseClass = ((ITypeParameter)constraint).EffectiveBaseClass;
if (baseClass.Kind == TypeKind.Class)
classTypeConstraints.Add(baseClass);
}
}
if (classTypeConstraints.Count == 0)
return this.Compilation.FindType(KnownTypeCode.Object);
// Find the derived-most type in the resulting set:
IType result = classTypeConstraints[0];
for (int i = 1; i < classTypeConstraints.Count; i++) {
if (classTypeConstraints[i].GetDefinition().IsDerivedFrom(result.GetDefinition()))
result = classTypeConstraints[i];
if (HasValueTypeConstraint)
return this.Compilation.FindType(KnownTypeCode.ValueType);
List<IType> classTypeConstraints = new List<IType>();
foreach (IType constraint in this.DirectBaseTypes) {
if (constraint.Kind == TypeKind.Class) {
classTypeConstraints.Add(constraint);
} else if (constraint.Kind == TypeKind.TypeParameter) {
IType baseClass = ((ITypeParameter)constraint).EffectiveBaseClass;
if (baseClass.Kind == TypeKind.Class)
classTypeConstraints.Add(baseClass);
}
return result;
}
if (classTypeConstraints.Count == 0)
return this.Compilation.FindType(KnownTypeCode.Object);
// Find the derived-most type in the resulting set:
IType result = classTypeConstraints[0];
for (int i = 1; i < classTypeConstraints.Count; i++) {
if (classTypeConstraints[i].GetDefinition().IsDerivedFrom(result.GetDefinition()))
result = classTypeConstraints[i];
}
return result;
}
public IList<IType> EffectiveInterfaceSet {
ICollection<IType> effectiveInterfaceSet;
public ICollection<IType> EffectiveInterfaceSet {
get {
throw new NotImplementedException();
var result = LazyInit.VolatileRead(ref effectiveInterfaceSet);
if (result != null) {
return result;
} else {
// protect against cyclic type parameters
using (var busyLock = BusyManager.Enter(this)) {
if (!busyLock.Success)
return EmptyList<IType>.Instance; // don't cache this error
return LazyInit.GetOrSet(ref effectiveInterfaceSet, CalculateEffectiveInterfaceSet());
}
}
}
}
ICollection<IType> CalculateEffectiveInterfaceSet()
{
HashSet<IType> result = new HashSet<IType>();
foreach (IType constraint in this.DirectBaseTypes) {
if (constraint.Kind == TypeKind.Interface) {
result.Add(constraint);
} else if (constraint.Kind == TypeKind.TypeParameter) {
result.UnionWith(((ITypeParameter)constraint).EffectiveInterfaceSet);
}
}
return result;
}
public abstract bool HasDefaultConstructorConstraint { get; }

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs

@ -189,7 +189,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -189,7 +189,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
get { return SpecialType.UnknownType; }
}
IList<IType> ITypeParameter.EffectiveInterfaceSet {
ICollection<IType> ITypeParameter.EffectiveInterfaceSet {
get { return EmptyList<IType>.Instance; }
}

Loading…
Cancel
Save