Browse Source

Re-implemented IType.GetMembers() to avoid redundant specialization.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
811784e303
  1. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  2. 40
      ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs
  3. 74
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  4. 60
      ICSharpCode.NRefactory/TypeSystem/Implementation/BaseTypeCollector.cs
  5. 145
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs
  6. 31
      ICSharpCode.NRefactory/TypeSystem/IntersectionType.cs
  7. 237
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -230,6 +230,7 @@ @@ -230,6 +230,7 @@
<Compile Include="TypeSystem\Implementation\AbstractFreezable.cs" />
<Compile Include="TypeSystem\Implementation\AbstractMember.cs" />
<Compile Include="TypeSystem\Implementation\AbstractType.cs" />
<Compile Include="TypeSystem\Implementation\BaseTypeCollector.cs" />
<Compile Include="TypeSystem\Implementation\DefaultAccessor.cs" />
<Compile Include="TypeSystem\Implementation\DefaultAttribute.cs" />
<Compile Include="TypeSystem\Implementation\DefaultEvent.cs" />

40
ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs

@ -26,35 +26,23 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -26,35 +26,23 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </remarks>
public static IEnumerable<IType> GetAllBaseTypes(this IType type, ITypeResolveContext context)
{
List<IType> output = new List<IType>();
Stack<ITypeDefinition> activeTypeDefinitions = new Stack<ITypeDefinition>();
CollectAllBaseTypes(type, context, activeTypeDefinitions, output);
return output;
BaseTypeCollector collector = new BaseTypeCollector(context);
collector.CollectBaseTypes(type);
return collector;
}
static void CollectAllBaseTypes(IType type, ITypeResolveContext context, Stack<ITypeDefinition> activeTypeDefinitions, List<IType> output)
/// <summary>
/// Gets the non-interface base types.
/// </summary>
/// <remarks>
/// When <paramref name="type"/> is an interface, this method will also return base interfaces.
/// </remarks>
public static IEnumerable<IType> GetNonInterfaceBaseTypes(this IType type, ITypeResolveContext context)
{
ITypeDefinition def = type.GetDefinition();
if (def != null) {
// Maintain a stack of currently active type definitions, and avoid having one definition
// multiple times on that stack.
// This is necessary to ensure the output is finite in the presence of cyclic inheritance:
// class C<X> : C<C<X>> {} would not be caught by the 'no duplicate output' check, yet would
// produce infinite output.
if (activeTypeDefinitions.Contains(def))
return;
activeTypeDefinitions.Push(def);
}
// 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)
if (!output.Contains(type)) {
output.Add(type);
foreach (IType baseType in type.GetBaseTypes(context)) {
CollectAllBaseTypes(baseType, context, activeTypeDefinitions, output);
}
}
if (def != null)
activeTypeDefinitions.Pop();
BaseTypeCollector collector = new BaseTypeCollector(context);
collector.SkipImplementedInterfaces = true;
collector.CollectBaseTypes(type);
return collector;
}
#endregion

