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

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.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
// SolutionItem.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
using System;
 
29
using System.Collections;
 
30
using System.Collections.Generic;
 
31
using System.Collections.ObjectModel;
 
32
using System.Xml;
 
33
using System.CodeDom.Compiler;
 
34
using MonoDevelop.Core;
 
35
using MonoDevelop.Core.Serialization;
 
36
using MonoDevelop.Projects.Extensions;
 
37
using MonoDevelop.Core.Collections;
 
38
using MonoDevelop.Core.StringParsing;
 
39
using MonoDevelop.Core.Instrumentation;
 
40
 
 
41
namespace MonoDevelop.Projects
 
42
{
 
43
        public abstract class SolutionItem: IExtendedDataItem, IBuildTarget, ILoadController
 
44
        {
 
45
                SolutionFolder parentFolder;
 
46
                Solution parentSolution;
 
47
                ISolutionItemHandler handler;
 
48
                int loading;
 
49
                SolutionFolder internalChildren;
 
50
                
 
51
                [ProjectPathItemProperty ("BaseDirectory", DefaultValue=null)]
 
52
                string baseDirectory;
 
53
                
 
54
                Hashtable extendedProperties;
 
55
                
 
56
                [ItemProperty ("Policies", IsExternal = true, SkipEmpty = true)]
 
57
                MonoDevelop.Projects.Policies.PolicyBag policies;
 
58
                
 
59
                PropertyBag userProperties;
 
60
                
 
61
                public SolutionItem()
 
62
                {
 
63
                        ProjectExtensionUtil.LoadControl (this);
 
64
                }
 
65
                
 
66
                public virtual void InitializeFromTemplate (XmlElement template)
 
67
                {
 
68
                }
 
69
                
 
70
                protected internal ISolutionItemHandler ItemHandler {
 
71
                        get {
 
72
                                if (handler == null) {
 
73
                                        InitializeItemHandler ();
 
74
                                        if (handler == null)
 
75
                                                throw new InvalidOperationException ("No handler found for solution item of type: " + GetType ());
 
76
                                }
 
77
                                return handler; 
 
78
                        }
 
79
                }
 
80
                
 
81
                internal virtual void SetItemHandler (ISolutionItemHandler handler)
 
82
                {
 
83
                        if (this.handler != null)
 
84
                                this.handler.Dispose ();
 
85
                        this.handler = handler;
 
86
                }
 
87
                
 
88
                internal ISolutionItemHandler GetItemHandler ()
 
89
                {
 
90
                        // Used to get the handler without lazy loading it
 
91
                        return this.handler;
 
92
                }
 
93
                
 
94
                public T GetService<T> () where T: class
 
95
                {
 
96
                        return (T) GetService (typeof(T));
 
97
                }
 
98
                
 
99
                public virtual object GetService (Type t)
 
100
                {
 
101
                        if (t.IsInstanceOfType (this))
 
102
                                return this;
 
103
                        return Services.ProjectService.GetExtensionChain (this).GetService (this, t);
 
104
                }
 
105
                
 
106
                public Solution ParentSolution {
 
107
                        get {
 
108
                                if (parentFolder != null)
 
109
                                        return parentFolder.ParentSolution;
 
110
                                return parentSolution; 
 
111
                        }
 
112
                        internal set {
 
113
                                parentSolution = value;
 
114
                        }
 
115
                }
 
116
                
 
117
                public bool Loading {
 
118
                        get { return loading > 0; }
 
119
                }
 
120
                
 
121
                public abstract void Save (IProgressMonitor monitor);
 
122
                
 
123
                public abstract string Name { get; set; }
 
124
                
 
125
                public FilePath BaseDirectory {
 
126
                        get {
 
127
                                if (baseDirectory == null) {
 
128
                                        FilePath dir = GetDefaultBaseDirectory ();
 
129
                                        if (dir.IsNullOrEmpty)
 
130
                                                dir = ".";
 
131
                                        return dir.FullPath;
 
132
                                }
 
133
                                else
 
134
                                        return baseDirectory;
 
135
                        }
 
136
                        set {
 
137
                                FilePath def = GetDefaultBaseDirectory ();
 
138
                                if (value != FilePath.Null && def != FilePath.Null && value.FullPath == def.FullPath)
 
139
                                        baseDirectory = null;
 
140
                                else if (string.IsNullOrEmpty (value))
 
141
                                        baseDirectory = null;
 
142
                                else
 
143
                                        baseDirectory = value.FullPath;
 
144
                                NotifyModified ("BaseDirectory");
 
145
                        }
 
146
                }
 
147
                
 
148
                public FilePath ItemDirectory {
 
149
                        get {
 
150
                                FilePath dir = GetDefaultBaseDirectory ();
 
151
                                if (string.IsNullOrEmpty (dir))
 
152
                                        dir = ".";
 
153
                                return dir.FullPath;
 
154
                        }
 
155
                }
 
156
                
 
157
                internal bool HasCustomBaseDirectory {
 
158
                        get { return baseDirectory != null; }
 
159
                }
 
160
 
 
161
                protected virtual FilePath GetDefaultBaseDirectory ( )
 
162
                {
 
163
                        return ParentSolution.BaseDirectory;
 
164
                }
 
165
                
 
166
                public string ItemId {
 
167
                        get { return ItemHandler.ItemId; }
 
168
                }
 
169
                
 
170
                public IDictionary ExtendedProperties {
 
171
                        get { return InternalGetExtendedProperties; }
 
172
                }
 
173
                
 
174
                public MonoDevelop.Projects.Policies.PolicyBag Policies {
 
175
                        get {
 
176
                                //newly created (i.e. not deserialised) SolutionItems may have a null PolicyBag
 
177
                                if (policies == null)
 
178
                                        policies = new MonoDevelop.Projects.Policies.PolicyBag ();
 
179
                                //this is the easiest reliable place to associate a deserialised Policybag with its owner
 
180
                                policies.Owner = this;
 
181
                                return policies;
 
182
                        }
 
183
                        //setter so that a solution can deserialise the PropertyBag on its RootFolder
 
184
                        internal set {
 
185
                                policies = value;
 
186
                        }
 
187
                }
 
188
                
 
189
                // User properties are only loaded when the project is loaded in the IDE.
 
190
                public PropertyBag UserProperties {
 
191
                        get {
 
192
                                if (userProperties == null)
 
193
                                        userProperties = new PropertyBag ();
 
194
                                return userProperties; 
 
195
                        }
 
196
                }
 
197
                
 
198
                // Initializes the user properties of the item
 
199
                public void LoadUserProperties (PropertyBag properties)
 
200
                {
 
201
                        if (userProperties != null)
 
202
                                throw new InvalidOperationException ("User properties already loaded.");
 
203
                        userProperties = properties;
 
204
                }
 
205
                
 
206
                public SolutionFolder ParentFolder {
 
207
                        get {
 
208
                                return parentFolder;
 
209
                        }
 
210
                        internal set {
 
211
                                parentFolder = value;
 
212
                                if (internalChildren != null)
 
213
                                        internalChildren.ParentFolder = value;
 
214
                        }
 
215
                }
 
216
                
 
217
                public virtual void Dispose ()
 
218
                {
 
219
                        if (extendedProperties != null) {
 
220
                                foreach (object ob in extendedProperties.Values) {
 
221
                                        IDisposable disp = ob as IDisposable;
 
222
                                        if (disp != null)
 
223
                                                disp.Dispose ();
 
224
                                }
 
225
                        }
 
226
                        if (handler != null)
 
227
                                handler.Dispose ();
 
228
                        if (userProperties != null)
 
229
                                ((IDisposable)userProperties).Dispose ();
 
230
                }
 
231
                
 
232
                public virtual IEnumerable<SolutionItem> GetReferencedItems (ConfigurationSelector configuration)
 
233
                {
 
234
                        return new SolutionItem [0];
 
235
                }
 
236
                
 
237
                public virtual BuildResult RunTarget (IProgressMonitor monitor, string target, ConfigurationSelector configuration)
 
238
                {
 
239
                        return Services.ProjectService.GetExtensionChain (this).RunTarget (monitor, this, target, configuration);
 
240
                }
 
241
                
 
242
                public void Clean (IProgressMonitor monitor, ConfigurationSelector configuration)
 
243
                {
 
244
                        RunTarget (monitor, ProjectService.CleanTarget, configuration);
 
245
                }
 
246
                
 
247
                public BuildResult Build (IProgressMonitor monitor, ConfigurationSelector configuration)
 
248
                {
 
249
                        return Build (monitor, configuration, false);
 
250
                }
 
251
                
 
252
                public BuildResult Build (IProgressMonitor monitor, ConfigurationSelector solutionConfiguration, bool buildReferences)
 
253
                {
 
254
                        ITimeTracker tt = Counters.BuildProjectTimer.BeginTiming ("Building " + Name);
 
255
                        try {
 
256
                                if (!buildReferences) {
 
257
                                        if (!NeedsBuilding (solutionConfiguration))
 
258
                                                return new BuildResult (new CompilerResults (null), "");
 
259
                                                
 
260
                                        try {
 
261
                                                SolutionEntityItem it = this as SolutionEntityItem;
 
262
                                                SolutionItemConfiguration iconf = it != null ? it.GetConfiguration (solutionConfiguration) : null;
 
263
                                                string confName = iconf != null ? iconf.Id : solutionConfiguration.ToString ();
 
264
                                                monitor.BeginTask (GettextCatalog.GetString ("Building: {0} ({1})", Name, confName), 1);
 
265
                                                
 
266
                                                // This will end calling OnBuild ()
 
267
                                                return RunTarget (monitor, ProjectService.BuildTarget, solutionConfiguration);
 
268
                                                
 
269
                                        } finally {
 
270
                                                monitor.EndTask ();
 
271
                                        }
 
272
                                }
 
273
                                        
 
274
                                // Get a list of all items that need to be built (including this),
 
275
                                // and build them in the correct order
 
276
                                
 
277
                                List<SolutionItem> referenced = new List<SolutionItem> ();
 
278
                                Set<SolutionItem> visited = new Set<SolutionItem> ();
 
279
                                GetBuildableReferencedItems (visited, referenced, this, solutionConfiguration);
 
280
                                
 
281
                                ReadOnlyCollection<SolutionItem> sortedReferenced = SolutionFolder.TopologicalSort (referenced, solutionConfiguration);
 
282
                                
 
283
                                BuildResult cres = new BuildResult ();
 
284
                                cres.BuildCount = 0;
 
285
                                HashSet<SolutionItem> failedItems = new HashSet<SolutionItem> ();
 
286
                                
 
287
                                monitor.BeginTask (null, sortedReferenced.Count);
 
288
                                foreach (SolutionItem p in sortedReferenced) {
 
289
                                        if (p.NeedsBuilding (solutionConfiguration) && !p.ContainsReferences (failedItems, solutionConfiguration)) {
 
290
                                                BuildResult res = p.Build (monitor, solutionConfiguration, false);
 
291
                                                cres.Append (res);
 
292
                                                if (res.ErrorCount > 0)
 
293
                                                        failedItems.Add (p);
 
294
                                        } else
 
295
                                                failedItems.Add (p);
 
296
                                        monitor.Step (1);
 
297
                                        if (monitor.IsCancelRequested)
 
298
                                                break;
 
299
                                }
 
300
                                monitor.EndTask ();
 
301
                                return cres;
 
302
                        } finally {
 
303
                                tt.End ();
 
304
                        }
 
305
                }
 
306
                
 
307
                internal bool ContainsReferences (HashSet<SolutionItem> items, ConfigurationSelector conf)
 
308
                {
 
309
                        foreach (SolutionItem it in GetReferencedItems (conf))
 
310
                                if (items.Contains (it))
 
311
                                        return true;
 
312
                        return false;
 
313
                }
 
314
                
 
315
                public DateTime GetLastBuildTime (ConfigurationSelector configuration)
 
316
                {
 
317
                        return OnGetLastBuildTime (configuration);
 
318
                }
 
319
                
 
320
                void GetBuildableReferencedItems (Set<SolutionItem> visited, List<SolutionItem> referenced, SolutionItem item, ConfigurationSelector configuration)
 
321
                {
 
322
                        if (!visited.Add(item))
 
323
                                return;
 
324
                        
 
325
                        if (item.NeedsBuilding (configuration))
 
326
                                referenced.Add (item);
 
327
 
 
328
                        foreach (SolutionItem ritem in item.GetReferencedItems (configuration))
 
329
                                GetBuildableReferencedItems (visited, referenced, ritem, configuration);
 
330
                }
 
331
                
 
332
                public void Execute (IProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
 
333
                {
 
334
                        Services.ProjectService.GetExtensionChain (this).Execute (monitor, this, context, configuration);
 
335
                }
 
336
                
 
337
                public bool CanExecute (ExecutionContext context, ConfigurationSelector configuration)
 
338
                {
 
339
                        return Services.ProjectService.GetExtensionChain (this).CanExecute (this, context, configuration);
 
340
                }
 
341
                
 
342
                public bool NeedsBuilding (ConfigurationSelector configuration)
 
343
                {
 
344
                        using (Counters.NeedsBuildingTimer.BeginTiming ("NeedsBuilding check for " + Name)) {
 
345
                                if (ParentSolution != null && this is SolutionEntityItem) {
 
346
                                        SolutionConfiguration sconf = ParentSolution.GetConfiguration (configuration);
 
347
                                        if (sconf != null && !sconf.BuildEnabledForItem ((SolutionEntityItem) this))
 
348
                                                return false;
 
349
                                }
 
350
                                return Services.ProjectService.GetExtensionChain (this).GetNeedsBuilding (this, configuration);
 
351
                        }
 
352
                }
 
353
                
 
354
                public void SetNeedsBuilding (bool value, ConfigurationSelector configuration)
 
355
                {
 
356
                        Services.ProjectService.GetExtensionChain (this).SetNeedsBuilding (this, value, configuration);
 
357
                }
 
358
                
 
359
                public virtual bool NeedsReload {
 
360
                        get {
 
361
                                if (ParentSolution != null)
 
362
                                        return ParentSolution.NeedsReload;
 
363
                                else
 
364
                                        return false;
 
365
                        }
 
366
                        set {
 
367
                        }
 
368
                }
 
369
                
 
370
                protected void RegisterInternalChild (SolutionItem item)
 
371
                {
 
372
                        if (internalChildren == null) {
 
373
                                internalChildren = new SolutionFolder ();
 
374
                                internalChildren.ParentFolder = parentFolder;
 
375
                        }
 
376
                        internalChildren.Items.Add (item);
 
377
                }
 
378
                
 
379
                protected void UnregisterInternalChild (SolutionItem item)
 
380
                {
 
381
                        if (internalChildren != null)
 
382
                                internalChildren.Items.Remove (item);
 
383
                }
 
384
                
 
385
                public virtual StringTagModelDescription GetStringTagModelDescription (ConfigurationSelector conf)
 
386
                {
 
387
                        StringTagModelDescription model = new StringTagModelDescription ();
 
388
                        model.Add (GetType ());
 
389
                        model.Add (typeof(Solution));
 
390
                        return model;
 
391
                }
 
392
                
 
393
                public virtual StringTagModel GetStringTagModel (ConfigurationSelector conf)
 
394
                {
 
395
                        StringTagModel source = new StringTagModel ();
 
396
                        source.Add (this);
 
397
                        if (ParentSolution != null)
 
398
                                source.Add (ParentSolution.GetStringTagModel ());
 
399
                        return source;
 
400
                }
 
401
                
 
402
                public static ReadOnlyCollection<T> TopologicalSort<T> (IEnumerable<T> items, ConfigurationSelector configuration) where T: SolutionItem
 
403
                {
 
404
                        IList<T> allItems;
 
405
                        allItems = items as IList<T>;
 
406
                        if (allItems == null)
 
407
                                allItems = new List<T> (items);
 
408
                        
 
409
                        List<T> sortedEntries = new List<T> ();
 
410
                        bool[] inserted = new bool[allItems.Count];
 
411
                        bool[] triedToInsert = new bool[allItems.Count];
 
412
                        for (int i = 0; i < allItems.Count; ++i) {
 
413
                                if (!inserted[i])
 
414
                                        Insert<T> (i, allItems, sortedEntries, inserted, triedToInsert, configuration);
 
415
                        }
 
416
                        return sortedEntries.AsReadOnly ();
 
417
                }
 
418
                
 
419
                static void Insert<T> (int index, IList<T> allItems, List<T> sortedItems, bool[] inserted, bool[] triedToInsert, ConfigurationSelector solutionConfiguration) where T: SolutionItem
 
420
                {
 
421
                        if (triedToInsert[index]) {
 
422
                                throw new CyclicDependencyException ();
 
423
                        }
 
424
                        triedToInsert[index] = true;
 
425
                        SolutionItem insertItem = allItems[index];
 
426
                        
 
427
                        foreach (SolutionItem reference in insertItem.GetReferencedItems (solutionConfiguration)) {
 
428
                                for (int j=0; j < allItems.Count; ++j) {
 
429
                                        SolutionItem checkItem = allItems[j];
 
430
                                        if (reference == checkItem) {
 
431
                                                if (!inserted[j])
 
432
                                                        Insert (j, allItems, sortedItems, inserted, triedToInsert, solutionConfiguration);
 
433
                                                break;
 
434
                                        }
 
435
                                }
 
436
                        }
 
437
                        sortedItems.Add ((T)insertItem);
 
438
                        inserted[index] = true;
 
439
                }
 
440
                
 
441
                internal virtual IDictionary InternalGetExtendedProperties {
 
442
                        get {
 
443
                                if (extendedProperties == null)
 
444
                                        extendedProperties = new Hashtable ();
 
445
                                return extendedProperties;
 
446
                        }
 
447
                }
 
448
                
 
449
                void ILoadController.BeginLoad ()
 
450
                {
 
451
                        loading++;
 
452
                        OnBeginLoad ();
 
453
                }
 
454
                
 
455
                void ILoadController.EndLoad ()
 
456
                {
 
457
                        loading--;
 
458
                        OnEndLoad ();
 
459
                }
 
460
                
 
461
                protected virtual void OnBeginLoad ()
 
462
                {
 
463
                }
 
464
                
 
465
                protected virtual void OnEndLoad ()
 
466
                {
 
467
                }
 
468
                
 
469
                protected void NotifyModified (string hint)
 
470
                {
 
471
                        OnModified (new SolutionItemModifiedEventArgs (this, hint));
 
472
                }
 
473
                
 
474
                protected virtual void OnModified (SolutionItemModifiedEventArgs args)
 
475
                {
 
476
                        if (Modified != null)
 
477
                                Modified (this, args);
 
478
                }
 
479
                
 
480
                protected virtual void OnNameChanged (SolutionItemRenamedEventArgs e)
 
481
                {
 
482
                        NotifyModified ("Name");
 
483
                        if (NameChanged != null)
 
484
                                NameChanged (this, e);
 
485
                }
 
486
                
 
487
                protected virtual void InitializeItemHandler ()
 
488
                {
 
489
                }
 
490
                
 
491
                
 
492
                internal protected abstract void OnClean (IProgressMonitor monitor, ConfigurationSelector configuration);
 
493
                internal protected abstract BuildResult OnBuild (IProgressMonitor monitor, ConfigurationSelector configuration);
 
494
                internal protected abstract void OnExecute (IProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration);
 
495
                internal protected abstract bool OnGetNeedsBuilding (ConfigurationSelector configuration);
 
496
                internal protected abstract void OnSetNeedsBuilding (bool val, ConfigurationSelector configuration);
 
497
                
 
498
                internal protected virtual DateTime OnGetLastBuildTime (ConfigurationSelector configuration)
 
499
                {
 
500
                        return DateTime.MinValue;
 
501
                }
 
502
                
 
503
                internal protected virtual bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration)
 
504
                {
 
505
                        return false;
 
506
                }
 
507
                
 
508
                public event SolutionItemRenamedEventHandler NameChanged;
 
509
                public event SolutionItemModifiedEventHandler Modified;
 
510
        }
 
511
        
 
512
        [Mono.Addins.Extension]
 
513
        class SolutionItemTagProvider: StringTagProvider<SolutionItem>, IStringTagProvider
 
514
        {
 
515
                public override IEnumerable<StringTagDescription> GetTags ()
 
516
                {
 
517
                        yield return new StringTagDescription ("ProjectName", "Project Name");
 
518
                        yield return new StringTagDescription ("ProjectDir", "Project Directory");
 
519
                }
 
520
                
 
521
                public override object GetTagValue (SolutionItem item, string tag)
 
522
                {
 
523
                        switch (tag) {
 
524
                                case "ITEMNAME":
 
525
                                case "PROJECTNAME":
 
526
                                        return item.Name;
 
527
                                case "ITEMDIR":
 
528
                                case "PROJECTDIR":
 
529
                                        return item.BaseDirectory;
 
530
                        }
 
531
                        throw new NotSupportedException ();
 
532
                }
 
533
        }
 
534
}