~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
 
2
// 
 
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:
 
8
// 
 
9
// The above copyright notice and this permission notice shall be included in all copies or
 
10
// substantial portions of the Software.
 
11
// 
 
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.
 
18
 
 
19
using System;
 
20
using System.Collections.Generic;
 
21
using System.Globalization;
 
22
 
 
23
using ICSharpCode.NRefactory.Utils;
 
24
 
 
25
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
 
26
{
 
27
        public abstract class AbstractTypeParameter : ITypeParameter, ICompilationProvider
 
28
        {
 
29
                readonly ICompilation compilation;
 
30
                readonly EntityType ownerType;
 
31
                readonly IEntity owner;
 
32
                readonly int index;
 
33
                readonly string name;
 
34
                readonly IList<IAttribute> attributes;
 
35
                readonly DomRegion region;
 
36
                readonly VarianceModifier variance;
 
37
                
 
38
                protected AbstractTypeParameter(IEntity owner, int index, string name, VarianceModifier variance, IList<IAttribute> attributes, DomRegion region)
 
39
                {
 
40
                        if (owner == null)
 
41
                                throw new ArgumentNullException("owner");
 
42
                        this.owner = owner;
 
43
                        this.compilation = owner.Compilation;
 
44
                        this.ownerType = owner.EntityType;
 
45
                        this.index = index;
 
46
                        this.name = name ?? ((this.OwnerType == EntityType.Method ? "!!" : "!") + index.ToString(CultureInfo.InvariantCulture));
 
47
                        this.attributes = attributes ?? EmptyList<IAttribute>.Instance;
 
48
                        this.region = region;
 
49
                        this.variance = variance;
 
50
                }
 
51
                
 
52
                protected AbstractTypeParameter(ICompilation compilation, EntityType ownerType, int index, string name, VarianceModifier variance, IList<IAttribute> attributes, DomRegion region)
 
53
                {
 
54
                        if (compilation == null)
 
55
                                throw new ArgumentNullException("compilation");
 
56
                        this.compilation = compilation;
 
57
                        this.ownerType = ownerType;
 
58
                        this.index = index;
 
59
                        this.name = name ?? ((this.OwnerType == EntityType.Method ? "!!" : "!") + index.ToString(CultureInfo.InvariantCulture));
 
60
                        this.attributes = attributes ?? EmptyList<IAttribute>.Instance;
 
61
                        this.region = region;
 
62
                        this.variance = variance;
 
63
                }
 
64
                
 
65
                public EntityType OwnerType {
 
66
                        get { return ownerType; }
 
67
                }
 
68
                
 
69
                public IEntity Owner {
 
70
                        get { return owner; }
 
71
                }
 
72
                
 
73
                public int Index {
 
74
                        get { return index; }
 
75
                }
 
76
                
 
77
                public IList<IAttribute> Attributes {
 
78
                        get { return attributes; }
 
79
                }
 
80
                
 
81
                public VarianceModifier Variance {
 
82
                        get { return variance; }
 
83
                }
 
84
                
 
85
                public DomRegion Region {
 
86
                        get { return region; }
 
87
                }
 
88
                
 
89
                public ICompilation Compilation {
 
90
                        get { return compilation; }
 
91
                }
 
92
                
 
93
                volatile IType effectiveBaseClass;
 
94
                
 
95
                public IType EffectiveBaseClass {
 
96
                        get {
 
97
                                if (effectiveBaseClass == null) {
 
98
                                        // protect against cyclic type parameters
 
99
                                        using (var busyLock = BusyManager.Enter(this)) {
 
100
                                                if (!busyLock.Success)
 
101
                                                        return SpecialType.UnknownType; // don't cache this error
 
102
                                                effectiveBaseClass = CalculateEffectiveBaseClass();
 
103
                                        }
 
104
                                }
 
105
                                return effectiveBaseClass;
 
106
                        }
 
107
                }
 
108
                
 
109
                IType CalculateEffectiveBaseClass()
 
110
                {
 
111
                        if (HasValueTypeConstraint)
 
112
                                return this.Compilation.FindType(KnownTypeCode.ValueType);
 
113
                        
 
114
                        List<IType> classTypeConstraints = new List<IType>();
 
115
                        foreach (IType constraint in this.DirectBaseTypes) {
 
116
                                if (constraint.Kind == TypeKind.Class) {
 
117
                                        classTypeConstraints.Add(constraint);
 
118
                                } else if (constraint.Kind == TypeKind.TypeParameter) {
 
119
                                        IType baseClass = ((ITypeParameter)constraint).EffectiveBaseClass;
 
120
                                        if (baseClass.Kind == TypeKind.Class)
 
121
                                                classTypeConstraints.Add(baseClass);
 
122
                                }
 
123
                        }
 
124
                        if (classTypeConstraints.Count == 0)
 
125
                                return this.Compilation.FindType(KnownTypeCode.Object);
 
126
                        // Find the derived-most type in the resulting set:
 
127
                        IType result = classTypeConstraints[0];
 
128
                        for (int i = 1; i < classTypeConstraints.Count; i++) {
 
129
                                if (classTypeConstraints[i].GetDefinition().IsDerivedFrom(result.GetDefinition()))
 
130
                                        result = classTypeConstraints[i];
 
131
                        }
 
132
                        return result;
 
133
                }
 
134
                
 
135
                ICollection<IType> effectiveInterfaceSet;
 
136
                
 
137
                public ICollection<IType> EffectiveInterfaceSet {
 
138
                        get {
 
139
                                var result = LazyInit.VolatileRead(ref effectiveInterfaceSet);
 
140
                                if (result != null) {
 
141
                                        return result;
 
142
                                } else {
 
143
                                        // protect against cyclic type parameters
 
144
                                        using (var busyLock = BusyManager.Enter(this)) {
 
145
                                                if (!busyLock.Success)
 
146
                                                        return EmptyList<IType>.Instance; // don't cache this error
 
147
                                                return LazyInit.GetOrSet(ref effectiveInterfaceSet, CalculateEffectiveInterfaceSet());
 
148
                                        }
 
149
                                }
 
150
                        }
 
151
                }
 
152
                
 
153
                ICollection<IType> CalculateEffectiveInterfaceSet()
 
154
                {
 
155
                        HashSet<IType> result = new HashSet<IType>();
 
156
                        foreach (IType constraint in this.DirectBaseTypes) {
 
157
                                if (constraint.Kind == TypeKind.Interface) {
 
158
                                        result.Add(constraint);
 
159
                                } else if (constraint.Kind == TypeKind.TypeParameter) {
 
160
                                        result.UnionWith(((ITypeParameter)constraint).EffectiveInterfaceSet);
 
161
                                }
 
162
                        }
 
163
                        return result;
 
164
                }
 
165
                
 
166
                public abstract bool HasDefaultConstructorConstraint { get; }
 
167
                public abstract bool HasReferenceTypeConstraint { get; }
 
168
                public abstract bool HasValueTypeConstraint { get; }
 
169
                
 
170
                public TypeKind Kind {
 
171
                        get { return TypeKind.TypeParameter; }
 
172
                }
 
173
                
 
174
                public bool? IsReferenceType {
 
175
                        get {
 
176
                                if (this.HasValueTypeConstraint)
 
177
                                        return false;
 
178
                                if (this.HasReferenceTypeConstraint)
 
179
                                        return true;
 
180
                                
 
181
                                // A type parameter is known to be a reference type if it has the reference type constraint
 
182
                                // or its effective base class is not object or System.ValueType.
 
183
                                IType effectiveBaseClass = this.EffectiveBaseClass;
 
184
                                if (effectiveBaseClass.Kind == TypeKind.Class || effectiveBaseClass.Kind == TypeKind.Delegate) {
 
185
                                        ITypeDefinition effectiveBaseClassDef = effectiveBaseClass.GetDefinition();
 
186
                                        if (effectiveBaseClassDef != null) {
 
187
                                                switch (effectiveBaseClassDef.KnownTypeCode) {
 
188
                                                        case KnownTypeCode.Object:
 
189
                                                        case KnownTypeCode.ValueType:
 
190
                                                        case KnownTypeCode.Enum:
 
191
                                                                return null;
 
192
                                                }
 
193
                                        }
 
194
                                        return true;
 
195
                                } else if (effectiveBaseClass.Kind == TypeKind.Struct || effectiveBaseClass.Kind == TypeKind.Enum) {
 
196
                                        return false;
 
197
                                }
 
198
                                return null;
 
199
                        }
 
200
                }
 
201
                
 
202
                IType IType.DeclaringType {
 
203
                        get { return null; }
 
204
                }
 
205
                
 
206
                int IType.TypeParameterCount {
 
207
                        get { return 0; }
 
208
                }
 
209
 
 
210
                bool IType.IsParameterized { 
 
211
                        get { return false; }
 
212
                }
 
213
 
 
214
                readonly static IList<IType> emptyTypeArguments = new IType[0];
 
215
                IList<IType> IType.TypeArguments {
 
216
                        get { return emptyTypeArguments; }
 
217
                }
 
218
 
 
219
                public abstract IEnumerable<IType> DirectBaseTypes { get; }
 
220
                
 
221
                public string Name {
 
222
                        get { return name; }
 
223
                }
 
224
                
 
225
                string INamedElement.Namespace {
 
226
                        get { return string.Empty; }
 
227
                }
 
228
                
 
229
                string INamedElement.FullName {
 
230
                        get { return name; }
 
231
                }
 
232
                
 
233
                public string ReflectionName {
 
234
                        get {
 
235
                                return (this.OwnerType == EntityType.Method ? "``" : "`") + index.ToString(CultureInfo.InvariantCulture);
 
236
                        }
 
237
                }
 
238
                
 
239
                ITypeDefinition IType.GetDefinition()
 
240
                {
 
241
                        return null;
 
242
                }
 
243
                
 
244
                public IType AcceptVisitor(TypeVisitor visitor)
 
245
                {
 
246
                        return visitor.VisitTypeParameter(this);
 
247
                }
 
248
                
 
249
                public IType VisitChildren(TypeVisitor visitor)
 
250
                {
 
251
                        return this;
 
252
                }
 
253
                
 
254
                public ITypeReference ToTypeReference()
 
255
                {
 
256
                        return TypeParameterReference.Create(this.OwnerType, this.Index);
 
257
                }
 
258
                
 
259
                IEnumerable<IType> IType.GetNestedTypes(Predicate<ITypeDefinition> filter, GetMemberOptions options)
 
260
                {
 
261
                        return EmptyList<IType>.Instance;
 
262
                }
 
263
                
 
264
                IEnumerable<IType> IType.GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter, GetMemberOptions options)
 
265
                {
 
266
                        return EmptyList<IType>.Instance;
 
267
                }
 
268
                
 
269
                public IEnumerable<IMethod> GetConstructors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)
 