74
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -61,44 +61,96 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -61,44 +61,96 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <summary>
/// Gets the direct base types.
/// </summary>
/// <param name="context">The context used for resolving type references</param>
/// <returns>Returns the direct base types including interfaces</returns>
IEnumerable<IType> GetBaseTypes(ITypeResolveContext context);
/// <summary>
/// Gets inner classes (including inherited inner classes).
/// </summary>
/// <param name="context">The context used for resolving type references</param>
/// <param name="filter">The filter used to select which types to return.
/// The filter is tested on the unparameterized types.</param>
/// <remarks>
/// If this type is parameterized, the nested type will also be parameterized.
/// Any additional type parameters on the nested type will be parameterized with the
/// corresponding ITypeParameter.
/// </remarks>
IEnumerable<IType> GetNestedTypes(ITypeResolveContext context, Predicate<ITypeDefinition> filter = null);
/// <summary>
/// Gets all methods that can be called on this return type.
/// Gets all instance constructors for this type.
/// </summary>
/// <remarks>The list does not include constructors.</remarks>
IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null);
/// <param name="context">The context used for resolving type references</param>
/// <param name="filter">The filter used to select which constructors to return.
/// The filter is tested on the original method definitions (before specialization).</param>
/// <remarks>
/// This list does not include constructors in base classes or static constructors.
/// For methods on parameterized types, type substitution will be performed on the method signature,
/// and the appriopriate <see cref="SpecializedMethod"/> will be returned.
/// </remarks>
IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null);
/// <summary>
/// Gets all instance constructors for this type.
/// Gets all methods that can be called on this type.
/// </summary>
/// <remarks>This list does not include constructors in base classes or static constructors.</remarks>
IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null);
/// <param name="context">The context used for resolving type references</param>
/// <param name="filter">The filter used to select which methods to return.
/// The filter is tested on the original method definitions (before specialization).</param>
/// <remarks>
/// The list does not include constructors.
/// For methods on parameterized types, type substitution will be performed on the method signature,
/// and the appriopriate <see cref="SpecializedMethod"/> will be returned.
/// </remarks>
IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null);
/// <summary>
/// Gets all properties that can be called on this return type.
/// Gets all properties that can be called on this type.
/// </summary>
/// <param name="context">The context used for resolving type references</param>
/// <param name="filter">The filter used to select which properties to return.
/// The filter is tested on the original property definitions (before specialization).</param>
/// <remarks>
/// For properties on parameterized types, type substitution will be performed on the property signature,
/// and the appriopriate <see cref="SpecializedProperty"/> will be returned.
/// </remarks>
IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null);
/// <summary>
/// Gets all fields that can be called on this return type.
/// Gets all fields that can be accessed on this type.
/// </summary>
/// <param name="context">The context used for resolving type references</param>
/// <param name="filter">The filter used to select which constructors to return.
/// The filter is tested on the original field definitions (before specialization).</param>
/// <remarks>
/// For fields on parameterized types, type substitution will be performed on the field's return type,
/// and the appriopriate <see cref="SpecializedField"/> will be returned.
/// </remarks>
IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null);
/// <summary>
/// Gets all events that can be called on this return type.
/// Gets all events that can be accessed on this type.
/// </summary>
/// <param name="context">The context used for resolving type references</param>
/// <param name="filter">The filter used to select which events to return.
/// The filter is tested on the original event definitions (before specialization).</param>
/// <remarks>
/// For fields on parameterized types, type substitution will be performed on the event's return type,
/// and the appriopriate <see cref="SpecializedEvent"/> will be returned.
/// </remarks>
IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null);
/// <summary>
/// Gets all members that can be called on this return type.
/// This is the union of GetFields(),GetProperties(),GetMethods() and GetEvents(). This does not include constructors.
/// Gets all members that can be called on this type.
/// </summary>
/// <param name="context">The context used for resolving type references</param>
/// <param name="filter">The filter used to select which members to return.
/// The filter is tested on the original member definitions (before specialization).</param>
/// <remarks>
/// The resulting list is the union of GetFields(), GetProperties(), GetMethods() and GetEvents().
/// It does not include constructors.
/// For parameterized types, type substitution will be performed.
/// </remarks>
IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null);
}

