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
/// <summary> /// <summary>
/// Gets the effective interface set of this type parameter. /// Gets the effective interface set of this type parameter.
/// </summary> /// </summary>
IList<IType> EffectiveInterfaceSet { get; } ICollection<IType> EffectiveInterfaceSet { get; }
/// <summary> /// <summary>
/// Gets if the type parameter has the 'new()' constraint. /// 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
public IType EffectiveBaseClass { public IType EffectiveBaseClass {
get { get {
if (effectiveBaseClass == null) if (effectiveBaseClass == null) {
effectiveBaseClass = CalculateEffectiveBaseClass(); // 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; return effectiveBaseClass;
} }
} }
IType CalculateEffectiveBaseClass() IType CalculateEffectiveBaseClass()
{ {
// protect against cyclic type parameters if (HasValueTypeConstraint)
using (var busyLock = BusyManager.Enter(this)) { return this.Compilation.FindType(KnownTypeCode.ValueType);
if (!busyLock.Success)
return SpecialType.UnknownType; List<IType> classTypeConstraints = new List<IType>();
foreach (IType constraint in this.DirectBaseTypes) {
if (HasValueTypeConstraint) if (constraint.Kind == TypeKind.Class) {
return this.Compilation.FindType(KnownTypeCode.ValueType); classTypeConstraints.Add(constraint);
} else if (constraint.Kind == TypeKind.TypeParameter) {
List<IType> classTypeConstraints = new List<IType>(); IType baseClass = ((ITypeParameter)constraint).EffectiveBaseClass;
foreach (IType constraint in this.DirectBaseTypes) { if (baseClass.Kind == TypeKind.Class)
if (constraint.Kind == TypeKind.Class) { classTypeConstraints.Add(baseClass);
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];
} }
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 { 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; } public abstract bool HasDefaultConstructorConstraint { get; }

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

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

Loading…
Cancel
Save