|
|
|
@ -94,19 +94,20 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
@@ -94,19 +94,20 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
|
|
|
|
|
|
|
|
|
|
public IType EffectiveBaseClass { |
|
|
|
|
get { |
|
|
|
|
if (effectiveBaseClass == null) |
|
|
|
|
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); |
|
|
|
|
|
|
|
|
@ -130,13 +131,37 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
@@ -130,13 +131,37 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
|
|
|
|
|
} |
|
|
|
|
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; } |
|
|
|
|
public abstract bool HasReferenceTypeConstraint { get; } |
|
|
|
|