~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric-updates

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Projects/MonoDevelop.Projects.Dom/DomReturnType.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-18 08:40:51 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218084051-gh8m6ukvokbwj7cf
Tags: 1.9.2+dfsg-1ubuntu1
* Merge from Debian Experimental (LP: #330519), remaining Ubuntu changes:
  + debian/control:
    - Update for Gnome# 2.24
    - Add libmono-cairo1.0-cil to build-deps to fool pkg-config check

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// DomReturnType.cs
 
3
//
 
4
// Author:
 
5
//   Mike Krüger <mkrueger@novell.com>
 
6
//
 
7
// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining
 
10
// a copy of this software and associated documentation files (the
 
11
// "Software"), to deal in the Software without restriction, including
 
12
// without limitation the rights to use, copy, modify, merge, publish,
 
13
// distribute, sublicense, and/or sell copies of the Software, and to
 
14
// permit persons to whom the Software is furnished to do so, subject to
 
15
// the following conditions:
 
16
// 
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
// 
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
//
 
28
 
 
29
using System;
 
30
using System.Text;
 
31
using System.Collections.Generic;
 
32
using System.Collections.ObjectModel;
 
33
using System.Diagnostics;
 
34
 
 
35
namespace MonoDevelop.Projects.Dom
 
36
{
 
37
        public class ReturnTypePart : IReturnTypePart
 
38
        {
 
39
                public string Name {
 
40
                        get;
 
41
                        set;
 
42
                }
 
43
                
 
44
                protected List<IReturnType> genericArguments = null;
 
45
                static readonly ReadOnlyCollection<IReturnType> emptyGenericParameters = new ReadOnlyCollection<IReturnType> (new IReturnType [0]);
 
46
                public System.Collections.ObjectModel.ReadOnlyCollection<IReturnType> GenericArguments {
 
47
                        get {
 
48
                                if (genericArguments == null)
 
49
                                        return emptyGenericParameters;
 
50
                                return genericArguments.AsReadOnly ();
 
51
                        }
 
52
                }
 
53
                public ReturnTypePart ()
 
54
                {
 
55
                }
 
56
                
 
57
                public ReturnTypePart (string name, IEnumerable<IReturnType> typeParameters)
 
58
                {
 
59
                        this.Name = name;
 
60
                        if (typeParameters != null) 
 
61
                                this.genericArguments = new List<IReturnType> (typeParameters);
 
62
                }
 
63
                public ReturnTypePart (string baseName, string name, IEnumerable<ITypeParameter> typeParameters)
 
64
                {
 
65
                        this.Name = name;
 
66
                        if (typeParameters != null) {
 
67
                                this.genericArguments = new List<IReturnType> ();
 
68
                                foreach (ITypeParameter para in typeParameters) {
 
69
                                        this.genericArguments.Add (new DomReturnType (baseName + "." + para.Name));
 
70
                                }
 
71
                        }
 
72
                }
 
73
                
 
74
                public string ToInvariantString ()
 
75
                {
 
76
                        if (genericArguments != null && genericArguments.Count > 0) {
 
77
                                StringBuilder result = new StringBuilder ();
 
78
                                result.Append (Name);
 
79
                                result.Append ('<');
 
80
                                for (int i = 0; i < genericArguments.Count; i++) {
 
81
                                        if (i > 0)
 
82
                                                result.Append (',');
 
83
                                        result.Append (genericArguments[i].ToInvariantString ());
 
84
                                }
 
85
                                result.Append ('>');
 
86
                                return result.ToString ();
 
87
                        }
 
88
                        return Name;
 
89
                }
 
90
                
 
91
                public void AddTypeParameter (IReturnType type)
 
92
                {
 
93
                        if (genericArguments == null)
 
94
                                genericArguments = new List<IReturnType> ();
 
95
                        this.genericArguments.Add (type);
 
96
                }
 
97
        }
 
98
        
 
99
        public class DomReturnType : IReturnType
 
100
        {
 
101
                static readonly int[] zeroDimensions = new int[0];
 
102
                static readonly int[] oneDimensions = new int[] { 1 };
 
103
                
 
104
                List<IReturnTypePart> parts = new List<IReturnTypePart> ();
 
105
                
 
106
                // TODO dom: free unused return types
 
107
                static Dictionary<string, IReturnType> returnTypeCache;
 
108
                
 
109
                public static readonly IReturnType Void;
 
110
                public static readonly IReturnType Object;
 
111
                public static readonly IReturnType Exception;
 
112
                
 
113
                static DomReturnType ()
 
114
                {
 
115
                        // Initialization is done here instead of using field initializers to
 
116
                        // ensure that the returnTypeCache dictionary us properly initialized
 
117
                        // when calling GetSharedReturnType.
 
118
                        
 
119
                        returnTypeCache = new Dictionary<string, IReturnType> ();
 
120
                        
 
121
                        Void      = GetSharedReturnType ("System.Void");
 
122
                        Object    = GetSharedReturnType ("System.Object");
 
123
                        Exception = GetSharedReturnType ("System.Exception");
 
124
                }
 
125
 
 
126
                public List<IReturnTypePart> Parts {
 
127
                        get {
 
128
                                return parts;
 
129
                        }
 
130
                }
 
131
                
 
132
                public string Name {
 
133
                        get {
 
134
                                Debug.Assert (parts.Count > 0);
 
135
                                return parts[parts.Count - 1].Name;
 
136
                        }
 
137
                        set {
 
138
                                Debug.Assert (parts.Count > 0);
 
139
                                parts[parts.Count - 1].Name = value;
 
140
                        }
 
141
                }
 
142
                
 
143
                public ReadOnlyCollection<IReturnType> GenericArguments {
 
144
                        get {
 
145
                                Debug.Assert (parts.Count > 0);
 
146
                                return parts[parts.Count - 1].GenericArguments;
 
147
                        }
 
148
                }
 
149
                public void AddTypeParameter (IReturnType type)
 
150
                {
 
151
                        Debug.Assert (parts.Count > 0);
 
152
                        parts[parts.Count - 1].AddTypeParameter (type);
 
153
                }
 
154
                
 
155
                protected string nspace;
 
156
                protected int pointerNestingLevel;
 
157
                protected int[] dimensions = null;
 
158
                ReturnTypeModifiers modifiers;
 
159
                
 
160
                public string FullName {
 
161
                        get {
 
162
                                if (Parts.Count == 1)
 
163
                                        return !String.IsNullOrEmpty (nspace) ? nspace + "." + Name : Name;
 
164
                                else {
 
165
                                        string fn = nspace;
 
166
                                        foreach (ReturnTypePart part in Parts) {
 
167
                                                if (fn.Length > 0)
 
168
                                                        fn += ".";
 
169
                                                fn += part.Name;
 
170
                                        }
 
171
                                        return fn;
 
172
                                }
 
173
                        }
 
174
                }
 
175
                
 
176
                public string DecoratedFullName {
 
177
                        get {
 
178
                                string dname = Namespace;
 
179
                                foreach (ReturnTypePart rpart in Parts) {
 
180
                                        if (dname.Length > 0)
 
181
                                                dname += ".";
 
182
                                        dname += rpart.Name;
 
183
                                        if (rpart.GenericArguments.Count > 0)
 
184
                                                dname += "`" + rpart.GenericArguments.Count;
 
185
                                }
 
186
                                return dname;
 
187
                        }
 
188
                }
 
189
                
 
190
                public static KeyValuePair<string, string> SplitFullName (string fullName)
 
191
                {
 
192
                        if (String.IsNullOrEmpty (fullName)) 
 
193
                                return new KeyValuePair<string, string> ("", "");
 
194
                        int idx = fullName.LastIndexOf ('.');
 
195
                        if (idx >= 0) 
 
196
                                return new KeyValuePair<string, string> (fullName.Substring (0, idx), fullName.Substring (idx + 1));
 
197
                        return new KeyValuePair<string, string> ("", fullName);
 
198
                }
 
199
 
 
200
                public ReturnTypeModifiers Modifiers {
 
201
                        get {
 
202
                                return this.modifiers;
 
203
                        }
 
204
                        set {
 
205
                                this.modifiers = value;
 
206
                        }
 
207
                }
 
208
                
 
209
 
 
210
                public string Namespace {
 
211
                        get {
 
212
                                return nspace;
 
213
                        }
 
214
                        set {
 
215
                                nspace = value;
 
216
                        }
 
217
                }
 
218
                public int PointerNestingLevel {
 
219
                        get {
 
220
                                return pointerNestingLevel;
 
221
                        }
 
222
                        set {
 
223
                                pointerNestingLevel = value;
 
224
                        }
 
225
                }
 
226
                
 
227
                public int ArrayDimensions {
 
228
                        get {
 
229
                                return dimensions != null ? dimensions.Length : 0;
 
230
                        }
 
231
                        set {
 
232
                                List<int> curDimensions = new List<int> (dimensions ?? zeroDimensions);
 
233
                                if (curDimensions.Count > value) 
 
234
                                        curDimensions.RemoveRange (value, value - curDimensions.Count);
 
235
                                while (curDimensions.Count < value)
 
236
                                        curDimensions.Add (0);
 
237
                                SetDimensions (curDimensions.ToArray ());
 
238
                        }
 
239
                }
 
240
 
 
241
                public bool IsNullable {
 
242
                        get {
 
243
                                return (Modifiers & ReturnTypeModifiers.Nullable) == ReturnTypeModifiers.Nullable;
 
244
                        }
 
245
                        set {
 
246
                                if (value) {
 
247
                                        Modifiers |= ReturnTypeModifiers.Nullable;
 
248
                                } else {
 
249
                                        Modifiers &= ~ReturnTypeModifiers.Nullable;
 
250
                                }
 
251
                        }
 
252
                }
 
253
 
 
254
                public bool IsByRef {
 
255
                        get {
 
256
                                return (Modifiers & ReturnTypeModifiers.ByRef) == ReturnTypeModifiers.ByRef;
 
257
                        }
 
258
                        set {
 
259
                                if (value) {
 
260
                                        Modifiers |= ReturnTypeModifiers.ByRef;
 
261
                                } else {
 
262
                                        Modifiers &= ~ReturnTypeModifiers.ByRef;
 
263
                                }
 
264
                        }
 
265
                }
 
266
                
 
267
                protected IType type;
 
268
                public virtual IType Type {
 
269
                        get {
 
270
                                return type;
 
271
                        }
 
272
                        set {
 
273
                                type = value;
 
274
                        }
 
275
                }
 
276
                
 
277
                public DomReturnType ()
 
278
                {
 
279
                        this.parts.Add (new ReturnTypePart ());
 
280
                }
 
281
                
 
282
                internal DomReturnType (string ns, List<IReturnTypePart> parts)
 
283
                {
 
284
                        this.nspace = ns;
 
285
                        this.parts = parts;
 
286
                }
 
287
                
 
288
                public DomReturnType (IType type)
 
289
                {
 
290
                        if (type == null)
 
291
                                throw new ArgumentNullException ("type was null");
 
292
                        this.type = type;
 
293
                        this.nspace = type is InstantiatedType ? ((InstantiatedType)type).UninstantiatedType.Namespace : type.Namespace;
 
294
                        IType curType = type;
 
295
                        do {
 
296
                                if (curType is InstantiatedType) {
 
297
                                        InstantiatedType instType = (InstantiatedType)curType;
 
298
                                        this.parts.Insert (0, new ReturnTypePart (instType.UninstantiatedType.Name, instType.GenericParameters));
 
299
                                } else
 
300
                                        this.parts.Insert (0, new ReturnTypePart (curType.FullName, curType.Name, curType.TypeParameters));
 
301
                                curType = curType.DeclaringType;
 
302
                        } while (curType != null);
 
303
                }
 
304
                
 
305
                public override bool Equals (object obj)
 
306
                {
 
307
                        DomReturnType type = obj as DomReturnType;
 
308
                        if (type == null)
 
309
                                return false;
 
310
                        if (ArrayDimensions != type.ArrayDimensions)
 
311
                                return false;
 
312
                        for (int n=0; n<ArrayDimensions; n++) {
 
313
                                if (GetDimension (n) != type.GetDimension (n))
 
314
                                        return false;
 
315
                        }
 
316
                        if (GenericArguments.Count != type.GenericArguments.Count)
 
317
                                return false;
 
318
                        for (int i = 0; i < GenericArguments.Count; i++) {
 
319
                                if (!GenericArguments[i].Equals (type.GenericArguments [i]))
 
320
                                        return false;
 
321
                        }
 
322
 
 
323
                        return Name == type.Name &&
 
324
                                nspace == type.nspace &&
 
325
                                pointerNestingLevel == type.pointerNestingLevel &&
 
326
                                Modifiers == type.Modifiers;
 
327
                }
 
328
 
 
329
                public override int GetHashCode ()
 
330
                {
 
331
                        return ToInvariantString ().GetHashCode ();
 
332
                }
 
333
 
 
334
                
 
335
                public int GetDimension (int arrayDimension)
 
336
                {
 
337
                        if (dimensions == null || arrayDimension < 0 || arrayDimension >= dimensions.Length)
 
338
                                return -1;
 
339
                        return this.dimensions [arrayDimension];
 
340
                }
 
341
 
 
342
                public void SetDimension (int arrayDimension, int dimension)
 
343
                {
 
344
                        if (arrayDimension < 0 || arrayDimension >= ArrayDimensions)
 
345
                                return;
 
346
                        
 
347
                        // Avoid changing the shared dimension
 
348
                        if (dimensions == oneDimensions)
 
349
                                dimensions = new int [ArrayDimensions];
 
350
                        
 
351
                        dimensions [arrayDimension] = dimension;
 
352
                        SetDimensions (dimensions);
 
353
                }
 
354
                
 
355
                public void SetDimensions (int[] arrayDimensions)
 
356
                {
 
357
                        // Reuse common dimension constants to save memory
 
358
                        if (arrayDimensions == null)
 
359
                                dimensions = null;
 
360
                        else if (arrayDimensions != null && arrayDimensions.Length == 1 && arrayDimensions[0] == 1)
 
361
                                dimensions = oneDimensions;
 
362
                        else
 
363
                                dimensions = arrayDimensions;
 
364
                }
 
365
                
 
366
                public int[] GetDimensions ()
 
367
                {
 
368
                        return dimensions ?? zeroDimensions;
 
369
                }
 
370
                
 
371
                public DomReturnType (string name) : this (name, false, new List<IReturnType> ())
 
372
                {
 
373
                }
 
374
                
 
375
                public DomReturnType (string name, bool isNullable, IEnumerable<IReturnType> typeParameters)
 
376
                {
 
377
                        KeyValuePair<string, string> splitted = SplitFullName (name);
 
378
                        this.nspace = splitted.Key;
 
379
                        this.parts.Add (new ReturnTypePart (splitted.Value, typeParameters));
 
380
                        this.IsNullable     = isNullable;
 
381
                }
 
382
                
 
383
                public static IReturnType FromInvariantString (string invariantString)
 
384
                {
 
385
                        return GetSharedReturnType (invariantString);
 
386
                }
 
387
                
 
388
                public static int num = 0;
 
389
                string invariantString = null;
 
390
                public string ToInvariantString ()
 
391
                {
 
392
                        if (invariantString != null)
 
393
                                return invariantString;
 
394
                        StringBuilder result = new StringBuilder ();
 
395
                        result.Append (Namespace);
 
396
                        foreach (ReturnTypePart part in Parts) {
 
397
                                if (result.Length > 0)
 
398
                                        result.Append ('.');
 
399
                                result.Append (part.ToInvariantString ());
 
400
                        }
 
401
                        for (int i = 0; i < ArrayDimensions; i++) {
 
402
                                result.Append ('[');
 
403
                                result.Append (new string (',', this.GetDimension (i)));
 
404
                                result.Append (']');
 
405
                        }
 
406
                        result.Append (new string ('*', this.PointerNestingLevel));
 
407
                        if (this.IsByRef)
 
408
                                result.Append ('&');
 
409
                        if (this.IsNullable)
 
410
                                result.Append ('?');
 
411
                        return invariantString = result.ToString ();
 
412
                }
 
413
                
 
414
                public S AcceptVisitor<T, S> (IDomVisitor<T, S> visitor, T data)
 
415
                {
 
416
                        return visitor.Visit (this, data);
 
417
                }
 
418
                
 
419
                public override string ToString ()
 
420
                {
 
421
                        StringBuilder genArgs = new StringBuilder ();
 
422
                        if (GenericArguments == null) {
 
423
                                genArgs.Append ("<null>");
 
424
                        } else {
 
425
                                genArgs.Append ("{");
 
426
                                foreach (object o in GenericArguments) {
 
427
                                        if (genArgs.Length > 1)
 
428
                                                genArgs.Append (", ");
 
429
                                        genArgs.Append (o != null ? o.ToString () : "null");
 
430
                                } 
 
431
                                genArgs.Append ("}");
 
432
                        }
 
433
                        
 
434
                        return string.Format ("[DomReturnType:FullName={0}, PointerNestingLevel={1}, ArrayDimensions={2}, GenericArguments={3}, UnderlyingType={4}]",
 
435
                                              FullName,
 
436
                                              PointerNestingLevel,
 
437
                                              ArrayDimensions,
 
438
                                              genArgs.ToString (),
 
439
                                              Type == null ? "null" : Type.ToString ());
 
440
                }
 
441
                
 
442
                public static string ConvertToString (IReturnType type)
 
443
                {
 
444
                        StringBuilder sb = new StringBuilder (DomType.GetInstantiatedTypeName (type.FullName, type.GenericArguments));
 
445
                        
 
446
                        if (type.PointerNestingLevel > 0)
 
447
                                sb.Append (new String ('*', type.PointerNestingLevel));
 
448
                        
 
449
                        if (type.ArrayDimensions > 0) {
 
450
                                for (int i = 0; i < type.ArrayDimensions; i++) {
 
451
                                        sb.Append ("[]");
 
452
                                }
 
453
                        }
 
454
                        
 
455
                        return sb.ToString ();
 
456
                }
 
457
                
 
458
#region shared return types
 
459
 
 
460
                public static IReturnType GetSharedReturnType (string invariantString)
 
461
                {
 
462
                        if (String.IsNullOrEmpty (invariantString))
 
463
                                return null;
 
464
                        lock (returnTypeCache) {
 
465
                                IReturnType type;
 
466
                                if (!returnTypeCache.TryGetValue (invariantString, out type)) {
 
467
                                        DomReturnType newType = new DomReturnType (invariantString);
 
468
                                        returnTypeCache[invariantString] = newType;
 
469
                                        return newType;
 
470
                                }
 
471
                                return type;
 
472
                        }
 
473
                }
 
474
                
 
475
                public static IReturnType GetSharedReturnType (IReturnType returnType)
 
476
                {
 
477
                        if (returnType == null)
 
478
                                return null;
 
479
                        string invariantString = returnType.ToInvariantString();
 
480
                        lock (returnTypeCache) {
 
481
                                IReturnType type;
 
482
                                if (!returnTypeCache.TryGetValue (invariantString, out type)) {
 
483
                                        returnTypeCache[invariantString] = returnType;
 
484
                                        return returnType;
 
485
                                }
 
486
                                return type;
 
487
                        }
 
488
                }
 
489
#endregion
 
490
        }
 
491
}