1
ļ»æ// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
20
using System.Collections.Generic;
22
using ICSharpCode.NRefactory.Utils;
24
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
27
/// Provides helper methods for implementing GetMembers() on IType-implementations.
28
/// Note: GetMembersHelper will recursively call back into IType.GetMembers(), but only with
29
/// both GetMemberOptions.IgnoreInheritedMembers and GetMemberOptions.ReturnMemberDefinitions set,
30
/// and only the 'simple' overloads (not taking type arguments).
32
/// Ensure that your IType implementation does not use the GetMembersHelper if both flags are set,
33
/// otherwise you'll get a StackOverflowException!
35
static class GetMembersHelper
37
#region GetNestedTypes
38
public static IEnumerable<IType> GetNestedTypes(IType type, Predicate<ITypeDefinition> filter, GetMemberOptions options)
40
return GetNestedTypes(type, null, filter, options);
43
public static IEnumerable<IType> GetNestedTypes(IType type, IList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)
45
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
46
return GetNestedTypesImpl(type, nestedTypeArguments, filter, options);
48
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetNestedTypesImpl(t, nestedTypeArguments, filter, options));
52
static IEnumerable<IType> GetNestedTypesImpl(IType outerType, IList<IType> nestedTypeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)
54
ITypeDefinition outerTypeDef = outerType.GetDefinition();
55
if (outerTypeDef == null)
58
int outerTypeParameterCount = outerTypeDef.TypeParameterCount;
59
ParameterizedType pt = outerType as ParameterizedType;
60
foreach (ITypeDefinition nestedType in outerTypeDef.NestedTypes) {
61
int totalTypeParameterCount = nestedType.TypeParameterCount;
62
if (nestedTypeArguments != null) {
63
if (totalTypeParameterCount - outerTypeParameterCount != nestedTypeArguments.Count)
66
if (!(filter == null || filter(nestedType)))
69
if (totalTypeParameterCount == 0 || (options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
70
yield return nestedType;
72
// We need to parameterize the nested type
73
IType[] newTypeArguments = new IType[totalTypeParameterCount];
74
for (int i = 0; i < outerTypeParameterCount; i++) {
75
newTypeArguments[i] = pt != null ? pt.GetTypeArgument(i) : outerTypeDef.TypeParameters[i];
77
for (int i = outerTypeParameterCount; i < totalTypeParameterCount; i++) {
78
if (nestedTypeArguments != null)
79
newTypeArguments[i] = nestedTypeArguments[i - outerTypeParameterCount];
81
newTypeArguments[i] = SpecialType.UnboundTypeArgument;
83
yield return new ParameterizedType(nestedType, newTypeArguments);
90
public static IEnumerable<IMethod> GetMethods(IType type, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
92
return GetMethods(type, null, filter, options);
95
public static IEnumerable<IMethod> GetMethods(IType type, IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
97
if (typeArguments != null && typeArguments.Count > 0) {
98
filter = FilterTypeParameterCount(typeArguments.Count).And(filter);
101
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
102
return GetMethodsImpl(type, typeArguments, filter, options);
104
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetMethodsImpl(t, typeArguments, filter, options));
108
static Predicate<IUnresolvedMethod> FilterTypeParameterCount(int expectedTypeParameterCount)
110
return m => m.TypeParameters.Count == expectedTypeParameterCount;
113
const GetMemberOptions declaredMembers = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
115
static IEnumerable<IMethod> GetMethodsImpl(IType baseType, IList<IType> methodTypeArguments, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
117
IEnumerable<IMethod> declaredMethods = baseType.GetMethods(filter, options | declaredMembers);
119
ParameterizedType pt = baseType as ParameterizedType;
120
if ((options & GetMemberOptions.ReturnMemberDefinitions) == 0
121
&& (pt != null || (methodTypeArguments != null && methodTypeArguments.Count > 0)))
123
TypeParameterSubstitution substitution = null;
124
foreach (IMethod m in declaredMethods) {
125
if (methodTypeArguments != null && methodTypeArguments.Count > 0) {
126
if (m.TypeParameters.Count != methodTypeArguments.Count)
129
if (substitution == null) {
131
substitution = pt.GetSubstitution(methodTypeArguments);
133
substitution = new TypeParameterSubstitution(null, methodTypeArguments);
135
yield return new SpecializedMethod(m, substitution);
138
foreach (IMethod m in declaredMethods) {
145
#region GetConstructors
146
public static IEnumerable<IMethod> GetConstructors(IType type, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
148
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
149
return GetConstructorsImpl(type, filter, options);
151
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetConstructorsImpl(t, filter, options));
155
static IEnumerable<IMethod> GetConstructorsImpl(IType baseType, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
157
IEnumerable<IMethod> declaredCtors = baseType.GetConstructors(filter, options | declaredMembers);
158
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
159
return declaredCtors;
162
ParameterizedType pt = baseType as ParameterizedType;
164
var substitution = pt.GetSubstitution();
165
return declaredCtors.Select(m => new SpecializedMethod(m, substitution) { DeclaringType = pt });
167
return declaredCtors;
172
#region GetProperties
173
public static IEnumerable<IProperty> GetProperties(IType type, Predicate<IUnresolvedProperty> filter, GetMemberOptions options)
175
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
176
return GetPropertiesImpl(type, filter, options);
178
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetPropertiesImpl(t, filter, options));
182
static IEnumerable<IProperty> GetPropertiesImpl(IType baseType, Predicate<IUnresolvedProperty> filter, GetMemberOptions options)
184
IEnumerable<IProperty> declaredProperties = baseType.GetProperties(filter, options | declaredMembers);
185
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
186
return declaredProperties;
189
ParameterizedType pt = baseType as ParameterizedType;
191
var substitution = pt.GetSubstitution();
192
return declaredProperties.Select(m => new SpecializedProperty(m, substitution) { DeclaringType = pt });
194
return declaredProperties;
200
public static IEnumerable<IField> GetFields(IType type, Predicate<IUnresolvedField> filter, GetMemberOptions options)
202
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
203
return GetFieldsImpl(type, filter, options);
205
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetFieldsImpl(t, filter, options));
209
static IEnumerable<IField> GetFieldsImpl(IType baseType, Predicate<IUnresolvedField> filter, GetMemberOptions options)
211
IEnumerable<IField> declaredFields = baseType.GetFields(filter, options | declaredMembers);
212
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
213
return declaredFields;
216
ParameterizedType pt = baseType as ParameterizedType;
218
var substitution = pt.GetSubstitution();
219
return declaredFields.Select(m => new SpecializedField(m, substitution) { DeclaringType = pt });
221
return declaredFields;
227
public static IEnumerable<IEvent> GetEvents(IType type, Predicate<IUnresolvedEvent> filter, GetMemberOptions options)
229
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
230
return GetEventsImpl(type, filter, options);
232
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetEventsImpl(t, filter, options));
236
static IEnumerable<IEvent> GetEventsImpl(IType baseType, Predicate<IUnresolvedEvent> filter, GetMemberOptions options)
238
IEnumerable<IEvent> declaredEvents = baseType.GetEvents(filter, options | declaredMembers);
239
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
240
return declaredEvents;
243
ParameterizedType pt = baseType as ParameterizedType;
245
var substitution = pt.GetSubstitution();
246
return declaredEvents.Select(m => new SpecializedEvent(m, substitution) { DeclaringType = pt });
248
return declaredEvents;
254
public static IEnumerable<IMember> GetMembers(IType type, Predicate<IUnresolvedMember> filter, GetMemberOptions options)
256
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
257
return GetMembersImpl(type, filter, options);
259
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetMembersImpl(t, filter, options));
263
static IEnumerable<IMember> GetMembersImpl(IType baseType, Predicate<IUnresolvedMember> filter, GetMemberOptions options)
265
foreach (var m in GetMethodsImpl(baseType, null, filter, options))
267
foreach (var m in GetPropertiesImpl(baseType, filter, options))
269
foreach (var m in GetFieldsImpl(baseType, filter, options))
271
foreach (var m in GetEventsImpl(baseType, filter, options))