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

« back to all changes in this revision

Viewing changes to contrib/NRefactory/Project/Src/Ast/TypeReference.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
 
// <file>
2
 
//     <copyright see="prj:///doc/copyright.txt"/>
3
 
//     <license see="prj:///doc/license.txt"/>
4
 
//     <owner name="Mike KrĆ¼ger" email="mike@icsharpcode.net"/>
5
 
//     <version>$Revision: 4482 $</version>
6
 
// </file>
7
 
 
8
 
using System;
9
 
using System.Collections.Generic;
10
 
using System.Diagnostics;
11
 
using System.Globalization;
12
 
using System.Runtime.InteropServices;
13
 
using System.Text;
14
 
 
15
 
namespace ICSharpCode.OldNRefactory.Ast
16
 
{
17
 
        public class TypeReference : AbstractNode, INullable, ICloneable
18
 
        {
19
 
                public static readonly TypeReference StructConstraint = new TypeReference("constraint: struct");
20
 
                public static readonly TypeReference ClassConstraint = new TypeReference("constraint: class");
21
 
                public static readonly TypeReference NewConstraint = new TypeReference("constraint: new");
22
 
                
23
 
                string type = "";
24
 
                int    pointerNestingLevel;
25
 
                int[]  rankSpecifier;
26
 
                List<TypeReference> genericTypes = new List<TypeReference>();
27
 
                
28
 
                #region Static primitive type list
29
 
                static Dictionary<string, string> types   = new Dictionary<string, string>();
30
 
                static Dictionary<string, string> vbtypes = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
31
 
                static Dictionary<string, string> typesReverse   = new Dictionary<string, string>();
32
 
                static Dictionary<string, string> vbtypesReverse = new Dictionary<string, string>();
33
 
                
34
 
                static TypeReference()
35
 
                {
36
 
                        // C# types
37
 
                        types.Add("bool",    "System.Boolean");
38
 
                        types.Add("byte",    "System.Byte");
39
 
                        types.Add("char",    "System.Char");
40
 
                        types.Add("decimal", "System.Decimal");
41
 
                        types.Add("double",  "System.Double");
42
 
                        types.Add("float",   "System.Single");
43
 
                        types.Add("int",     "System.Int32");
44
 
                        types.Add("long",    "System.Int64");
45
 
                        types.Add("object",  "System.Object");
46
 
                        types.Add("sbyte",   "System.SByte");
47
 
                        types.Add("short",   "System.Int16");
48
 
                        types.Add("string",  "System.String");
49
 
                        types.Add("uint",    "System.UInt32");
50
 
                        types.Add("ulong",   "System.UInt64");
51
 
                        types.Add("ushort",  "System.UInt16");
52
 
                        types.Add("void",    "System.Void");
53
 
                        
54
 
                        // VB.NET types
55
 
                        vbtypes.Add("Boolean", "System.Boolean");
56
 
                        vbtypes.Add("Byte",    "System.Byte");
57
 
                        vbtypes.Add("SByte",   "System.SByte");
58
 
                        vbtypes.Add("Date",        "System.DateTime");
59
 
                        vbtypes.Add("Char",    "System.Char");
60
 
                        vbtypes.Add("Decimal", "System.Decimal");
61
 
                        vbtypes.Add("Double",  "System.Double");
62
 
                        vbtypes.Add("Single",  "System.Single");
63
 
                        vbtypes.Add("Integer", "System.Int32");
64
 
                        vbtypes.Add("Long",    "System.Int64");
65
 
                        vbtypes.Add("UInteger","System.UInt32");
66
 
                        vbtypes.Add("ULong",   "System.UInt64");
67
 
                        vbtypes.Add("Object",  "System.Object");
68
 
                        vbtypes.Add("Short",   "System.Int16");
69
 
                        vbtypes.Add("UShort",  "System.UInt16");
70
 
                        vbtypes.Add("String",  "System.String");
71
 
                        
72
 
                        foreach (KeyValuePair<string, string> pair in types) {
73
 
                                typesReverse.Add(pair.Value, pair.Key);
74
 
                        }
75
 
                        foreach (KeyValuePair<string, string> pair in vbtypes) {
76
 
                                vbtypesReverse.Add(pair.Value, pair.Key);
77
 
                        }
78
 
                }
79
 
                
80
 
                /// <summary>
81
 
                /// Gets a shortname=>full name dictionary of C# types.
82
 
                /// </summary>
83
 
                public static IDictionary<string, string> PrimitiveTypesCSharp {
84
 
                        get { return types; }
85
 
                }
86
 
                
87
 
                /// <summary>
88
 
                /// Gets a shortname=>full name dictionary of VB types.
89
 
                /// </summary>
90
 
                public static IDictionary<string, string> PrimitiveTypesVB {
91
 
                        get { return vbtypes; }
92
 
                }
93
 
                
94
 
                /// <summary>
95
 
                /// Gets a full name=>shortname dictionary of C# types.
96
 
                /// </summary>
97
 
                public static IDictionary<string, string> PrimitiveTypesCSharpReverse {
98
 
                        get { return typesReverse; }
99
 
                }
100
 
                
101
 
                /// <summary>
102
 
                /// Gets a full name=>shortname dictionary of VB types.
103
 
                /// </summary>
104
 
                public static IDictionary<string, string> PrimitiveTypesVBReverse {
105
 
                        get { return vbtypesReverse; }
106
 
                }
107
 
                
108
 
                
109
 
                static string GetSystemType(string type)
110
 
                {
111
 
                        if (types == null) return type;
112
 
                        
113
 
                        string systemType;
114
 
                        if (types.TryGetValue(type, out systemType)) {
115
 
                                return systemType;
116
 
                        }
117
 
                        if (vbtypes.TryGetValue(type, out systemType)) {
118
 
                                return systemType;
119
 
                        }
120
 
                        return type;
121
 
                }
122
 
                #endregion
123
 
                
124
 
                object ICloneable.Clone()
125
 
                {
126
 
                        return this.Clone();
127
 
                }
128
 
                
129
 
                public virtual TypeReference Clone()
130
 
                {
131
 
                        TypeReference c = new TypeReference(type);
132
 
                        CopyFields(this, c);
133
 
                        return c;
134
 
                }
135
 
                
136
 
                /// <summary>
137
 
                /// Copies the pointerNestingLevel, RankSpecifier, GenericTypes and IsGlobal flag
138
 
                /// from <paramref name="from"/> to <paramref name="to"/>.
139
 
                /// </summary>
140
 
                /// <remarks>
141
 
                /// If <paramref name="to"/> already contains generics, the new generics are appended to the list.
142
 
                /// </remarks>
143
 
                protected static void CopyFields(TypeReference from, TypeReference to)
144
 
                {
145
 
                        to.pointerNestingLevel = from.pointerNestingLevel;
146
 
                        if (from.rankSpecifier != null) {
147
 
                                to.rankSpecifier = (int[])from.rankSpecifier.Clone();
148
 
                        }
149
 
                        foreach (TypeReference r in from.genericTypes) {
150
 
                                to.genericTypes.Add(r.Clone());
151
 
                        }
152
 
                        to.IsGlobal = from.IsGlobal;
153
 
                        to.IsKeyword = from.IsKeyword;
154
 
                }
155
 
                
156
 
                public string Type {
157
 
                        get {
158
 
                                return type;
159
 
                        }
160
 
                        set {
161
 
                                Debug.Assert(value != null);
162
 
                                type = value ?? "?";
163
 
                        }
164
 
                }
165
 
                
166
 
                /// <summary>
167
 
                /// Removes the last identifier from the type.
168
 
                /// e.g. "System.String.Length" becomes "System.String" or
169
 
                /// "System.Collections.IEnumerable(of string).Current" becomes "System.Collections.IEnumerable(of string)"
170
 
                /// This is used for explicit interface implementation in VB.
171
 
                /// </summary>
172
 
                public static string StripLastIdentifierFromType(ref TypeReference tr)
173
 
                {
174
 
                        if (tr is InnerClassTypeReference && ((InnerClassTypeReference)tr).Type.IndexOf('.') < 0) {
175
 
                                string ident = ((InnerClassTypeReference)tr).Type;
176
 
                                tr = ((InnerClassTypeReference)tr).BaseType;
177
 
                                return ident;
178
 
                        } else {
179
 
                                int pos = tr.Type.LastIndexOf('.');
180
 
                                if (pos < 0)
181
 
                                        return tr.Type;
182
 
                                string ident = tr.Type.Substring(pos + 1);
183
 
                                tr.Type = tr.Type.Substring(0, pos);
184
 
                                return ident;
185
 
                        }
186
 
                }
187
 
                
188
 
                [Obsolete("Use 'Type' instead - it now contains the SystemType for primitive types.")]
189
 
                public string SystemType {
190
 
                        get {
191
 
                                return this.Type;
192
 
                        }
193
 
                }
194
 
                
195
 
                public int PointerNestingLevel {
196
 
                        get {
197
 
                                return pointerNestingLevel;
198
 
                        }
199
 
                        set {
200
 
                                Debug.Assert(this.IsNull == false);
201
 
                                pointerNestingLevel = value;
202
 
                        }
203
 
                }
204
 
                
205
 
                /// <summary>
206
 
                /// The rank of the array type.
207
 
                /// For "object[]", this is { 0 }; for "object[,]", it is {1}.
208
 
                /// For "object[,][,,][]", it is {1, 2, 0}.
209
 
                /// For non-array types, this property is null or {}.
210
 
                /// </summary>
211
 
                public int[] RankSpecifier {
212
 
                        get {
213
 
                                return rankSpecifier;
214
 
                        }
215
 
                        set {
216
 
                                Debug.Assert(this.IsNull == false);
217
 
                                rankSpecifier = value;
218
 
                        }
219
 
                }
220
 
                
221
 
                public List<TypeReference> GenericTypes {
222
 
                        get {
223
 
                                return genericTypes;
224
 
                        }
225
 
                }
226
 
                
227
 
                public bool IsArrayType {
228
 
                        get {
229
 
                                return rankSpecifier != null && rankSpecifier.Length > 0;
230
 
                        }
231
 
                }
232
 
                
233
 
                public static TypeReference CheckNull(TypeReference typeReference)
234
 
                {
235
 
                        return typeReference ?? NullTypeReference.Instance;
236
 
                }
237
 
                
238
 
                public static TypeReference Null {
239
 
                        get {
240
 
                                return NullTypeReference.Instance;
241
 
                        }
242
 
                }
243
 
                
244
 
                public virtual bool IsNull {
245
 
                        get {
246
 
                                return false;
247
 
                        }
248
 
                }
249
 
                
250
 
                /// <summary>
251
 
                /// Gets/Sets if the type reference had a "global::" prefix.
252
 
                /// </summary>
253
 
                public bool IsGlobal {
254
 
                        get; set;
255
 
                }
256
 
                
257
 
                /// <summary>
258
 
                /// Gets/Sets if the type reference was using a language keyword.
259
 
                /// </summary>
260
 
                public bool IsKeyword {
261
 
                        get; set;
262
 
                }
263
 
                
264
 
                public TypeReference(string type)
265
 
                {
266
 
                        this.Type = type;
267
 
                }
268
 
                
269
 
                [Obsolete("Type and SystemType are no longer distinguished - use the (string type, bool isKeyword) constructor instead!")]
270
 
                public TypeReference(string type, string systemType)
271
 
                {
272
 
                        this.Type = systemType;
273
 
                        this.IsKeyword = type != systemType;
274
 
                }
275
 
                
276
 
                public TypeReference(string type, bool isKeyword)
277
 
                {
278
 
                        this.Type = type;
279
 
                        this.IsKeyword = isKeyword;
280
 
                }
281
 
                
282
 
                public TypeReference(string type, List<TypeReference> genericTypes) : this(type)
283
 
                {
284
 
                        if (genericTypes != null) {
285
 
                                this.genericTypes = genericTypes;
286
 
                        }
287
 
                }
288
 
                
289
 
                public TypeReference(string type, int[] rankSpecifier) : this(type, 0, rankSpecifier)
290
 
                {
291
 
                }
292
 
                
293
 
                public TypeReference(string type, int pointerNestingLevel, int[] rankSpecifier) : this(type, pointerNestingLevel, rankSpecifier, null)
294
 
                {
295
 
                }
296
 
                
297
 
                public TypeReference(string type, int pointerNestingLevel, int[] rankSpecifier, List<TypeReference> genericTypes)
298
 
                {
299
 
                        Debug.Assert(type != null);
300
 
                        this.type = type;
301
 
                        this.pointerNestingLevel = pointerNestingLevel;
302
 
                        this.rankSpecifier = rankSpecifier;
303
 
                        if (genericTypes != null) {
304
 
                                this.genericTypes = genericTypes;
305
 
                        }
306
 
                }
307
 
                
308
 
                protected TypeReference()
309
 
                {}
310
 
                
311
 
                public override object AcceptVisitor(IAstVisitor visitor, object data)
312
 
                {
313
 
                        return visitor.VisitTypeReference(this, data);
314
 
                }
315
 
                
316
 
                public override string ToString()
317
 
                {
318
 
                        StringBuilder b = new StringBuilder(type);
319
 
                        if (genericTypes != null && genericTypes.Count > 0) {
320
 
                                b.Append('<');
321
 
                                for (int i = 0; i < genericTypes.Count; i++) {
322
 
                                        if (i > 0) b.Append(',');
323
 
                                        b.Append(genericTypes[i].ToString());
324
 
                                }
325
 
                                b.Append('>');
326
 
                        }
327
 
                        if (pointerNestingLevel > 0) {
328
 
                                b.Append('*', pointerNestingLevel);
329
 
                        }
330
 
                        if (IsArrayType) {
331
 
                                foreach (int rank in rankSpecifier) {
332
 
                                        b.Append('[');
333
 
                                        if (rank < 0)
334
 
                                                b.Append('`', -rank);
335
 
                                        else
336
 
                                                b.Append(',', rank);
337
 
                                        b.Append(']');
338
 
                                }
339
 
                        }
340
 
                        return b.ToString();
341
 
                }
342
 
                
343
 
                public static bool AreEqualReferences(TypeReference a, TypeReference b)
344
 
                {
345
 
                        if (a == b) return true;
346
 
                        if (a == null || b == null) return false;
347
 
                        if (a is InnerClassTypeReference) a = ((InnerClassTypeReference)a).CombineToNormalTypeReference();
348
 
                        if (b is InnerClassTypeReference) b = ((InnerClassTypeReference)b).CombineToNormalTypeReference();
349
 
                        if (a.type != b.type) return false;
350
 
                        if (a.IsKeyword != b.IsKeyword) return false;
351
 
                        if (a.IsGlobal != b.IsGlobal) return false;
352
 
                        if (a.pointerNestingLevel != b.pointerNestingLevel) return false;
353
 
                        if (a.IsArrayType != b.IsArrayType) return false;
354
 
                        if (a.IsArrayType) {
355
 
                                if (a.rankSpecifier.Length != b.rankSpecifier.Length) return false;
356
 
                                for (int i = 0; i < a.rankSpecifier.Length; i++) {
357
 
                                        if (a.rankSpecifier[i] != b.rankSpecifier[i]) return false;
358
 
                                }
359
 
                        }
360
 
                        if (a.genericTypes.Count != b.genericTypes.Count) return false;
361
 
                        for (int i = 0; i < a.genericTypes.Count; i++) {
362
 
                                if (!AreEqualReferences(a.genericTypes[i], b.genericTypes[i]))
363
 
                                        return false;
364
 
                        }
365
 
                        return true;
366
 
                }
367
 
        }
368
 
 
369
 
        internal sealed class NullTypeReference : TypeReference
370
 
        {
371
 
                public static readonly NullTypeReference Instance = new NullTypeReference();
372
 
                public override bool IsNull {
373
 
                        get {
374
 
                                return true;
375
 
                        }
376
 
                }
377
 
                public override TypeReference Clone()
378
 
                {
379
 
                        return this;
380
 
                }
381
 
                public override object AcceptVisitor(IAstVisitor visitor, object data)
382
 
                {
383
 
                        return null;
384
 
                }
385
 
                
386
 
                public override string ToString()
387
 
                {
388
 
                        return String.Format("[NullTypeReference]");
389
 
                }
390
 
        }
391
 
 
392
 
        /// <summary>
393
 
        /// We need this special type reference for cases like
394
 
        /// OuterClass(Of T1).InnerClass(Of T2) (in expression or type context)
395
 
        /// or Dictionary(Of String, NamespaceStruct).KeyCollection (in type context, otherwise it's a
396
 
        /// MemberReferenceExpression)
397
 
        /// </summary>
398
 
        public class InnerClassTypeReference: TypeReference
399
 
        {
400
 
                TypeReference baseType;
401
 
                
402
 
                public TypeReference BaseType {
403
 
                        get { return baseType; }
404
 
                        set { baseType = value; }
405
 
                }
406
 
                
407
 
                public override TypeReference Clone()
408
 
                {
409
 
                        InnerClassTypeReference c = new InnerClassTypeReference(baseType.Clone(), Type, new List<TypeReference>());
410
 
                        CopyFields(this, c);
411
 
                        return c;
412
 
                }
413
 
                
414
 
                public InnerClassTypeReference(TypeReference outerClass, string innerType, List<TypeReference> innerGenericTypes)
415
 
                        : base(innerType, innerGenericTypes)
416
 
                {
417
 
                        this.baseType = outerClass;
418
 
                }
419
 
                
420
 
                public override object AcceptVisitor(IAstVisitor visitor, object data)
421
 
                {
422
 
                        return visitor.VisitInnerClassTypeReference(this, data);
423
 
                }
424
 
                
425
 
                /// <summary>
426
 
                /// Creates a type reference where all type parameters are specified for the innermost class.
427
 
                /// Namespace.OuterClass(of string).InnerClass(of integer).InnerInnerClass
428
 
                /// becomes Namespace.OuterClass.InnerClass.InnerInnerClass(of string, integer)
429
 
                /// </summary>
430
 
                public TypeReference CombineToNormalTypeReference()
431
 
                {
432
 
                        TypeReference tr = (baseType is InnerClassTypeReference)
433
 
                                ? ((InnerClassTypeReference)baseType).CombineToNormalTypeReference()
434
 
                                : baseType.Clone();
435
 
                        CopyFields(this, tr);
436
 
                        tr.Type += "." + Type;
437
 
                        return tr;
438
 
                }
439
 
                
440
 
                public override string ToString()
441
 
                {
442
 
                        return "[InnerClassTypeReference: (" + baseType.ToString() + ")." + base.ToString() + "]";
443
 
                }
444
 
        }
445
 
}