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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory/TypeSystem/ParameterizedType.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.Collections.ObjectModel;
 
22
using System.Diagnostics;
 
23
using System.Linq;
 
24
using System.Text;
 
25
 
 
26
using ICSharpCode.NRefactory.TypeSystem.Implementation;
 
27
 
 
28
namespace ICSharpCode.NRefactory.TypeSystem
 
29
{
 
30
        /// <summary>
 
31
        /// ParameterizedType represents an instance of a generic type.
 
32
        /// Example: List&lt;string&gt;
 
33
        /// </summary>
 
34
        /// <remarks>
 
35
        /// When getting the members, this type modifies the lists so that
 
36
        /// type parameters in the signatures of the members are replaced with
 
37
        /// the type arguments.
 
38
        /// </remarks>
 
39
        [Serializable]
 
40
        public sealed class ParameterizedType : IType, ICompilationProvider
 
41
        {
 
42
                readonly ITypeDefinition genericType;
 
43
                readonly IType[] typeArguments;
 
44
                
 
45
                public ParameterizedType(ITypeDefinition genericType, IEnumerable<IType> typeArguments)
 
46
                {
 
47
                        if (genericType == null)
 
48
                                throw new ArgumentNullException("genericType");
 
49
                        if (typeArguments == null)
 
50
                                throw new ArgumentNullException("typeArguments");
 
51
                        this.genericType = genericType;
 
52
                        this.typeArguments = typeArguments.ToArray(); // copy input array to ensure it isn't modified
 
53
                        if (this.typeArguments.Length == 0)
 
54
                                throw new ArgumentException("Cannot use ParameterizedType with 0 type arguments.");
 
55
                        if (genericType.TypeParameterCount != this.typeArguments.Length)
 
56
                                throw new ArgumentException("Number of type arguments must match the type definition's number of type parameters");
 
57
                        for (int i = 0; i < this.typeArguments.Length; i++) {
 
58
                                if (this.typeArguments[i] == null)
 
59
                                        throw new ArgumentNullException("typeArguments[" + i + "]");
 
60
                                ICompilationProvider p = this.typeArguments[i] as ICompilationProvider;
 
61
                                if (p != null && p.Compilation != genericType.Compilation)
 
62
                                        throw new InvalidOperationException("Cannot parameterize a type with type arguments from a different compilation.");
 
63
                        }
 
64
                }
 
65
                
 
66
                /// <summary>
 
67
                /// Fast internal version of the constructor. (no safety checks)
 
68
                /// Keeps the array that was passed and assumes it won't be modified.
 
69
                /// </summary>
 
70
                internal ParameterizedType(ITypeDefinition genericType, IType[] typeArguments)
 
71
                {
 
72
                        Debug.Assert(genericType.TypeParameterCount == typeArguments.Length);
 
73
                        this.genericType = genericType;
 
74
                        this.typeArguments = typeArguments;
 
75
                }
 
76
                
 
77
                public TypeKind Kind {
 
78
                        get { return genericType.Kind; }
 
79
                }
 
80
                
 
81
                public ICompilation Compilation {
 
82
                        get { return genericType.Compilation; }
 
83
                }
 
84
                
 
85
                public bool? IsReferenceType {
 
86
                        get { return genericType.IsReferenceType; }
 
87
                }
 
88
                
 
89
                public IType DeclaringType {
 
90
                        get {
 
91
                                ITypeDefinition declaringTypeDef = genericType.DeclaringTypeDefinition;
 
92
                                if (declaringTypeDef != null && declaringTypeDef.TypeParameterCount > 0
 
93
                                    && declaringTypeDef.TypeParameterCount <= genericType.TypeParameterCount)
 
94
                                {
 
95
                                        IType[] newTypeArgs = new IType[declaringTypeDef.TypeParameterCount];
 
96
                                        Array.Copy(this.typeArguments, 0, newTypeArgs, 0, newTypeArgs.Length);
 
97
                                        return new ParameterizedType(declaringTypeDef, newTypeArgs);
 
98
                                }
 
99
                                return declaringTypeDef;
 
100
                        }
 
101
                }
 
102
                
 
103
                public int TypeParameterCount {
 
104
                        get { return typeArguments.Length; }
 
105
                }
 
106
                
 
107
                public string FullName {
 
108
                        get { return genericType.FullName; }
 
109
                }
 
110
                
 
111
                public string Name {
 
112
                        get { return genericType.Name; }
 
113
                }
 
114
                
 
115
                public string Namespace {
 
116
                        get { return genericType.Namespace; }
 
117
                }
 
118
                
 
119
                public string ReflectionName {
 
120
                        get {
 
121
                                StringBuilder b = new StringBuilder(genericType.ReflectionName);
 
122
                                b.Append('[');
 
123
                                for (int i = 0; i < typeArguments.Length; i++) {
 
124
                                        if (i > 0)
 
125
                                                b.Append(',');
 
126
                                        b.Append('[');
 
127
                                        b.Append(typeArguments[i].ReflectionName);
 
128
                                        b.Append(']');
 
129
                                }
 
130
                                b.Append(']');
 
131
                                return b.ToString();
 
132
                        }
 
133
                }
 
134
                
 
135
                public override string ToString()
 
136
                {
 
137
                        return ReflectionName;
 
138
                }
 
139
                
 
140
                public IList<IType> TypeArguments {
 
141
                        get {
 
142
                                return typeArguments;
 
143
                        }
 
144
                }
 
145
 
 
146
                public bool IsParameterized { 
 
147
                        get {
 
148
                                return true;
 
149
                        }
 
150
                }
 
151
 
 
152
                /// <summary>
 
153
                /// Same as 'parameterizedType.TypeArguments[index]', but is a bit more efficient (doesn't require the read-only wrapper).
 
154
                /// </summary>
 
155
                public IType GetTypeArgument(int index)
 
156
                {
 
157
                        return typeArguments[index];
 
158
                }
 
159
                
 
160
                /// <summary>
 
161
                /// Gets the definition of the generic type.
 
162
                /// For <c>ParameterizedType</c>, this method never returns null.
 
163
                /// </summary>
 
164
                public ITypeDefinition GetDefinition()
 
165
                {
 
166
                        return genericType;
 
167
                }
 
168
                
 
169
                public ITypeReference ToTypeReference()
 
170
                {
 
171
                        return new ParameterizedTypeReference(genericType.ToTypeReference(), typeArguments.Select(t => t.ToTypeReference()));
 
172
                }
 
173
                
 
174
                /// <summary>
 
175
                /// Gets a type visitor that performs the substitution of class type parameters with the type arguments
 
176
                /// of this parameterized type.
 
177
                /// </summary>
 
178
                public TypeParameterSubstitution GetSubstitution()
 
179
                {
 
180
                        return new TypeParameterSubstitution(typeArguments, null);
 
181
                }
 
182
                
 
183
                /// <summary>
 
184
                /// Gets a type visitor that performs the substitution of class type parameters with the type arguments
 
185
                /// of this parameterized type,
 
186
                /// and also substitutes method type parameters with the specified method type arguments.
 
187
                /// </summary>
 
188
                public TypeParameterSubstitution GetSubstitution(IList<IType> methodTypeArguments)
 
189
                {
 
190
                        return new TypeParameterSubstitution(typeArguments, methodTypeArguments);
 
191
                }
 
192
                
 
193
                public IEnumerable<IType> DirectBaseTypes {
 
194
                        get {
 
195
                                var substitution = GetSubstitution();
 
196
                                return genericType.DirectBaseTypes.Select(t => t.AcceptVisitor(substitution));
 
197
                        }
 
198
                }
 
199
                
 
200
                public IEnumerable<IType> GetNestedTypes(Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
201
                {
 
202
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
203
                                return genericType.GetNestedTypes(filter, options);
 
204
                        else
 
205
                                return GetMembersHelper.GetNestedTypes(this, filter, options);
 
206
                }
 
207
                
 
208
                public IEnumerable<IType> GetNestedTypes(IList<IType> typeArguments, Predicate<ITypeDefinition> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
209
                {
 
210
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
211
                                return genericType.GetNestedTypes(typeArguments, filter, options);
 
212
                        else
 
213
                                return GetMembersHelper.GetNestedTypes(this, typeArguments, filter, options);
 
214
                }
 
215
                
 
216
                public IEnumerable<IMethod> GetConstructors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers)
 
217
                {
 
218
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
219
                                return genericType.GetConstructors(filter, options);
 
220
                        else
 
221
                                return GetMembersHelper.GetConstructors(this, filter, options);
 
222
                }
 
223
                
 
224
                public IEnumerable<IMethod> GetMethods(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
225
                {
 
226
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
227
                                return genericType.GetMethods(filter, options);
 
228
                        else
 
229
                                return GetMembersHelper.GetMethods(this, filter, options);
 
230
                }
 
231
                
 
232
                public IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
233
                {
 
234
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
235
                                return genericType.GetMethods(typeArguments, filter, options);
 
236
                        else
 
237
                                return GetMembersHelper.GetMethods(this, typeArguments, filter, options);
 
238
                }
 
239
                
 
240
                public IEnumerable<IProperty> GetProperties(Predicate<IUnresolvedProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
241
                {
 
242
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
243
                                return genericType.GetProperties(filter, options);
 
244
                        else
 
245
                                return GetMembersHelper.GetProperties(this, filter, options);
 
246
                }
 
247
                
 
248
                public IEnumerable<IField> GetFields(Predicate<IUnresolvedField> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
249
                {
 
250
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
251
                                return genericType.GetFields(filter, options);
 
252
                        else
 
253
                                return GetMembersHelper.GetFields(this, filter, options);
 
254
                }
 
255
                
 
256
                public IEnumerable<IEvent> GetEvents(Predicate<IUnresolvedEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
257
                {
 
258
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
259
                                return genericType.GetEvents(filter, options);
 
260
                        else
 
261
                                return GetMembersHelper.GetEvents(this, filter, options);
 
262
                }
 
263
                
 
264
                public IEnumerable<IMember> GetMembers(Predicate<IUnresolvedMember> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
265
                {
 
266
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
267
                                return genericType.GetMembers(filter, options);
 
268
                        else
 
269
                                return GetMembersHelper.GetMembers(this, filter, options);
 
270
                }
 
271
                
 
272
                public IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
 
273
                {
 
274
                        if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
 
275
                                return genericType.GetAccessors(filter, options);
 
276
                        else
 
277
                                return GetMembersHelper.GetAccessors(this, filter, options);
 
278
                }
 
279
                
 
280
                public override bool Equals(object obj)
 
281
                {
 
282
                        return Equals(obj as IType);
 
283
                }
 
284
                
 
285
                public bool Equals(IType other)
 
286
                {
 
287
                        ParameterizedType c = other as ParameterizedType;
 
288
                        if (c == null || !genericType.Equals(c.genericType) || typeArguments.Length != c.typeArguments.Length)
 
289
                                return false;
 
290
                        for (int i = 0; i < typeArguments.Length; i++) {
 
291
                                if (!typeArguments[i].Equals(c.typeArguments[i]))
 
292
                                        return false;
 
293
                        }
 
294
                        return true;
 
295
                }
 
296
                
 
297
                public override int GetHashCode()
 
298
                {
 
299
                        int hashCode = genericType.GetHashCode();
 
300
                        unchecked {
 
301
                                foreach (var ta in typeArguments) {
 
302
                                        hashCode *= 1000000007;
 
303
                                        hashCode += 1000000009 * ta.GetHashCode();
 
304
                                }
 
305
                        }
 
306
                        return hashCode;
 
307
                }
 
308
                
 
309
                public IType AcceptVisitor(TypeVisitor visitor)
 
310
                {
 
311
                        return visitor.VisitParameterizedType(this);
 
312
                }
 
313
                
 
314
                public IType VisitChildren(TypeVisitor visitor)
 
315
                {
 
316
                        IType g = genericType.AcceptVisitor(visitor);
 
317
                        ITypeDefinition def = g as ITypeDefinition;
 
318
                        if (def == null)
 
319
                                return g;
 
320
                        // Keep ta == null as long as no elements changed, allocate the array only if necessary.
 
321
                        IType[] ta = (g != genericType) ? new IType[typeArguments.Length] : null;
 
322
                        for (int i = 0; i < typeArguments.Length; i++) {
 
323
                                IType r = typeArguments[i].AcceptVisitor(visitor);
 
324
                                if (r == null)
 
325
                                        throw new NullReferenceException("TypeVisitor.Visit-method returned null");
 
326
                                if (ta == null && r != typeArguments[i]) {
 
327
                                        // we found a difference, so we need to allocate the array
 
328
                                        ta = new IType[typeArguments.Length];
 
329
                                        for (int j = 0; j < i; j++) {
 
330
                                                ta[j] = typeArguments[j];
 
331
                                        }
 
332
                                }
 
333
                                if (ta != null)
 
334
                                        ta[i] = r;
 
335
                        }
 
336
                        if (def == genericType && ta == null)
 
337
                                return this;
 
338
                        else
 
339
                                return new ParameterizedType(def, ta ?? typeArguments);
 
340
                }
 
341
        }
 
342
        
 
343
        /// <summary>
 
344
        /// ParameterizedTypeReference is a reference to generic class that specifies the type parameters.
 
345
        /// Example: List&lt;string&gt;
 
346
        /// </summary>
 
347
        [Serializable]
 
348
        public sealed class ParameterizedTypeReference : ITypeReference, ISupportsInterning
 
349
        {
 
350
                readonly ITypeReference genericType;
 
351
                readonly ITypeReference[] typeArguments;
 
352
                
 
353
                public ParameterizedTypeReference(ITypeReference genericType, IEnumerable<ITypeReference> typeArguments)
 
354
                {
 
355
                        if (genericType == null)
 
356
                                throw new ArgumentNullException("genericType");
 
357
                        if (typeArguments == null)
 
358
                                throw new ArgumentNullException("typeArguments");
 
359
                        this.genericType = genericType;
 
360
                        this.typeArguments = typeArguments.ToArray();
 
361
                        for (int i = 0; i < this.typeArguments.Length; i++) {
 
362
                                if (this.typeArguments[i] == null)
 
363
                                        throw new ArgumentNullException("typeArguments[" + i + "]");
 
364
                        }
 
365
                }
 
366
                
 
367
                public ITypeReference GenericType {
 
368
                        get { return genericType; }
 
369
                }
 
370
                
 
371
                public ReadOnlyCollection<ITypeReference> TypeArguments {
 
372
                        get {
 
373
                                return Array.AsReadOnly(typeArguments);
 
374
                        }
 
375
                }
 
376
                
 
377
                public IType Resolve(ITypeResolveContext context)
 
378
                {
 
379
                        IType baseType = genericType.Resolve(context);
 
380
                        ITypeDefinition baseTypeDef = baseType.GetDefinition();
 
381
                        if (baseTypeDef == null)
 
382
                                return baseType;
 
383
                        int tpc = baseTypeDef.TypeParameterCount;
 
384
                        if (tpc == 0)
 
385
                                return baseTypeDef;
 
386
                        IType[] resolvedTypes = new IType[tpc];
 
387
                        for (int i = 0; i < resolvedTypes.Length; i++) {
 
388
                                if (i < typeArguments.Length)
 
389
                                        resolvedTypes[i] = typeArguments[i].Resolve(context);
 
390
                                else
 
391
                                        resolvedTypes[i] = SpecialType.UnknownType;
 
392
                        }
 
393
                        return new ParameterizedType(baseTypeDef, resolvedTypes);
 
394
                }
 
395
                
 
396
                public override string ToString()
 
397
                {
 
398
                        StringBuilder b = new StringBuilder(genericType.ToString());
 
399
                        b.Append('[');
 
400
                        for (int i = 0; i < typeArguments.Length; i++) {
 
401
                                if (i > 0)
 
402
                                        b.Append(',');
 
403
                                b.Append('[');
 
404
                                b.Append(typeArguments[i].ToString());
 
405
                                b.Append(']');
 
406
                        }
 
407
                        b.Append(']');
 
408
                        return b.ToString();
 
409
                }
 
410
                
 
411
                int ISupportsInterning.GetHashCodeForInterning()
 
412
                {
 
413
                        int hashCode = genericType.GetHashCode();
 
414
                        unchecked {
 
415
                                foreach (ITypeReference t in typeArguments) {
 
416
                                        hashCode *= 27;
 
417
                                        hashCode += t.GetHashCode();
 
418
                                }
 
419
                        }
 
420
                        return hashCode;
 
421
                }
 
422
                
 
423
                bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
 
424
                {
 
425
                        ParameterizedTypeReference o = other as ParameterizedTypeReference;
 
426
                        if (o != null && genericType == o.genericType && typeArguments.Length == o.typeArguments.Length) {
 
427
                                for (int i = 0; i < typeArguments.Length; i++) {
 
428
                                        if (typeArguments[i] != o.typeArguments[i])
 
429
                                                return false;
 
430
                                }
 
431
                                return true;
 
432
                        }
 
433
                        return false;
 
434
                }
 
435
        }
 
436
}