270
                {
 
271
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
 
272
                                if (this.HasDefaultConstructorConstraint || this.HasValueTypeConstraint) {
 
273
                                        if (filter == null || filter(DefaultUnresolvedMethod.DummyConstructor)) {
 
274
                                                return new [] { DefaultResolvedMethod.GetDummyConstructor(compilation, this) };
 
275
                                        }
 
276
                                }
 
277
                                return EmptyList<IMethod>.Instance;
 
278
                        } else {
 
279
                                return GetMembersHelper.GetConstructors(this, filter, options);
 
280
                        }
 
281
                }
 
282
                
 
283
                public IEnumerable<IMethod> GetMethods(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
284
                {
 
285
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
 
286
                                return EmptyList<IMethod>.Instance;
 
287
                        else
 
288
                                return GetMembersHelper.GetMethods(this, FilterNonStatic(filter), options);
 
289
                }
 
290
                
 
291
                public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
292
                {
 
293
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
 
294
                                return EmptyList<IMethod>.Instance;
 
295
                        else
 
296
                                return GetMembersHelper.GetMethods(this, typeArguments, FilterNonStatic(filter), options);
 
297
                }
 
298
                
 
299
                public IEnumerable<IProperty> GetProperties(Predicate<IUnresolvedProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
300
                {
 
301
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
 
302
                                return EmptyList<IProperty>.Instance;
 
303
                        else
 
304
                                return GetMembersHelper.GetProperties(this, FilterNonStatic(filter), options);
 
305
                }
 
306
                
 
307
                public IEnumerable<IField> GetFields(Predicate<IUnresolvedField> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
308
                {
 
309
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
 
310
                                return EmptyList<IField>.Instance;
 
311
                        else
 
312
                                return GetMembersHelper.GetFields(this, FilterNonStatic(filter), options);
 
313
                }
 
314
                
 
315
                public IEnumerable<IEvent> GetEvents(Predicate<IUnresolvedEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
316
                {
 
317
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
 
318
                                return EmptyList<IEvent>.Instance;
 
319
                        else
 
320
                                return GetMembersHelper.GetEvents(this, FilterNonStatic(filter), options);
 
321
                }
 
322
                
 
323
                public IEnumerable<IMember> GetMembers(Predicate<IUnresolvedMember> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
324
                {
 
325
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
 
326
                                return EmptyList<IMember>.Instance;
 
327
                        else
 
328
                                return GetMembersHelper.GetMembers(this, FilterNonStatic(filter), options);
 
329
                }
 
330
                
 
331
                public IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
332
                {
 
333
                        if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
 
334
                                return EmptyList<IMethod>.Instance;
 
335
                        else
 
336
                                return GetMembersHelper.GetAccessors(this, FilterNonStatic(filter), options);
 
337
                }
 
338
 
 
339
                public TypeParameterSubstitution GetSubstitution()
 
340
                {
 
341
                        return TypeParameterSubstitution.Identity;
 
342
                }
 
343
                
 
344
                public TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments)
 
345
                {
 
346
                        return TypeParameterSubstitution.Identity;
 
347
                }
 
348
 
 
349
                static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IUnresolvedMember
 
350
                {
 
351
                        if (filter == null)
 
352
                                return member => !member.IsStatic;
 
353
                        else
 
354
                                return member => !member.IsStatic && filter(member);
 
355
                }
 
356
                
 
357
                public sealed override bool Equals(object obj)
 
358
                {
 
359
                        return Equals(obj as IType);
 
360
                }
 
361
                
 
362
                public override int GetHashCode()
 
363
                {
 
364
                        return base.GetHashCode();
 
365
                }
 
366
                
 
367
                public virtual bool Equals(IType other)
 
368
                {
 
369
                        return this == other; // use reference equality for type parameters
 
370
                }
 
371
                
 
372
                public override string ToString()
 
373
                {
 
374
                        return this.ReflectionName + " (owner=" + owner + ")";
 
375
                }
 
376
        }
 
377
}