60
ICSharpCode.NRefactory/TypeSystem/Implementation/BaseTypeCollector.cs

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// Helper class for the GetAllBaseTypes() implementation.
/// </summary>
sealed class BaseTypeCollector : List<IType>
{
readonly ITypeResolveContext context;
readonly Stack<ITypeDefinition> activeTypeDefinitions = new Stack<ITypeDefinition>();
/// <summary>
/// If this option is enabled, the list will not contain interfaces when retrieving the base types
/// of a class.
/// </summary>
internal bool SkipImplementedInterfaces;
public BaseTypeCollector(ITypeResolveContext context)
{
this.context = context;
}
public void CollectBaseTypes(IType type)
{
ITypeDefinition def = type.GetDefinition();
if (def != null) {
// Maintain a stack of currently active type definitions, and avoid having one definition
// multiple times on that stack.
// This is necessary to ensure the output is finite in the presence of cyclic inheritance:
// class C<X> : C<C<X>> {} would not be caught by the 'no duplicate output' check, yet would
// produce infinite output.
if (activeTypeDefinitions.Contains(def))
return;
activeTypeDefinitions.Push(def);
}
// 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)
if (!this.Contains(type)) {
this.Add(type);
foreach (IType baseType in type.GetBaseTypes(context)) {
if (SkipImplementedInterfaces && def != null && def.ClassType != ClassType.Interface) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef != null && baseTypeDef.ClassType == ClassType.Interface) {
// skip the interface
continue;
}
}
CollectBaseTypes(baseType);
}
}
if (def != null)
activeTypeDefinitions.Pop();
}
}
}

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

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
@ -434,27 +433,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -434,27 +433,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public virtual IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetMethods(context, filter);
List<IMethod> methods = new List<IMethod>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
int baseCount = 0;
foreach (var baseType in GetBaseTypes(context)) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) {
methods.AddRange(baseType.GetMethods(context, filter));
baseCount++;
}
}
if (baseCount > 1)
RemoveDuplicates(methods);
AddFilteredRange(methods, this.Methods.Where(m => !m.IsConstructor), filter);
}
}
return methods;
return ParameterizedType.GetMethods(this, context, filter);
}
public virtual IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null)
@ -464,7 +443,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -464,7 +443,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return compound.GetConstructors(context, filter);
List<IMethod> methods = new List<IMethod>();
AddFilteredRange(methods, this.Methods.Where(m => m.IsConstructor && !m.IsStatic), filter);
foreach (IMethod m in this.Methods) {
if (m.IsConstructor && !m.IsStatic) {
if (filter == null || filter(m))
methods.Add(m);
}
}
if (this.AddDefaultConstructorIfRequired) {
if (this.ClassType == ClassType.Class && methods.Count == 0
@ -480,129 +464,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -480,129 +464,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public virtual IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetProperties(context, filter);
List<IProperty> properties = new List<IProperty>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
int baseCount = 0;
foreach (var baseType in GetBaseTypes(context)) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) {
properties.AddRange(baseType.GetProperties(context, filter));
baseCount++;
}
}
if (baseCount > 1)
RemoveDuplicates(properties);
AddFilteredRange(properties, this.Properties, filter);
}
}
return properties;
return ParameterizedType.GetProperties(this, context, filter);
}
public virtual IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetFields(context, filter);
List<IField> fields = new List<IField>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
int baseCount = 0;
foreach (var baseType in GetBaseTypes(context)) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) {
fields.AddRange(baseType.GetFields(context, filter));
baseCount++;
}
}
if (baseCount > 1)
RemoveDuplicates(fields);
AddFilteredRange(fields, this.Fields, filter);
}
}
return fields;
return ParameterizedType.GetFields(this, context, filter);
}
public virtual IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetEvents(context, filter);
List<IEvent> events = new List<IEvent>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
int baseCount = 0;
foreach (var baseType in GetBaseTypes(context)) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) {
events.AddRange(baseType.GetEvents(context, filter));
baseCount++;
}
}
if (baseCount > 1)
RemoveDuplicates(events);
AddFilteredRange(events, this.Events, filter);
}
}
return events;
return ParameterizedType.GetEvents(this, context, filter);
}
public virtual IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null)
{
ITypeDefinition compound = GetCompoundClass();
if (compound != this)
return compound.GetMembers(context, filter);
List<IMember> members = new List<IMember>();
using (var busyLock = BusyManager.Enter(this)) {
if (busyLock.Success) {
int baseCount = 0;
foreach (var baseType in GetBaseTypes(context)) {
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef != null && (baseTypeDef.ClassType != ClassType.Interface || this.ClassType == ClassType.Interface)) {
members.AddRange(baseType.GetMembers(context, filter));
baseCount++;
}
}
if (baseCount > 1)
RemoveDuplicates(members);
AddFilteredRange(members, this.Methods.Where(m => !m.IsConstructor), filter);
AddFilteredRange(members, this.Properties, filter);
AddFilteredRange(members, this.Fields, filter);
AddFilteredRange(members, this.Events, filter);
}
}
return members;
}
static void AddFilteredRange<T>(List<T> targetList, IEnumerable<T> sourceList, Predicate<T> filter) where T : class
{
if (filter == null) {
targetList.AddRange(sourceList);
} else {
foreach (T element in sourceList) {
if (filter(element))
targetList.Add(element);
}
}
}
/// <summary>
/// Removes duplicate members from the list.
/// This is necessary when the same member can be inherited twice due to multiple inheritance.
/// </summary>
static void RemoveDuplicates<T>(List<T> list) where T : class
{
if (list.Count > 1) {
HashSet<T> hash = new HashSet<T>();
list.RemoveAll(m => !hash.Add(m));
}
return ParameterizedType.GetMembers(this, context, filter);
}
// we use reference equality

