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

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Projects/MonoDevelop.Projects/SolutionItem.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
// 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
 
 
38
namespace MonoDevelop.Projects
 
39
{
 
40
        public abstract class SolutionItem: IExtendedDataItem, IBuildTarget, ILoadController
 
41
        {
 
42
                SolutionFolder parentFolder;
 
43
                Solution parentSolution;
 
44
                ISolutionItemHandler handler;
 
45
                int loading;
 
46
                
 
47
                [ProjectPathItemProperty ("BaseDirectory", DefaultValue=null)]
 
48
                string baseDirectory;
 
49
                
 
50
                Hashtable extendedProperties;
 
51
                
 
52
                [ItemProperty ("Policies", IsExternal = true, SkipEmpty = true)]
 
53
                MonoDevelop.Projects.Policies.PolicyBag policies;
 
54
                
 
55
                public SolutionItem()
 
56
                {
 
57
                        ProjectExtensionUtil.LoadControl (this);
 
58
                }
 
59
                
 
60
                public virtual void InitializeFromTemplate (XmlElement template)
 
61
                {
 
62
                }
 
63
                
 
64
                protected internal ISolutionItemHandler ItemHandler {
 
65
                        get {
 
66
                                if (handler == null) {
 
67
                                        InitializeItemHandler ();
 
68
                                        if (handler == null)
 
69
                                                throw new InvalidOperationException ("No handler found for solution item of type: " + GetType ());
 
70
                                }
 
71
                                return handler; 
 
72
                        }
 
73
                }
 
74
                
 
75
                internal virtual void SetItemHandler (ISolutionItemHandler handler)
 
76
                {
 
77
                        if (this.handler != null)
 
78
                                this.handler.Dispose ();
 
79
                        this.handler = handler;
 
80
                }
 
81
                
 
82
                internal ISolutionItemHandler GetItemHandler ()
 
83
                {
 
84
                        // Used to get the handler without lazy loading it
 
85
                        return this.handler;
 
86
                }
 
87
                
 
88
                public Solution ParentSolution {
 
89
                        get {
 
90
                                if (parentFolder != null)
 
91
                                        return parentFolder.ParentSolution;
 
92
                                return parentSolution; 
 
93
                        }
 
94
                        internal set {
 
95
                                parentSolution = value;
 
96
                        }
 
97
                }
 
98
                
 
99
                protected bool Loading {
 
100
                        get { return loading > 0; }
 
101
                }
 
102
                
 
103
                public abstract void Save (IProgressMonitor monitor);
 
104
                
 
105
                public abstract string Name { get; set; }
 
106
                
 
107
                public string BaseDirectory {
 
108
                        get {
 
109
                                if (baseDirectory == null)
 
110
                                        return System.IO.Path.GetFullPath (GetDefaultBaseDirectory ());
 
111
                                else
 
112
                                        return baseDirectory;
 
113
                        }
 
114
                        set {
 
115
                                string def = GetDefaultBaseDirectory ();
 
116
                                if (value != null && def != null && System.IO.Path.GetFullPath (value) == System.IO.Path.GetFullPath (def))
 
117
                                        baseDirectory = null;
 
118
                                else if (string.IsNullOrEmpty (value))
 
119
                                        baseDirectory = null;
 
120
                                else
 
121
                                        baseDirectory = System.IO.Path.GetFullPath (value);
 
122
                                NotifyModified ("BaseDirectory");
 
123
                        }
 
124
                }
 
125
                
 
126
                internal bool HasCustomBaseDirectory {
 
127
                        get { return baseDirectory != null; }
 
128
                }
 
129
                
 
130
                protected virtual string GetDefaultBaseDirectory ()
 
131
                {
 
132
                        return ParentSolution.BaseDirectory;
 
133
                }
 
134
                
 
135
                public string ItemId {
 
136
                        get { return ItemHandler.ItemId; }
 
137
                }
 
138
                
 
139
                public IDictionary ExtendedProperties {
 
140
                        get { return InternalGetExtendedProperties; }
 
141
                }
 
142
                
 
143
                public MonoDevelop.Projects.Policies.PolicyBag Policies {
 
144
                        get {
 
145
                                //newly created (i.e. not deserialised) SolutionItems may have a null PolicyBag
 
146
                                if (policies == null)
 
147
                                        policies = new MonoDevelop.Projects.Policies.PolicyBag ();
 
148
                                //this is the easiest reliable place to associate a deserialised Policybag with its owner
 
149
                                policies.Owner = this;
 
150
                                return policies;
 
151
                        }
 
152
                        //setter so that a solution can deserialise the PropertyBag on its RootFolder
 
153
                        internal set {
 
154
                                policies = value;
 
155
                        }
 
156
                }
 
157
                
 
158
                public SolutionFolder ParentFolder {
 
159
                        get {
 
160
                                return parentFolder;
 
161
                        }
 
162
                        internal set {
 
163
                                parentFolder = value;
 
164
                        }
 
165
                }
 
166
                
 
167
                public virtual void Dispose ()
 
168
                {
 
169
                        if (extendedProperties != null) {
 
170
                                foreach (object ob in extendedProperties.Values) {
 
171
                                        IDisposable disp = ob as IDisposable;
 
172
                                        if (disp != null)
 
173
                                                disp.Dispose ();
 
174
                                }
 
175
                        }
 
176
                        if (handler != null)
 
177
                                handler.Dispose ();
 
178
                }
 
179
                
 
180
                public virtual IEnumerable<SolutionItem> GetReferencedItems (string solutionConfiguration)
 
181
                {
 
182
                        return new SolutionItem [0];
 
183
                }
 
184
                
 
185
                public BuildResult RunTarget (IProgressMonitor monitor, string target, string solutionConfiguration)
 
186
                {
 
187
                        return Services.ProjectService.ExtensionChain.RunTarget (monitor, this, target, solutionConfiguration);
 
188
                }
 
189
                
 
190
                public void Clean (IProgressMonitor monitor, string solutionConfiguration)
 
191
                {
 
192
                        Services.ProjectService.ExtensionChain.RunTarget (monitor, this, ProjectService.CleanTarget, solutionConfiguration);
 
193
                }
 
194
                
 
195
                public BuildResult Build (IProgressMonitor monitor, string solutionConfiguration)
 
196
                {
 
197
                        return Build (monitor, solutionConfiguration, false);
 
198
                }
 
199
                
 
200
                public BuildResult Build (IProgressMonitor monitor, string solutionConfiguration, bool buildReferences)
 
201
                {
 
202
                        if (!buildReferences) {
 
203
                                if (!NeedsBuilding (solutionConfiguration))
 
204
                                        return new BuildResult (new CompilerResults (null), "");
 
205
                                        
 
206
                                try {
 
207
                                        SolutionEntityItem it = this as SolutionEntityItem;
 
208
                                        string confName = it != null ? it.GetActiveConfigurationId (solutionConfiguration) : solutionConfiguration;
 
209
                                        monitor.BeginTask (GettextCatalog.GetString ("Building: {0} ({1})", Name, confName), 1);
 
210
                                        
 
211
                                        // This will end calling OnBuild ()
 
212
                                        return Services.ProjectService.ExtensionChain.RunTarget (monitor, this, ProjectService.BuildTarget, solutionConfiguration);
 
213
                                        
 
214
                                } finally {
 
215
                                        monitor.EndTask ();
 
216
                                }
 
217
                        }
 
218
                                
 
219
                        // Get a list of all items that need to be built (including this),
 
220
                        // and build them in the correct order
 
221
                        
 
222
                        List<SolutionItem> referenced = new List<SolutionItem> ();
 
223
                        GetBuildableReferencedItems (referenced, this, solutionConfiguration);
 
224
                        
 
225
                        ReadOnlyCollection<SolutionItem> sortedReferenced = SolutionFolder.TopologicalSort (referenced, solutionConfiguration);
 
226
                        
 
227
                        BuildResult cres = new BuildResult ();
 
228
                        cres.BuildCount = 0;
 
229
                        
 
230
                        monitor.BeginTask (null, sortedReferenced.Count);
 
231
                        foreach (SolutionItem p in sortedReferenced) {
 
232
                                if (p.NeedsBuilding (solutionConfiguration)) {
 
233
                                        BuildResult res = p.Build (monitor, solutionConfiguration, false);
 
234
                                        cres.Append (res);
 
235
                                        if (res.ErrorCount > 0)
 
236
                                                break;
 
237
                                }
 
238
                                monitor.Step (1);
 
239
                                if (monitor.IsCancelRequested)
 
240
                                        break;
 
241
                        }
 
242
                        monitor.EndTask ();
 
243
                        return cres;
 
244
                }
 
245
                
 
246
                public DateTime GetLastBuildTime (string itemConfiguration)
 
247
                {
 
248
                        return OnGetLastBuildTime (itemConfiguration);
 
249
                }
 
250
                
 
251
                void GetBuildableReferencedItems (List<SolutionItem> referenced, SolutionItem item, string solutionConfiguration)
 
252
                {
 
253
                        if (referenced.Contains (item)) return;
 
254
                        
 
255
                        if (item.NeedsBuilding (solutionConfiguration))
 
256
                                referenced.Add (item);
 
257
 
 
258
                        foreach (SolutionItem ritem in item.GetReferencedItems (solutionConfiguration))
 
259
                                GetBuildableReferencedItems (referenced, ritem, solutionConfiguration);
 
260
                }
 
261
                
 
262
                public void Execute (IProgressMonitor monitor, ExecutionContext context, string solutionConfiguration)
 
263
                {
 
264
                        Services.ProjectService.ExtensionChain.Execute (monitor, this, context, solutionConfiguration);
 
265
                }
 
266
                
 
267
                public bool CanExecute (ExecutionContext context, string solutionConfiguration)
 
268
                {
 
269
                        return Services.ProjectService.ExtensionChain.CanExecute (this, context, solutionConfiguration);
 
270
                }
 
271
                
 
272
                public bool NeedsBuilding (string solutionConfiguration)
 
273
                {
 
274
                        return Services.ProjectService.ExtensionChain.GetNeedsBuilding (this, solutionConfiguration);
 
275
                }
 
276
                
 
277
                public void SetNeedsBuilding (bool value, string solutionConfiguration)
 
278
                {
 
279
                        Services.ProjectService.ExtensionChain.SetNeedsBuilding (this, value, solutionConfiguration);
 
280
                }
 
281
                
 
282
                public virtual bool NeedsReload {
 
283
                        get {
 
284
                                if (ParentSolution != null)
 
285
                                        return ParentSolution.NeedsReload;
 
286
                                else
 
287
                                        return false;
 
288
                        }
 
289
                        set {
 
290
                        }
 
291
                }
 
292
                
 
293
                public static ReadOnlyCollection<T> TopologicalSort<T> (IEnumerable<T> items, string solutionConfiguration) where T: SolutionItem
 
294
                {
 
295
                        IList<T> allItems;
 
296
                        allItems = items as IList<T>;
 
297
                        if (allItems == null)
 
298
                                allItems = new List<T> (items);
 
299
                        
 
300
                        List<T> sortedEntries = new List<T> ();
 
301
                        bool[] inserted = new bool[allItems.Count];
 
302
                        bool[] triedToInsert = new bool[allItems.Count];
 
303
                        for (int i = 0; i < allItems.Count; ++i) {
 
304
                                if (!inserted[i])
 
305
                                        Insert<T> (i, allItems, sortedEntries, inserted, triedToInsert, solutionConfiguration);
 
306
                        }
 
307
                        return sortedEntries.AsReadOnly ();
 
308
                }
 
309
                
 
310
                static void Insert<T> (int index, IList<T> allItems, List<T> sortedItems, bool[] inserted, bool[] triedToInsert, string solutionConfiguration) where T: SolutionItem
 
311
                {
 
312
                        if (triedToInsert[index]) {
 
313
                                throw new CyclicBuildOrderException();
 
314
                        }
 
315
                        triedToInsert[index] = true;
 
316
                        SolutionItem insertItem = allItems[index];
 
317
                        
 
318
                        foreach (SolutionItem reference in insertItem.GetReferencedItems (solutionConfiguration)) {
 
319
                                for (int j=0; j < allItems.Count; ++j) {
 
320
                                        SolutionItem checkItem = allItems[j];
 
321
                                        if (reference == checkItem) {
 
322
                                                if (!inserted[j])
 
323
                                                        Insert (j, allItems, sortedItems, inserted, triedToInsert, solutionConfiguration);
 
324
                                                break;
 
325
                                        }
 
326
                                }
 
327
                        }
 
328
                        sortedItems.Add ((T)insertItem);
 
329
                        inserted[index] = true;
 
330
                }
 
331
                
 
332
                internal virtual IDictionary InternalGetExtendedProperties {
 
333
                        get {
 
334
                                if (extendedProperties == null)
 
335
                                        extendedProperties = new Hashtable ();
 
336
                                return extendedProperties;
 
337
                        }
 
338
                }
 
339
                
 
340
                void ILoadController.BeginLoad ()
 
341
                {
 
342
                        loading++;
 
343
                        OnBeginLoad ();
 
344
                }
 
345
                
 
346
                void ILoadController.EndLoad ()
 
347
                {
 
348
                        loading--;
 
349
                        OnEndLoad ();
 
350
                }
 
351
                
 
352
                protected virtual void OnBeginLoad ()
 
353
                {
 
354
                }
 
355
                
 
356
                protected virtual void OnEndLoad ()
 
357
                {
 
358
                }
 
359
                
 
360
                protected void NotifyModified (string hint)
 
361
                {
 
362
                        OnModified (new SolutionItemModifiedEventArgs (this, hint));
 
363
                }
 
364
                
 
365
                protected virtual void OnModified (SolutionItemModifiedEventArgs args)
 
366
                {
 
367
                        if (Modified != null)
 
368
                                Modified (this, args);
 
369
                }
 
370
                
 
371
                protected virtual void OnNameChanged (SolutionItemRenamedEventArgs e)
 
372
                {
 
373
                        NotifyModified ("Name");
 
374
                        if (NameChanged != null)
 
375
                                NameChanged (this, e);
 
376
                }
 
377
                
 
378
                protected virtual void InitializeItemHandler ()
 
379
                {
 
380
                }
 
381
                
 
382
                
 
383
                internal protected abstract void OnClean (IProgressMonitor monitor, string solutionConfiguration);
 
384
                internal protected abstract BuildResult OnBuild (IProgressMonitor monitor, string solutionConfiguration);
 
385
                internal protected abstract void OnExecute (IProgressMonitor monitor, ExecutionContext context, string solutionConfiguration);
 
386
                internal protected abstract bool OnGetNeedsBuilding (string solutionConfiguration);
 
387
                internal protected abstract void OnSetNeedsBuilding (bool val, string solutionConfiguration);
 
388
                
 
389
                internal protected virtual DateTime OnGetLastBuildTime (string solutionConfiguration)
 
390
                {
 
391
                        return DateTime.MinValue;
 
392
                }
 
393
                
 
394
                internal protected virtual bool OnGetCanExecute (ExecutionContext context, string solutionConfiguration)
 
395
                {
 
396
                        return false;
 
397
                }
 
398
                
 
399
                public event SolutionItemRenamedEventHandler NameChanged;
 
400
                public event SolutionItemModifiedEventHandler Modified;
 
401
        }
 
402
}