~ubuntu-branches/ubuntu/maverick/monodevelop/maverick

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Core/MonoDevelop.Projects.Dom.Serialization/ParserDatabase.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-07-05 13:00:05 UTC
  • mfrom: (1.2.8 upstream) (1.3.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100705130005-d6hp4k5gcn1xkj8c
Tags: 2.4+dfsg-1ubuntu1
* debian/patches/remove_support_for_moonlight.patch,
  debian/patches/dont_add_moonlight_to_core_addins.patch,
  debian/control:
  + Enable support for Moonlight
* debian/rules:
  + Ensure Moonlight addin isn't shipped in main MonoDevelop package by
    mistake

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ParserDatabase.cs
 
2
//
 
3
// Author:
 
4
//   Lluis Sanchez Gual <lluis@novell.com>
 
5
//
 
6
// Copyright (c) 2008 Novell, Inc (http://www.novell.com)
 
7
//
 
8
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
9
// of this software and associated documentation files (the "Software"), to deal
 
10
// in the Software without restriction, including without limitation the rights
 
11
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
12
// copies of the Software, and to permit persons to whom the Software is
 
13
// furnished to do so, subject to the following conditions:
 
14
//
 
15
// The above copyright notice and this permission notice shall be included in
 
16
// all copies or substantial portions of the Software.
 
17
//
 
18
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
21
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
22
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
23
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
24
// THE SOFTWARE.
 
25
//
 
26
//
 
27
 
 
28
 
 
29
using System;
 
30
using System.IO;
 
31
using System.Threading;
 
32
using System.Collections;
 
33
using System.Collections.Generic;
 
34
using System.Collections.Specialized;
 
35
using System.Diagnostics;
 
36
using System.Reflection;
 
37
using System.Runtime.Serialization;
 
38
using System.Runtime.Serialization.Formatters;
 
39
using System.Runtime.Serialization.Formatters.Binary;
 
40
using System.Security;
 
41
using System.Security.Permissions;
 
42
using System.Security.Policy;
 
43
using System.Xml;
 
44
 
 
45
using MonoDevelop.Core;
 
46
using MonoDevelop.Core.ProgressMonitoring;
 
47
using Mono.Addins;
 
48
using MonoDevelop.Projects;
 
49
using MonoDevelop.Projects.Utility;
 
50
using MonoDevelop.Projects.Text;
 
51
using MonoDevelop.Projects.Dom;
 
52
using MonoDevelop.Projects.Dom.Parser;
 
53
using MonoDevelop.Core.Assemblies;
 
54
 
 
55
namespace MonoDevelop.Projects.Dom.Serialization
 
56
{
 
57
        internal class ParserDatabase: IParserDatabase
 
58
        {
 
59
                static readonly string[] sharedNameTable = new string[] {
 
60
                        "", // 505195
 
61
                        "System.Void", // 116020
 
62
                        "To be added", // 78598
 
63
                        "System.Int32", // 72669
 
64
                        "System.String", // 72097
 
65
                        "System.Object", // 48530
 
66
                        "System.Boolean", // 46200
 
67
                        ".ctor", // 39938
 
68
                        "System.IntPtr", // 35184
 
69
                        "To be added.", // 19082
 
70
                        "value", // 11906
 
71
                        "System.Byte", // 8524
 
72
                        "To be added: an object of type 'string'", // 7928
 
73
                        "e", // 7858
 
74
                        "raw", // 7830
 
75
                        "System.IAsyncResult", // 7760
 
76
                        "System.Type", // 7518
 
77
                        "name", // 7188
 
78
                        "object", // 6982
 
79
                        "System.UInt32", // 6966
 
80
                        "index", // 6038
 
81
                        "To be added: an object of type 'int'", // 5196
 
82
                        "System.Int64", // 4166
 
83
                        "callback", // 4158
 
84
                        "System.EventArgs", // 4140
 
85
                        "method", // 4030
 
86
                        "System.Enum", // 3980
 
87
                        "value__", // 3954
 
88
                        "Invoke", // 3906
 
89
                        "result", // 3856
 
90
                        "System.AsyncCallback", // 3850
 
91
                        "System.MulticastDelegate", // 3698
 
92
                        "BeginInvoke", // 3650
 
93
                        "EndInvoke", // 3562
 
94
                        "node", // 3416
 
95
                        "sender", // 3398
 
96
                        "context", // 3310
 
97
                        "System.EventHandler", // 3218
 
98
                        "System.Double", // 3206
 
99
                        "type", // 3094
 
100
                        "x", // 3056
 
101
                        "System.Single", // 2940
 
102
                        "data", // 2930
 
103
                        "args", // 2926
 
104
                        "System.Char", // 2813
 
105
                        "Gdk.Key", // 2684
 
106
                        "ToString", // 2634
 
107
                        "'a", // 2594
 
108
                        "System.Drawing.Color", // 2550
 
109
                        "y", // 2458
 
110
                        "To be added: an object of type 'object'", // 2430
 
111
                        "System.DateTime", // 2420
 
112
                        "message", // 2352
 
113
                        "GLib.GType", // 2292
 
114
                        "o", // 2280
 
115
                        "a <see cref=\"T:System.Int32\" />", // 2176
 
116
                        "path", // 2062
 
117
                        "obj", // 2018
 
118
                        "Nemerle.Core.list`1", // 1950
 
119
                        "System.Windows.Forms", // 1942
 
120
                        "System.Collections.ArrayList", // 1918
 
121
                        "a <see cref=\"T:System.String\" />", // 1894
 
122
                        "key", // 1868
 
123
                        "Add", // 1864
 
124
                        "arg0", // 1796
 
125
                        "System.IO.Stream", // 1794
 
126
                        "s", // 1784
 
127
                        "arg1", // 1742
 
128
                        "provider", // 1704
 
129
                        "System.UInt64", // 1700
 
130
                        "System.Drawing.Rectangle", // 1684
 
131
                        "System.IFormatProvider", // 1684
 
132
                        "gch", // 1680
 
133
                        "System.Exception", // 1652
 
134
                        "Equals", // 1590
 
135
                        "System.Drawing.Pen", // 1584
 
136
                        "count", // 1548
 
137
                        "System.Collections.IEnumerator", // 1546
 
138
                        "info", // 1526
 
139
                        "Name", // 1512
 
140
                        "System.Attribute", // 1494
 
141
                        "gtype", // 1470
 
142
                        "To be added: an object of type 'Type'", // 1444
 
143
                        "System.Collections.Hashtable", // 1416
 
144
                        "array", // 1380
 
145
                        "System.Int16", // 1374
 
146
                        "Gtk", // 1350
 
147
                        "System.ComponentModel.ITypeDescriptorContext", // 1344
 
148
                        "System.Collections.ICollection", // 1330
 
149
                        "Dispose", // 1330
 
150
                        "Gtk.Widget", // 1326
 
151
                        "System.Runtime.Serialization.StreamingContext", // 1318
 
152
                        "Nemerle.Compiler.Parsetree.PExpr", // 1312
 
153
                        "System.Guid", // 1310
 
154
                        "i", // 1302
 
155
                        "Gtk.TreeIter", // 1300
 
156
                        "text", // 1290
 
157
                        "System.Runtime.Serialization.SerializationInfo", // 1272
 
158
                        "state", // 1264
 
159
                        "Remove" // 1256
 
160
                };
 
161
                
 
162
                public ParserDatabase ()
 
163
                {
 
164
                        Array.Sort (sharedNameTable);
 
165
                }
 
166
 
 
167
                public void Initialize ()
 
168
                {
 
169
                        DeleteObsoleteDatabases ();
 
170
                }
 
171
 
 
172
 
 
173
                public ProjectDom LoadSingleFileDom (string file)
 
174
                {
 
175
                        return new DatabaseProjectDom (this, new SimpleCodeCompletionDatabase (file, this));
 
176
                }
 
177
 
 
178
                public ProjectDom LoadAssemblyDom (TargetRuntime runtime, TargetFramework fx, string file)
 
179
                {
 
180
                        return new DatabaseProjectDom (this, new AssemblyCodeCompletionDatabase (runtime, fx, file, this));
 
181
                }
 
182
 
 
183
                public ProjectDom LoadProjectDom (Project project)
 
184
                {
 
185
                        DatabaseProjectDom dom = new DatabaseProjectDom (this, new ProjectCodeCompletionDatabase (project, this));
 
186
                        dom.Project = project;
 
187
                        return dom;
 
188
                }
 
189
                
 
190
                void DeleteObsoleteDatabases ()
 
191
                {
 
192
                        string[] files = Directory.GetFiles (ProjectDomService.CodeCompletionPath, "*.pidb");
 
193
                        foreach (string file in files)
 
194
                        {
 
195
                                string name = Path.GetFileNameWithoutExtension (file);
 
196
                                string baseDir = Path.GetDirectoryName (file);
 
197
                                AssemblyCodeCompletionDatabase.CleanDatabase (baseDir, name);
 
198
                        }
 
199
                }
 
200
                
 
201
 
 
202
                
 
203
#region Default Parser Layer dependent functions
 
204
 
 
205
                public IType GetClass (SerializationCodeCompletionDatabase db, string typeName, IList<IReturnType> genericArguments, bool deepSearchReferences, bool caseSensitive)
 
206
                {
 
207
                        if (deepSearchReferences)
 
208
                                return DeepGetClass (db, typeName, genericArguments, caseSensitive);
 
209
                        else
 
210
                                return GetClass (db, typeName, genericArguments, caseSensitive);
 
211
                }
 
212
                
 
213
                IType GetClass (SerializationCodeCompletionDatabase db, string typeName, IList<IReturnType> genericArguments, bool caseSensitive)
 
214
                {
 
215
                        if (db != null) {
 
216
                                IType c = db.GetClass (typeName, genericArguments, caseSensitive);
 
217
                                if (c != null) return c;
 
218
                                foreach (ReferenceEntry re in db.References)
 
219
                                {
 
220
                                        SerializationCodeCompletionDatabase cdb = GetDatabase (re.Uri);
 
221
                                        if (cdb == null) continue;
 
222
                                        c = cdb.GetClass (typeName, genericArguments, caseSensitive);
 
223
                                        if (c != null) return c;
 
224
                                }
 
225
                        }
 
226
                        return null;
 
227
                }
 
228
                
 
229
                public IType DeepGetClass (SerializationCodeCompletionDatabase db, string typeName, IList<IReturnType> genericArguments, bool caseSensitive)
 
230
                {
 
231
                        if (db == null) return null;
 
232
                        
 
233
                        IType c = db.GetClass (typeName, genericArguments, caseSensitive);
 
234
                        if (c != null) return c;
 
235
                        
 
236
                        foreach (ReferenceEntry re in db.References)
 
237
                        {
 
238
                                SerializationCodeCompletionDatabase cdb = GetDatabase (re.Uri);
 
239
                                if (cdb == null) continue;
 
240
                                // deep get class should only go to depth 1, to prevent type lookup errors in the form:
 
241
                                // A -> B -> C v1.0 / A -> C v2.0 & getTypeName from assembly C. If C isn't referenced directly
 
242
                                // it's impossible to get types from assembly A, therefore DeepGetClassRec is incorrect here.
 
243
                                c = cdb.GetClass (typeName, genericArguments, caseSensitive);
 
244
//                              c = DeepGetClassRec (visitedDbs, cdb, typeName, genericArguments, caseSensitive);
 
245
                                if (c != null) return c;
 
246
                        }
 
247
                        return null;
 
248
                }
 
249
                
 
250
/*              public string SearchNamespace (SerializationCodeCompletionDatabase db, IUsing usin, string partitialNamespaceName)
 
251
                {
 
252
                        return SearchNamespace (db, usin, partitialNamespaceName, true);
 
253
                }
 
254
                
 
255
                public string SearchNamespace (SerializationCodeCompletionDatabase db, IUsing usin, string partitialNamespaceName, bool caseSensitive)
 
256
                {
 
257
//                      LoggingService.LogDebug ("SearchNamespace : >{0}<", partitialNamespaceName);
 
258
                        if (NamespaceExists (db, partitialNamespaceName, caseSensitive)) {
 
259
                                return partitialNamespaceName;
 
260
                        }
 
261
                        
 
262
                        // search for partitial namespaces
 
263
                        IReturnType alias;
 
264
                        if (usin.Aliases.TryGetValue ("", out alias)) {
 
265
                                string declaringNamespace = alias.FullName;
 
266
                                while (declaringNamespace.Length > 0) {
 
267
                                        if ((caseSensitive ? declaringNamespace.EndsWith(partitialNamespaceName) : declaringNamespace.ToLower().EndsWith(partitialNamespaceName.ToLower()) ) && NamespaceExists (db, declaringNamespace, caseSensitive)) {
 
268
                                                return declaringNamespace;
 
269
                                        }
 
270
                                        int index = declaringNamespace.IndexOf('.');
 
271
                                        if (index > 0) {
 
272
                                                declaringNamespace = declaringNamespace.Substring(0, index);
 
273
                                        } else {
 
274
                                                break;
 
275
                                        }
 
276
                                }
 
277
                        }
 
278
                        
 
279
                        // Remember:
 
280
                        //     Each namespace has an own using object
 
281
                        //     The namespace name is an alias which has the key ""
 
282
                        foreach (string aliasString in usin.Aliases.Keys) {
 
283
                                if (caseSensitive ? partitialNamespaceName.StartsWith (aliasString) : partitialNamespaceName.ToLower().StartsWith(aliasString.ToLower())) {
 
284
                                        if (aliasString.Length > 0) {
 
285
                                                string nsName = String.Concat (usin.Aliases [aliasString], partitialNamespaceName.Remove(0, aliasString.Length));
 
286
                                                if (NamespaceExists (db, nsName, caseSensitive)) {
 
287
                                                        return nsName;
 
288
                                                }
 
289
                                        }
 
290
                                }
 
291
                        }
 
292
                        return null;
 
293
                }
 
294
*/
 
295
                
 
296
                public IEnumerable<IType> GetSubclassesTree (SerializationCodeCompletionDatabase db,
 
297
                                                             IType cls,
 
298
                                                             bool deepSearchReferences, 
 
299
                                                             IList<string> namespaces)
 
300
                {
 
301
                        if (cls.FullName == "System.Object") {
 
302
                                // Just return all classes
 
303
                                if (!deepSearchReferences)
 
304
                                        return db.GetClassList (true, namespaces);
 
305
                                else
 
306
                                        return GetAllClassesRec (new HashSet<SerializationCodeCompletionDatabase> (), db, namespaces);
 
307
                        }
 
308
                        else {
 
309
                                var visited = new Dictionary<SerializationCodeCompletionDatabase, HashSet<IType>> ();
 
310
                                SearchSubclasses (visited, cls, namespaces, db);
 
311
        
 
312
                                if (deepSearchReferences) {
 
313
                                        List<IType> types = new List<IType> ();
 
314
                                        foreach (HashSet<IType> list in visited.Values) {
 
315
                                                // Don't use AddRange here. It won't work due to a bug in mono (#459816).
 
316
                                                foreach (IType tt in list)
 
317
                                                        types.Add (tt);
 
318
                                        }
 
319
                                        return types;
 
320
                                } else {
 
321
                                        return visited [db];
 
322
                                }
 
323
                        }
 
324
                }
 
325
 
 
326
                IEnumerable<IType> GetAllClassesRec (HashSet<SerializationCodeCompletionDatabase> visited, SerializationCodeCompletionDatabase db, IList<string> namespaces)
 
327
                {
 
328
                        if (visited.Add (db)) {
 
329
                                foreach (IType dsub in db.GetClassList (true, namespaces))
 
330
                                        yield return dsub;
 
331
                                foreach (ReferenceEntry re in db.References) {
 
332
                                        SerializationCodeCompletionDatabase cdb = GetDatabase (re.Uri);
 
333
                                        if (cdb == null) continue;
 
334
                                        foreach (IType dsub in GetAllClassesRec (visited, cdb, namespaces))
 
335
                                                yield return dsub;
 
336
                                }
 
337
                        }
 
338
                }
 
339
 
 
340
                HashSet<IType> SearchSubclasses (Dictionary<SerializationCodeCompletionDatabase, HashSet<IType>> visited, IType btype, IList<string> namespaces, SerializationCodeCompletionDatabase db)
 
341
                {
 
342
                        HashSet<IType> types;
 
343
                        if (visited.TryGetValue (db, out types))
 
344
                                return types;
 
345
 
 
346
                        types = new HashSet<IType> (GetSubclassesTree (db, btype, namespaces));
 
347
                        visited [db] = types;
 
348
 
 
349
                        // For each reference, get the list of subclasses implemented in that reference,
 
350
                        // then look for subclasses of any of those in the current db
 
351
 
 
352
                        // A project can only have subclasses of classes implemented in assemblies it references
 
353
                        
 
354
                        foreach (ReferenceEntry re in db.References) {
 
355
                                SerializationCodeCompletionDatabase cdb = GetDatabase (re.Uri);
 
356
                                if (cdb != null && cdb != db) {
 
357
                                        HashSet<IType> refTypes = SearchSubclasses (visited, btype, namespaces, cdb);
 
358
                                        foreach (IType t in refTypes)
 
359
                                                foreach (IType st in GetSubclassesTree (db, t, namespaces))
 
360
                                                        types.Add (st);
 
361
                                }
 
362
                        }
 
363
 
 
364
                        return types;
 
365
                }
 
366
 
 
367
                IEnumerable<IType> GetSubclassesTree (SerializationCodeCompletionDatabase db, IType btype, IList<string> namespaces)
 
368
                {
 
369
                        foreach (IType dsub in db.GetSubclasses (btype, namespaces)) {
 
370
                                yield return dsub;
 
371
                                foreach (IType sub in GetSubclassesTree (db, dsub, namespaces))
 
372
                                        yield return sub;
 
373
                        }
 
374
                }
 
375
                
 
376
                public SerializationCodeCompletionDatabase GetDatabase (string uri)
 
377
                {
 
378
                        try {
 
379
                                DatabaseProjectDom dom = ProjectDomService.GetDomForUri (uri) as DatabaseProjectDom;
 
380
                                if (dom != null)
 
381
                                        return dom.Database;
 
382
                        } catch (Exception e) {
 
383
                                LoggingService.LogError ("Can't load assembly: " + uri, e);
 
384
                        }
 
385
                        return null;
 
386
                }
 
387
                
 
388
#endregion
 
389
 
 
390
                internal static string GetDecoratedName (string name, int genericArgumentCount)
 
391
                {
 
392
                        if (genericArgumentCount <= 0)
 
393
                                return name;
 
394
                        return name + "`" + genericArgumentCount;
 
395
                }
 
396
                
 
397
                internal static string GetDecoratedName (ClassEntry entry)
 
398
                {
 
399
                        return GetDecoratedName (entry.Name, entry.TypeParameterCount);
 
400
                }
 
401
 
 
402
                internal static string GetDecoratedName (IType type)
 
403
                {
 
404
                        return GetDecoratedName (type.FullName, type.TypeParameters.Count);
 
405
                }
 
406
 
 
407
                internal static string GetDecoratedName (IReturnType type)
 
408
                {
 
409
                        return ((DomReturnType)type).DecoratedFullName;
 
410
                }
 
411
 
 
412
                
 
413
                ////////////////////////////////////
 
414
                
 
415
                internal INameEncoder CreateNameEncoder ()
 
416
                {
 
417
                        return new StringNameTable (sharedNameTable);
 
418
                }
 
419
 
 
420
                internal INameDecoder CreateNameDecoder ()
 
421
                {
 
422
                        return new StringNameTable (sharedNameTable);
 
423
                }
 
424
        }
 
425
}