31
ICSharpCode.NRefactory/TypeSystem/IntersectionType.cs

@ -7,6 +7,7 @@ using System.Collections.ObjectModel; @@ -7,6 +7,7 @@ using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.TypeSystem
@ -103,33 +104,37 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -103,33 +104,37 @@ namespace ICSharpCode.NRefactory.TypeSystem
return types;
}
public override IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter)
{
filter = FilterNonStatic(filter);
return types.SelectMany(t => t.GetEvents(context, filter));
}
public override IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter)
{
filter = FilterNonStatic(filter);
return types.SelectMany(t => t.GetMethods(context, filter));
return ParameterizedType.GetMethods(this, context, FilterNonStatic(filter));
}
public override IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter)
{
filter = FilterNonStatic(filter);
return types.SelectMany(t => t.GetProperties(context, filter));
return ParameterizedType.GetProperties(this, context, FilterNonStatic(filter));
}
public override IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter)
{
filter = FilterNonStatic(filter);
return types.SelectMany(t => t.GetFields(context, filter));
return ParameterizedType.GetFields(this, context, FilterNonStatic(filter));
}
public override IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter)
{
return ParameterizedType.GetEvents(this, context, FilterNonStatic(filter));
}
public override IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter)
{
return ParameterizedType.GetMembers(this, context, FilterNonStatic(filter));
}
static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IMember
{
return member => !member.IsStatic && (filter == null || filter(member));
if (filter == null)
return member => !member.IsStatic;
else
return member => !member.IsStatic && filter(member);
}
}
}

237
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -206,11 +206,11 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -206,11 +206,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
return types;
}
public IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null)
public IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IMethod> methods = genericType.GetMethods(context, filter).ToList();
List<IMethod> methods = genericType.GetConstructors(context, filter).ToList();
for (int i = 0; i < methods.Count; i++) {
SpecializedMethod m = new SpecializedMethod(methods[i]);
m.SetDeclaringType(this);
@ -220,102 +220,191 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -220,102 +220,191 @@ namespace ICSharpCode.NRefactory.TypeSystem
return methods;
}
public IEnumerable<IMethod> GetConstructors(ITypeResolveContext context, Predicate<IMethod> filter = null)
public IEnumerable<IMethod> GetMethods(ITypeResolveContext context, Predicate<IMethod> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IMethod> methods = genericType.GetConstructors(context, filter).ToList();
for (int i = 0; i < methods.Count; i++) {
SpecializedMethod m = new SpecializedMethod(methods[i]);
m.SetDeclaringType(this);
m.SubstituteTypes(substitutionFunc);
methods[i] = m;
return GetMethods(this, context, filter);
}
internal static IEnumerable<IMethod> GetMethods(IType type, ITypeResolveContext context, Predicate<IMethod> filter)
{
Predicate<IMethod> newFilter;
if (filter == null)
newFilter = m => !m.IsConstructor;
else
newFilter = m => !m.IsConstructor && filter(m);
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetMethodsInternal(t, context, newFilter));
}
static IEnumerable<IMethod> GetMethodsInternal(IType baseType, ITypeResolveContext context, Predicate<IMethod> filter)
{
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
yield break;
baseTypeDef = baseTypeDef.GetCompoundClass();
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
Substitution substitution = null;
Func<ITypeReference, ITypeReference> substitutionFunc = null;
foreach (IMethod m in baseTypeDef.Methods) {
if (!(filter == null || filter(m)))
continue;
if (substitution == null) {
substitution = new Substitution(pt.typeArguments);
substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
}
SpecializedMethod sm = new SpecializedMethod(m);
sm.SetDeclaringType(pt);
sm.SubstituteTypes(substitutionFunc);
yield return sm;
}
} else {
foreach (IMethod m in baseTypeDef.Methods) {
if (filter == null || filter(m))
yield return m;
}
}
return methods;
}
public IEnumerable<IProperty> GetProperties(ITypeResolveContext context, Predicate<IProperty> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IProperty> properties = genericType.GetProperties(context, filter).ToList();
for (int i = 0; i < properties.Count; i++) {
SpecializedProperty p = new SpecializedProperty(properties[i]);
p.SetDeclaringType(this);
p.SubstituteTypes(substitutionFunc);
properties[i] = p;
return GetProperties(this, context, filter);
}
internal static IEnumerable<IProperty> GetProperties(IType type, ITypeResolveContext context, Predicate<IProperty> filter)
{
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetPropertiesInternal(t, context, filter));
}
static IEnumerable<IProperty> GetPropertiesInternal(IType baseType, ITypeResolveContext context, Predicate<IProperty> filter)
{
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
yield break;
baseTypeDef = baseTypeDef.GetCompoundClass();
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
Substitution substitution = null;
Func<ITypeReference, ITypeReference> substitutionFunc = null;
foreach (IProperty p in baseTypeDef.Properties) {
if (!(filter == null || filter(p)))
continue;
if (substitution == null) {
substitution = new Substitution(pt.typeArguments);
substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
}
SpecializedProperty sp = new SpecializedProperty(p);
sp.SetDeclaringType(pt);
sp.SubstituteTypes(substitutionFunc);
yield return sp;
}
} else {
foreach (IProperty p in baseTypeDef.Properties) {
if (filter == null || filter(p))
yield return p;
}
}
return properties;
}
public IEnumerable<IField> GetFields(ITypeResolveContext context, Predicate<IField> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
List<IField> fields = genericType.GetFields(context, filter).ToList();
for (int i = 0; i < fields.Count; i++) {
SpecializedField f = new SpecializedField(fields[i]);
f.SetDeclaringType(this);
f.ReturnType = f.ReturnType.Resolve(context).AcceptVisitor(substitution);
fields[i] = f;
return GetFields(this, context, filter);
}
internal static IEnumerable<IField> GetFields(IType type, ITypeResolveContext context, Predicate<IField> filter)
{
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetFieldsInternal(t, context, filter));
}
static IEnumerable<IField> GetFieldsInternal(IType baseType, ITypeResolveContext context, Predicate<IField> filter)
{
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
yield break;
baseTypeDef = baseTypeDef.GetCompoundClass();
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
Substitution substitution = null;
Func<ITypeReference, ITypeReference> substitutionFunc = null;
foreach (IField f in baseTypeDef.Fields) {
if (!(filter == null || filter(f)))
continue;
if (substitution == null) {
substitution = new Substitution(pt.typeArguments);
substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
}
SpecializedField sf = new SpecializedField(f);
sf.SetDeclaringType(pt);
sf.ReturnType = f.ReturnType.Resolve(context).AcceptVisitor(substitution);
yield return sf;
}
} else {
foreach (IField f in baseTypeDef.Fields) {
if (filter == null || filter(f))
yield return f;
}
}
return fields;
}
public IEnumerable<IEvent> GetEvents(ITypeResolveContext context, Predicate<IEvent> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
List<IEvent> events = genericType.GetEvents(context, filter).ToList();
for (int i = 0; i < events.Count; i++) {
SpecializedEvent e = new SpecializedEvent(events[i]);
e.SetDeclaringType(this);
e.ReturnType = e.ReturnType.Resolve(context).AcceptVisitor(substitution);
events[i] = e;
return GetEvents(this, context, filter);
}
internal static IEnumerable<IEvent> GetEvents(IType type, ITypeResolveContext context, Predicate<IEvent> filter)
{
return type.GetNonInterfaceBaseTypes(context).SelectMany(t => GetEventsInternal(t, context, filter));
}
static IEnumerable<IEvent> GetEventsInternal(IType baseType, ITypeResolveContext context, Predicate<IEvent> filter)
{
ITypeDefinition baseTypeDef = baseType.GetDefinition();
if (baseTypeDef == null)
yield break;
baseTypeDef = baseTypeDef.GetCompoundClass();
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
Substitution substitution = null;
Func<ITypeReference, ITypeReference> substitutionFunc = null;
foreach (IEvent e in baseTypeDef.Events) {
if (!(filter == null || filter(e)))
continue;
if (substitution == null) {
substitution = new Substitution(pt.typeArguments);
substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
}
SpecializedEvent se = new SpecializedEvent(e);
se.SetDeclaringType(pt);
se.ReturnType = e.ReturnType.Resolve(context).AcceptVisitor(substitution);
yield return se;
}
} else {
foreach (IEvent e in baseTypeDef.Events) {
if (filter == null || filter(e))
yield return e;
}
}
return events;
}
public IEnumerable<IMember> GetMembers(ITypeResolveContext context, Predicate<IMember> filter = null)
{
Substitution substitution = new Substitution(typeArguments);
Func<ITypeReference, ITypeReference> substitutionFunc = t => t.Resolve(context).AcceptVisitor(substitution);
List<IMember> members = genericType.GetMembers(context, filter).ToList();
for (int i = 0; i < members.Count; i++) {
members[i] = Specialize(members[i], substitutionFunc);
}
return members;
return GetMembers(this, context, filter);
}
IMember Specialize(IMember member, Func<ITypeReference, ITypeReference> substitution)
internal static IEnumerable<IMember> GetMembers(IType type, ITypeResolveContext context, Predicate<IMember> filter)
{
IMethod method = member as IMethod;
if (method != null) {
SpecializedMethod m = new SpecializedMethod(method);
m.SetDeclaringType(this);
m.SubstituteTypes(substitution);
return m;
}
IProperty property = member as IProperty;
if (property != null) {
SpecializedProperty p = new SpecializedProperty(property);
p.SetDeclaringType(this);
p.SubstituteTypes(substitution);
return p;
}
IField field = member as IField;
if (field != null) {
SpecializedField f = new SpecializedField(field);
f.SetDeclaringType(this);
f.ReturnType = substitution(f.ReturnType);
return f;
}
IEvent ev = member as IEvent;
if (ev != null) {
SpecializedEvent e = new SpecializedEvent(ev);
e.SetDeclaringType(this);
e.ReturnType = substitution(e.ReturnType);
return e;
}
throw new ArgumentException("Unknown member");
Predicate<IMethod> methodFilter;
if (filter == null)
methodFilter = m => !m.IsConstructor;
else
methodFilter = m => !m.IsConstructor && filter(m);
return type.GetNonInterfaceBaseTypes(context).SelectMany(
delegate (IType t) {
IEnumerable<IMember> members = GetMethodsInternal(t, context, methodFilter);
members = members.Concat(GetPropertiesInternal(t, context, filter));
members = members.Concat(GetFieldsInternal(t, context, filter));
members = members.Concat(GetEventsInternal(t, context, filter));
return members;
});
}
public override bool Equals(object obj)

Loading…
Cancel
Save