Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorLluis Sanchez Gual <lluis@xamarin.com>2015-02-10 11:06:27 +0300
committerLluis Sanchez Gual <lluis@xamarin.com>2015-02-10 11:06:27 +0300
commit386d6ad60ab9a957b11b719813efbd2890f80897 (patch)
tree488042486f98c68ed41870c5fee0a661d5c7c73e /main
parentff8f17e92c127a34aded7f89b8ab6176330279ab (diff)
Thread safeness improvements
Initial work to make the project model thread-safe for reading. Added checks to prevent changing the model in background threads. Changed collections to be immutable. Also made some adjustments to the api for initializing projects from templates.
Diffstat (limited to 'main')
-rw-r--r--main/src/addins/AspNet/Projects/AspNetAppProjectFlavor.cs6
-rw-r--r--main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs2
-rw-r--r--main/src/addins/NUnit/Project/NUnitAssemblyGroupProject.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs29
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs3
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs10
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs140
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemConfigurationCollection.cs16
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs30
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFileCollection.cs46
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectItemCollection.cs71
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs9
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionConfigurationCollection.cs14
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolder.cs30
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs21
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItemCollection.cs56
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs70
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemConfigurationCollection.cs20
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs19
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs22
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItemExtension.cs11
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs13
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs11
-rw-r--r--main/src/core/MonoDevelop.Core/packages.config4
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs27
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SolutionItemDescriptor.cs5
-rw-r--r--main/tests/UnitTests/TestBase.cs2
30 files changed, 450 insertions, 249 deletions
diff --git a/main/src/addins/AspNet/Projects/AspNetAppProjectFlavor.cs b/main/src/addins/AspNet/Projects/AspNetAppProjectFlavor.cs
index 5db38c19a3..daac2c7a4c 100644
--- a/main/src/addins/AspNet/Projects/AspNetAppProjectFlavor.cs
+++ b/main/src/addins/AspNet/Projects/AspNetAppProjectFlavor.cs
@@ -94,12 +94,12 @@ namespace MonoDevelop.AspNet.Projects
#region constructors
- protected override void OnInitializeNew (string languageName, ProjectCreateInformation info, XmlElement projectOptions)
+ protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
{
- base.OnInitializeNew (languageName, info, projectOptions);
+ base.OnInitializeFromTemplate (projectCreateInfo, template);
codebehindTypeNameCache = new WebFormsCodeBehindTypeNameCache (Project);
- var binPath = info == null? (FilePath)"bin" : info.BinPath;
+ var binPath = projectCreateInfo == null? (FilePath)"bin" : projectCreateInfo.BinPath;
foreach (var cfg in Project.Configurations.Cast<DotNetProjectConfiguration> ())
cfg.OutputDirectory = binPath;
}
diff --git a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs
index baa5499033..7afa7cda60 100644
--- a/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs
+++ b/main/src/addins/MonoDevelop.Gettext/MonoDevelop.Gettext/TranslationProject.cs
@@ -128,7 +128,7 @@ namespace MonoDevelop.Gettext
return true;
}
- protected override void OnInitializeFromTemplate (XmlElement template)
+ protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
{
OutputType = (TranslationOutputType)Enum.Parse (typeof(TranslationOutputType), template.GetAttribute ("outputType"));
PackageName = template.GetAttribute ("packageName");
diff --git a/main/src/addins/NUnit/Project/NUnitAssemblyGroupProject.cs b/main/src/addins/NUnit/Project/NUnitAssemblyGroupProject.cs
index 235b1193dd..1cb385cbd7 100644
--- a/main/src/addins/NUnit/Project/NUnitAssemblyGroupProject.cs
+++ b/main/src/addins/NUnit/Project/NUnitAssemblyGroupProject.cs
@@ -53,7 +53,7 @@ namespace MonoDevelop.NUnit
Configurations.Add (CreateConfiguration ("Default"));
}
- protected override void OnInitializeFromTemplate (XmlElement element)
+ protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement element)
{
Configurations.Add (CreateConfiguration ("Default"));
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
index 8d998ad721..c65057e3ff 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
@@ -86,6 +86,9 @@
<Reference Include="System.ServiceModel" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Build.Engine" />
+ <Reference Include="System.Collections.Immutable">
+ <HintPath>..\..\..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="MonoDevelop.Core\StringParserService.cs" />
@@ -490,6 +493,7 @@
<None Include="Makefile.am" />
<None Include="MonoDevelop.Projects.Formats.MSBuild.Conditions\InvalidProjectFileException.cs" />
<None Include="BuildVariables.cs.in" />
+ <None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MonoDevelop.Core.addin.xml">
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs
index cf37e4cab7..f00b9dd561 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs
@@ -132,7 +132,7 @@ namespace MonoDevelop.Projects.Extensions
{
var item = CreateSolutionItem (new ProgressMonitor (), null, Guid).Result;
item.EnsureInitialized ();
- item.InitializeNew (info, projectOptions);
+ item.InitializeFromTemplate (info, projectOptions);
return item;
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs
index 9a10fb9d08..48220d8d0d 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectService.cs
@@ -131,28 +131,25 @@ namespace MonoDevelop.Projects.Formats.MSBuild
internal static async Task<SolutionItem> LoadProjectAsync (ProgressMonitor monitor, string fileName, MSBuildFileFormat format, string typeGuid, Type itemType, SolutionItemTypeNode node, SolutionLoadContext ctx)
{
- var item = await CreateSolutionItem (monitor, fileName, typeGuid, itemType, node);
+ SolutionItem item;
+
+ if (itemType != null)
+ item = (SolutionItem)Activator.CreateInstance (itemType);
+ else {
+ item = await node.CreateSolutionItem (monitor, fileName, typeGuid ?? node.Guid);
+ item.EnsureInitialized ();
+ }
item.BeginLoad ();
ctx.LoadCompleted += delegate {
item.EndLoad ();
+ item.NotifyItemReady ();
};
await item.LoadAsync (monitor, fileName, format);
return item;
}
- // All of the last 4 parameters are optional, but at least one must be provided.
- static async Task<SolutionItem> CreateSolutionItem (ProgressMonitor monitor, string fileName, string typeGuid, Type itemClass, SolutionItemTypeNode node)
- {
- if (itemClass != null)
- return (SolutionItem)Activator.CreateInstance (itemClass);
-
- var it = await node.CreateSolutionItem (monitor, fileName, typeGuid ?? node.Guid);
- it.EnsureInitialized ();
- return it;
- }
-
internal static bool CanCreateSolutionItem (string type, ProjectCreateInformation info, System.Xml.XmlElement projectOptions)
{
foreach (var node in GetItemTypeNodes ()) {
@@ -168,6 +165,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (node.Guid.Equals (typeGuid, StringComparison.OrdinalIgnoreCase)) {
var p = node.CreateProject (typeGuid, flavorGuids);
p.EnsureInitialized ();
+ p.NotifyItemReady ();
return p;
}
}
@@ -177,8 +175,11 @@ namespace MonoDevelop.Projects.Formats.MSBuild
internal static SolutionItem CreateSolutionItem (string type, ProjectCreateInformation info, System.Xml.XmlElement projectOptions)
{
foreach (var node in GetItemTypeNodes ()) {
- if (node.CanCreateSolutionItem (type, info, projectOptions))
- return node.CreateSolutionItem (type, info, projectOptions);
+ if (node.CanCreateSolutionItem (type, info, projectOptions)) {
+ var item = node.CreateSolutionItem (type, info, projectOptions);
+ item.NotifyItemReady ();
+ return item;
+ }
}
throw new InvalidOperationException ("Unknown project type: " + type);
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs
index 2fc75c9a5a..64840fa148 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/SlnFileFormat.cs
@@ -529,7 +529,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (fileName == null || monitor == null)
return null;
- var sol = new Solution ();
+ var sol = new Solution (true);
sol.OnBeginLoad ();
try {
monitor.BeginTask (string.Format (GettextCatalog.GetString ("Loading solution: {0}"), fileName), 1);
@@ -543,6 +543,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
} finally {
monitor.EndTask ();
sol.OnEndLoad ();
+ sol.NotifyItemReady ();
}
return sol;
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs
index 1a14d722ca..f6a379a626 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs
@@ -54,9 +54,9 @@ namespace MonoDevelop.Projects.SharedAssetsProjects
languageName = language;
}
- internal protected override void InitializeNew (ProjectCreateInformation projectCreateInfo, XmlElement projectOptions)
+ protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement projectOptions)
{
- base.InitializeNew (projectCreateInfo, projectOptions);
+ base.OnInitializeFromTemplate (projectCreateInfo, projectOptions);
languageName = projectOptions.GetAttribute ("language");
DefaultNamespace = projectCreateInfo.ProjectName;
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
index 8cb0ee3c95..3dbb63b242 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
@@ -108,8 +108,16 @@ namespace MonoDevelop.Projects
CompileTarget = CompileTarget.Library;
}
- internal protected override void InitializeNew (ProjectCreateInformation projectCreateInfo, XmlElement projectOptions)
+ protected override void SetShared ()
{
+ base.SetShared ();
+ projectReferences.SetShared ();
+ }
+
+ protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement projectOptions)
+ {
+ base.OnInitializeFromTemplate (projectCreateInfo, projectOptions);
+
if ((projectOptions != null) && (projectOptions.Attributes ["Target"] != null))
CompileTarget = (CompileTarget)Enum.Parse (typeof(CompileTarget), projectOptions.Attributes ["Target"].Value);
else if (IsLibraryBasedProjectType)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs
index c4f7ad68e2..59a2eddd0f 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemCollection.cs
@@ -28,46 +28,140 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Collections.Immutable;
+using MonoDevelop.Core;
namespace MonoDevelop.Projects
{
- public class ItemCollection<T>: Collection<T>
+ public class ItemCollection<T>: IEnumerable<T>
{
- protected override void InsertItem (int index, T item)
+ ImmutableList<T> list = ImmutableList<T>.Empty;
+ bool controlWrites;
+ T[] singleItem = new T[1];
+
+ protected ImmutableList<T> List {
+ get {
+ return this.list;
+ }
+ set {
+ list = value;
+ }
+ }
+
+ internal void SetShared ()
{
- base.InsertItem (index, item);
- OnItemAdded (item);
+ controlWrites = true;
}
-
- protected override void RemoveItem (int index)
+
+ protected void AssertCanWrite ()
{
- T it = this [index];
- base.RemoveItem (index);
- OnItemRemoved (it);
+ if (controlWrites)
+ Runtime.AssertMainThread ();
}
-
- protected override void SetItem (int index, T item)
+
+ public void Add (T item)
{
- T it = this [index];
- base.SetItem (index, item);
- OnItemRemoved (it);
- OnItemAdded (item);
+ list = list.Add (item);
+ singleItem [0] = item;
+ OnItemsAdded (singleItem);
}
-
- protected override void ClearItems ()
+
+ public void AddRange (IEnumerable<T> items)
+ {
+ AssertCanWrite ();
+ list = list.AddRange (items);
+ OnItemsAdded (items);
+ }
+
+ public void RemoveRange (IEnumerable<T> items)
+ {
+ AssertCanWrite ();
+ list = list.RemoveRange (items);
+ OnItemsRemoved (items);
+ }
+
+ public bool Remove (T item)
+ {
+ AssertCanWrite ();
+
+ int i = list.IndexOf (item);
+ if (i != -1) {
+ RemoveAt (i);
+ return true;
+ }
+ return false;
+ }
+
+ public void RemoveAt (int index)
+ {
+ AssertCanWrite ();
+ T it = list [index];
+ list = list.RemoveAt (index);
+ singleItem [0] = it;
+ OnItemsRemoved (singleItem);
+ }
+
+ public int IndexOf (T item)
+ {
+ return list.IndexOf (item);
+ }
+
+ public bool Contains (T item)
{
- List<T> items = new List<T> (this);
- base.ClearItems ();
- foreach (T it in items)
- OnItemRemoved (it);
+ return list.Contains (item);
+ }
+
+ public T this [int index] {
+ get {
+ return list [index];
+ }
+ set {
+ AssertCanWrite ();
+ T it = list [index];
+ list = list.SetItem (index, value);
+ singleItem [0] = it;
+ OnItemsRemoved (singleItem);
+ singleItem [0] = value;
+ OnItemsAdded (singleItem);
+ }
+ }
+
+ public void Clear ()
+ {
+ AssertCanWrite ();
+ var oldList = list;
+ list = list.Clear ();
+ OnItemsRemoved (oldList);
+ }
+
+ public int Count {
+ get { return list.Count; }
}
- protected virtual void OnItemAdded (T item)
+ protected virtual void OnItemsAdded (IEnumerable<T> items)
{
}
- protected virtual void OnItemRemoved (T item)
+ protected virtual void OnItemsRemoved (IEnumerable<T> items)
{
}
+
+ #region IEnumerable implementation
+
+ public IEnumerator<T> GetEnumerator ()
+ {
+ return list.GetEnumerator ();
+ }
+
+ #endregion
+
+ #region IEnumerable implementation
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
+ {
+ return ((System.Collections.IEnumerable)list).GetEnumerator ();
+ }
+
+ #endregion
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemConfigurationCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemConfigurationCollection.cs
index 9104295b95..2b361185ba 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemConfigurationCollection.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ItemConfigurationCollection.cs
@@ -109,16 +109,20 @@ namespace MonoDevelop.Projects
#endregion
- protected override void OnItemAdded (T conf)
+ protected override void OnItemsAdded (IEnumerable<T> confs)
{
- if (ConfigurationAdded != null)
- ConfigurationAdded (this, new ConfigurationEventArgs (null, conf));
+ foreach (var conf in confs) {
+ if (ConfigurationAdded != null)
+ ConfigurationAdded (this, new ConfigurationEventArgs (null, conf));
+ }
}
- protected override void OnItemRemoved (T conf)
+ protected override void OnItemsRemoved (IEnumerable<T> confs)
{
- if (ConfigurationRemoved != null)
- ConfigurationRemoved (this, new ConfigurationEventArgs (null, conf));
+ foreach (var conf in confs) {
+ if (ConfigurationRemoved != null)
+ ConfigurationRemoved (this, new ConfigurationEventArgs (null, conf));
+ }
}
#pragma warning disable 67
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
index 5023ae08b5..b56a02ced4 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
@@ -33,7 +33,6 @@ using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.IO;
-using MonoDevelop;
using MonoDevelop.Core;
using MonoDevelop.Core.Serialization;
using MonoDevelop.Projects;
@@ -43,8 +42,6 @@ using System.Xml;
using MonoDevelop.Core.Instrumentation;
using MonoDevelop.Core.Assemblies;
using MonoDevelop.Projects.Extensions;
-using System.Threading;
-using Mono.Addins;
namespace MonoDevelop.Projects
@@ -68,8 +65,13 @@ namespace MonoDevelop.Projects
List<string> defaultImports;
+ ProjectItemCollection items;
+ ProjectItemCollection wildcardItems;
+
protected Project ()
{
+ items = new ProjectItemCollection (this);
+ wildcardItems = new ProjectItemCollection (this);
FileService.FileChanged += OnFileChanged;
Runtime.SystemAssemblyService.DefaultRuntimeChanged += OnDefaultRuntimeChanged;
files = new ProjectFileCollection ();
@@ -77,6 +79,14 @@ namespace MonoDevelop.Projects
DependencyResolutionEnabled = true;
}
+ public ProjectItemCollection Items {
+ get { return items; }
+ }
+
+ internal ProjectItemCollection WildcardItems {
+ get { return wildcardItems; }
+ }
+
protected Project (params string[] flavorGuids): this()
{
this.flavorGuids = flavorGuids;
@@ -94,6 +104,14 @@ namespace MonoDevelop.Projects
}
}
+ protected override void SetShared ()
+ {
+ base.SetShared ();
+ items.SetShared ();
+ wildcardItems.SetShared ();
+ files.SetShared ();
+ }
+
internal class CreationContext
{
public MSBuildProject Project { get; set; }
@@ -565,6 +583,12 @@ namespace MonoDevelop.Projects
public override void Dispose ()
{
+ foreach (var item in items.Concat (wildcardItems)) {
+ IDisposable disp = item as IDisposable;
+ if (disp != null)
+ disp.Dispose ();
+ }
+
FileService.FileChanged -= OnFileChanged;
Runtime.SystemAssemblyService.DefaultRuntimeChanged -= OnDefaultRuntimeChanged;
CleanupProjectBuilder ();
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFileCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFileCollection.cs
index 5b5bfd3d22..27fd0914c6 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFileCollection.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFileCollection.cs
@@ -31,6 +31,7 @@ using System.Linq;
using System.Collections.Generic;
using MonoDevelop.Core;
+using System.Collections.Immutable;
namespace MonoDevelop.Projects
{
@@ -113,12 +114,12 @@ namespace MonoDevelop.Projects
[Serializable()]
public class ProjectFileCollection : ProjectItemCollection<ProjectFile>
{
- Dictionary<FilePath, ProjectFile> files;
+ ImmutableDictionary<FilePath, ProjectFile> files;
ProjectFileNode root;
public ProjectFileCollection ()
{
- files = new Dictionary<FilePath, ProjectFile> ();
+ files = ImmutableDictionary<FilePath, ProjectFile>.Empty;
root = new ProjectFileNode ();
}
@@ -142,9 +143,10 @@ namespace MonoDevelop.Projects
void FilePathChanged (object sender, ProjectFilePathChangedEventArgs e)
{
+ AssertCanWrite ();
ProjectVirtualPathChanged (sender, e);
- files.Remove (e.OldPath);
- files[e.NewPath] = e.ProjectFile;
+ files = files.Remove (e.OldPath);
+ files = files.SetItem (e.NewPath, e.ProjectFile);
}
void AddProjectFile (ProjectFile item)
@@ -158,7 +160,7 @@ namespace MonoDevelop.Projects
node.ProjectFile = item;
}
- files[item.FilePath] = item;
+ files = files.SetItem (item.FilePath, item);
}
void PruneEmptyParents (ProjectFileNode node)
@@ -178,37 +180,25 @@ namespace MonoDevelop.Projects
PruneEmptyParents (node.Parent);
}
- files.Remove (item.FilePath);
+ files = files.Remove (item.FilePath);
item.VirtualPathChanged -= ProjectVirtualPathChanged;
item.PathChanged -= FilePathChanged;
}
#region ItemCollection<T>
- protected override void OnItemAdded (ProjectFile item)
+ protected override void OnItemsAdded (IEnumerable<ProjectFile> items)
{
- AddProjectFile (item);
- base.OnItemAdded (item);
+ foreach (var item in items)
+ AddProjectFile (item);
+ base.OnItemsAdded (items);
}
- protected override void OnItemRemoved (ProjectFile item)
+ protected override void OnItemsRemoved (IEnumerable<ProjectFile> items)
{
- RemoveProjectFile (item);
- base.OnItemRemoved (item);
- }
- #endregion
-
- #region ProjectItemCollection<T>
- protected override void AddItem (ProjectFile item)
- {
- AddProjectFile (item);
- base.AddItem (item);
- }
-
- protected override void RemoveItem (ProjectFile item)
- {
- RemoveProjectFile (item);
- base.RemoveItem (item);
+ foreach (var item in items)
+ RemoveProjectFile (item);
+ base.OnItemsRemoved (items);
}
#endregion
@@ -254,7 +244,7 @@ namespace MonoDevelop.Projects
public ProjectFile[] GetFilesInPath (FilePath path)
{
List<ProjectFile> list = new List<ProjectFile> ();
- foreach (ProjectFile file in Items) {
+ foreach (ProjectFile file in this) {
if (file.FilePath.IsChildPathOf (path))
list.Add (file);
}
@@ -265,7 +255,7 @@ namespace MonoDevelop.Projects
{
fileName = FileService.GetFullPath (fileName);
for (int n = 0; n < Count; n++) {
- if (Items[n].Name == fileName) {
+ if (this[n].Name == fileName) {
RemoveAt (n);
break;
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectItemCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectItemCollection.cs
index 4a2badcff1..1c4de51014 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectItemCollection.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectItemCollection.cs
@@ -37,7 +37,7 @@ namespace MonoDevelop.Projects
{
}
- internal ProjectItemCollection (SolutionItem parent): base (parent)
+ internal ProjectItemCollection (Project parent): base (parent)
{
}
}
@@ -55,7 +55,7 @@ namespace MonoDevelop.Projects
IItemListHandler parentCollection;
List<IItemListHandler> subCollections;
- internal ProjectItemCollection (SolutionItem parent)
+ internal ProjectItemCollection (Project parent)
{
this.parent = parent;
}
@@ -64,34 +64,9 @@ namespace MonoDevelop.Projects
{
}
- protected virtual void AddItem (T item)
- {
- Items.Add (item);
- }
-
- public void AddRange (IEnumerable<T> items)
- {
- foreach (var item in items)
- AddItem (item);
- NotifyAdded (items, false);
- NotifyAdded (items, true);
- }
-
- protected virtual void RemoveItem (T item)
- {
- Items.Remove (item);
- }
-
- public void RemoveRange (IEnumerable<T> items)
- {
- foreach (var item in items)
- RemoveItem (item);
- NotifyRemoved (items, false);
- NotifyRemoved (items, true);
- }
-
public void Bind<U> (ProjectItemCollection<U> subCollection) where U:T
{
+ AssertCanWrite ();
if (subCollections == null)
subCollections = new List<IItemListHandler> ();
subCollections.Add (subCollection);
@@ -116,33 +91,43 @@ namespace MonoDevelop.Projects
}
}
- protected override void OnItemAdded (T item)
+ protected override void OnItemsAdded (IEnumerable<T> items)
{
- var items = new T [] { item };
- NotifyAdded (items, true);
- NotifyAdded (items, false);
+ if (!ignoreChangeEvents) {
+ NotifyAdded (items, true);
+ NotifyAdded (items, false);
+ }
}
- protected override void OnItemRemoved (T item)
+ protected override void OnItemsRemoved (IEnumerable<T> items)
{
- var items = new T [] { item };
- NotifyRemoved (items, true);
- NotifyRemoved (items, false);
+ if (!ignoreChangeEvents) {
+ NotifyRemoved (items, true);
+ NotifyRemoved (items, false);
+ }
}
-
+
+ bool ignoreChangeEvents;
+
void IItemListHandler.InternalAdd (IEnumerable<ProjectItem> items, bool comesFromParent)
{
- foreach (var item in items)
- AddItem ((T) item);
-
+ try {
+ ignoreChangeEvents = true;
+ AddRange (items.Cast<T> ());
+ } finally {
+ ignoreChangeEvents = false;
+ }
NotifyAdded (items, comesFromParent);
}
void IItemListHandler.InternalRemove (IEnumerable<ProjectItem> items, bool comesFromParent)
{
- foreach (var item in items)
- RemoveItem ((T) item);
-
+ try {
+ ignoreChangeEvents = true;
+ RemoveRange (items.Cast<T> ());
+ } finally {
+ ignoreChangeEvents = false;
+ }
NotifyRemoved (items, comesFromParent);
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs
index 19136f870b..454865b9d2 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs
@@ -69,11 +69,17 @@ namespace MonoDevelop.Projects
[ProjectPathItemProperty ("outputpath")]
string outputdir = null;
- public Solution ()
+ public Solution (): this (false)
+ {
+ }
+
+ internal Solution (bool loading)
{
Counters.SolutionsLoaded++;
configurations = new SolutionConfigurationCollection (this);
Initialize (this);
+ if (!loading)
+ NotifyItemReady ();
}
internal HashSet<string> LoadedProjects {
@@ -591,7 +597,6 @@ namespace MonoDevelop.Projects
}
}
-
public Task<BuildResult> Clean (ProgressMonitor monitor, string configuration)
{
return Clean (monitor, (SolutionConfigurationSelector) configuration);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionConfigurationCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionConfigurationCollection.cs
index ecb8d59d36..c36a4e72ae 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionConfigurationCollection.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionConfigurationCollection.cs
@@ -47,22 +47,24 @@ namespace MonoDevelop.Projects
this.parentSolution = parentSolution;
}
- protected override void OnItemAdded (SolutionConfiguration conf)
+ protected override void OnItemsAdded (IEnumerable<SolutionConfiguration> confs)
{
if (parentSolution != null) {
- conf.ParentSolution = parentSolution;
+ foreach (var conf in confs)
+ conf.ParentSolution = parentSolution;
parentSolution.NotifyConfigurationsChanged ();
}
- base.OnItemAdded (conf);
+ base.OnItemsAdded (confs);
}
- protected override void OnItemRemoved (SolutionConfiguration conf)
+ protected override void OnItemsRemoved (IEnumerable<SolutionConfiguration> confs)
{
if (parentSolution != null) {
- conf.ParentSolution = null;
+ foreach (var conf in confs)
+ conf.ParentSolution = null;
parentSolution.NotifyConfigurationsChanged ();
}
- base.OnItemRemoved (conf);
+ base.OnItemsRemoved (confs);
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolder.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolder.cs
index d0acf20ea1..b37c24b4f0 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolder.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolder.cs
@@ -50,7 +50,7 @@ using System.Threading.Tasks;
namespace MonoDevelop.Projects
{
[DataInclude (typeof(SolutionConfiguration))]
- public class SolutionFolder : SolutionFolderItem
+ public sealed class SolutionFolder : SolutionFolderItem
{
SolutionFolderItemCollection items;
SolutionFolderFileCollection files;
@@ -88,7 +88,7 @@ namespace MonoDevelop.Projects
}
}
- public virtual bool IsRoot {
+ public bool IsRoot {
get { return ParentFolder == null; }
}
@@ -819,7 +819,7 @@ namespace MonoDevelop.Projects
OnItemAdded (e);
}
- protected virtual void OnItemAdded (SolutionItemChangeEventArgs e)
+ void OnItemAdded (SolutionItemChangeEventArgs e)
{
if (ItemAdded != null)
ItemAdded (this, e);
@@ -831,13 +831,13 @@ namespace MonoDevelop.Projects
NotifyItemRemovedFromFolder (this, e, removedFromSolution);
}
- protected virtual void OnItemRemoved (SolutionItemChangeEventArgs e)
+ void OnItemRemoved (SolutionItemChangeEventArgs e)
{
if (ItemRemoved != null)
ItemRemoved (this, e);
}
- protected virtual void OnFileRemovedFromProject (ProjectFileEventArgs e)
+ void OnFileRemovedFromProject (ProjectFileEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnFileRemovedFromProject (e);
@@ -846,7 +846,7 @@ namespace MonoDevelop.Projects
}
}
- protected virtual void OnFileChangedInProject (ProjectFileEventArgs e)
+ void OnFileChangedInProject (ProjectFileEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnFileChangedInProject (e);
@@ -855,7 +855,7 @@ namespace MonoDevelop.Projects
}
}
- protected virtual void OnFilePropertyChangedInProject (ProjectFileEventArgs e)
+ void OnFilePropertyChangedInProject (ProjectFileEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnFilePropertyChangedInProject (e);
@@ -864,7 +864,7 @@ namespace MonoDevelop.Projects
}
}
- protected virtual void OnFileAddedToProject (ProjectFileEventArgs e)
+ void OnFileAddedToProject (ProjectFileEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnFileAddedToProject (e);
@@ -873,7 +873,7 @@ namespace MonoDevelop.Projects
}
}
- protected virtual void OnFileRenamedInProject (ProjectFileRenamedEventArgs e)
+ void OnFileRenamedInProject (ProjectFileRenamedEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnFileRenamedInProject (e);
@@ -882,7 +882,7 @@ namespace MonoDevelop.Projects
}
}
- protected virtual void OnReferenceRemovedFromProject (ProjectReferenceEventArgs e)
+ void OnReferenceRemovedFromProject (ProjectReferenceEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnReferenceRemovedFromProject (e);
@@ -891,7 +891,7 @@ namespace MonoDevelop.Projects
}
}
- protected virtual void OnReferenceAddedToProject (ProjectReferenceEventArgs e)
+ void OnReferenceAddedToProject (ProjectReferenceEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnReferenceAddedToProject (e);
@@ -900,7 +900,7 @@ namespace MonoDevelop.Projects
}
}
- protected virtual void OnItemModified (SolutionItemModifiedEventArgs e)
+ void OnItemModified (SolutionItemModifiedEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnEntryModified (e);
@@ -908,7 +908,7 @@ namespace MonoDevelop.Projects
ItemModified (this, e);
}
- protected virtual void OnItemSaved (SolutionItemEventArgs e)
+ void OnItemSaved (SolutionItemEventArgs e)
{
if (ParentFolder == null && ParentSolution != null)
ParentSolution.OnEntrySaved (e);
@@ -916,13 +916,13 @@ namespace MonoDevelop.Projects
ItemSaved (this, e);
}
- protected virtual void OnSolutionItemFileAdded (SolutionItemFileEventArgs args)
+ void OnSolutionItemFileAdded (SolutionItemFileEventArgs args)
{
if (SolutionItemFileAdded != null)
SolutionItemFileAdded (this, args);
}
- protected virtual void OnSolutionItemFileRemoved (SolutionItemFileEventArgs args)
+ void OnSolutionItemFileRemoved (SolutionItemFileEventArgs args)
{
if (SolutionItemFileRemoved != null)
SolutionItemFileRemoved (this, args);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs
index ab5c16374c..9257ed79a8 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItem.cs
@@ -43,6 +43,7 @@ namespace MonoDevelop.Projects
SolutionFolder parentFolder;
Solution parentSolution;
SolutionFolder internalChildren;
+ string typeGuid;
[ProjectPathItemProperty ("BaseDirectory", DefaultValue=null)]
string baseDirectory;
@@ -53,7 +54,7 @@ namespace MonoDevelop.Projects
[ItemProperty ("UseMSBuildEngine")]
public bool? UseMSBuildEngine { get; set; }
- PropertyBag userProperties;
+ PropertyBag userProperties = new PropertyBag ();
internal List<string> UnresolvedProjectDependencies { get; set; }
@@ -63,6 +64,7 @@ namespace MonoDevelop.Projects
return base.Name;
}
set {
+ AssertMainThread ();
if (value != Name) {
var oldName = Name;
OnSetName (value);
@@ -72,8 +74,13 @@ namespace MonoDevelop.Projects
}
public string TypeGuid {
- get;
- set;
+ get {
+ return this.typeGuid;
+ }
+ set {
+ AssertMainThread ();
+ typeGuid = value;
+ }
}
protected abstract void OnSetName (string value);
@@ -118,6 +125,7 @@ namespace MonoDevelop.Projects
return baseDirectory;
}
set {
+ AssertMainThread ();
FilePath def = GetDefaultBaseDirectory ();
if (value != FilePath.Null && def != FilePath.Null && value.FullPath == def.FullPath)
baseDirectory = null;
@@ -172,6 +180,7 @@ namespace MonoDevelop.Projects
return itemId;
}
set {
+ AssertMainThread ();
itemId = value;
}
}
@@ -216,8 +225,6 @@ namespace MonoDevelop.Projects
/// </remarks>
public PropertyBag UserProperties {
get {
- if (userProperties == null)
- userProperties = new PropertyBag ();
return userProperties;
}
}
@@ -249,6 +256,7 @@ namespace MonoDevelop.Projects
return parentFolder;
}
internal set {
+ AssertMainThread ();
if (parentFolder != null && parentFolder.ParentSolution != null && (value == null || value.ParentSolution != parentFolder.ParentSolution))
NotifyUnboundFromSolution (false);
@@ -370,6 +378,7 @@ namespace MonoDevelop.Projects
/// </remarks>
protected void RegisterInternalChild (SolutionFolderItem item)
{
+ AssertMainThread ();
if (internalChildren == null) {
internalChildren = new SolutionFolder ();
internalChildren.ParentFolder = parentFolder;
@@ -385,6 +394,7 @@ namespace MonoDevelop.Projects
/// </param>
protected void UnregisterInternalChild (SolutionFolderItem item)
{
+ AssertMainThread ();
if (internalChildren != null)
internalChildren.Items.Remove (item);
}
@@ -462,6 +472,7 @@ namespace MonoDevelop.Projects
/// </param>
protected virtual void OnModified (SolutionItemModifiedEventArgs args)
{
+ AssertMainThread ();
if (Modified != null && !Disposed)
Modified (this, args);
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItemCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItemCollection.cs
index 81b85305e1..5bd93f3f24 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItemCollection.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionFolderItemCollection.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.ObjectModel;
+using System.Collections.Generic;
namespace MonoDevelop.Projects
{
@@ -46,50 +47,49 @@ namespace MonoDevelop.Projects
internal void Replace (SolutionFolderItem item, SolutionFolderItem newItem)
{
int i = IndexOf (item);
- Items [i] = newItem;
+ List = List.SetItem (i, newItem);
newItem.ParentFolder = parentFolder;
}
- protected override void OnItemAdded (SolutionFolderItem item)
+ protected override void OnItemsAdded (IEnumerable<SolutionFolderItem> items)
{
if (parentFolder != null) {
- // If the item belongs to another solution, remove it from there.
- // If it belongs to the same solution, just move the item, avoiding
- // the global item added/removed events.
- if (item.ParentFolder != null && item.ParentSolution != null) {
- if (item.ParentSolution != parentFolder.ParentSolution)
- item.ParentFolder.Items.Remove (item);
- else {
- SolutionFolder oldFolder = item.ParentFolder;
- item.ParentFolder = null;
- oldFolder.Items.InternalRemove (item);
- oldFolder.NotifyItemRemoved (item, false);
- item.ParentFolder = parentFolder;
- parentFolder.NotifyItemAdded (item, false);
- return;
+ foreach (var item in items) {
+ // If the item belongs to another solution, remove it from there.
+ // If it belongs to the same solution, just move the item, avoiding
+ // the global item added/removed events.
+ if (item.ParentFolder != null && item.ParentSolution != null) {
+ if (item.ParentSolution != parentFolder.ParentSolution)
+ item.ParentFolder.Items.Remove (item);
+ else {
+ SolutionFolder oldFolder = item.ParentFolder;
+ item.ParentFolder = null;
+ oldFolder.Items.InternalRemove (item);
+ oldFolder.NotifyItemRemoved (item, false);
+ item.ParentFolder = parentFolder;
+ parentFolder.NotifyItemAdded (item, false);
+ return;
+ }
}
+ item.ParentFolder = parentFolder;
+ parentFolder.NotifyItemAdded (item, true);
}
- item.ParentFolder = parentFolder;
- parentFolder.NotifyItemAdded (item, true);
}
}
- protected override void OnItemRemoved (SolutionFolderItem item)
+ protected override void OnItemsRemoved (IEnumerable<SolutionFolderItem> items)
{
if (parentFolder != null) {
- item.ParentFolder = null;
- parentFolder.NotifyItemRemoved (item, true);
+ foreach (var item in items) {
+ item.ParentFolder = null;
+ parentFolder.NotifyItemRemoved (item, true);
+ }
}
}
-
- internal void InternalAdd (SolutionFolderItem item)
- {
- Items.Add (item);
- }
-
+
internal void InternalRemove (SolutionFolderItem item)
{
- Items.Remove (item);
+ List = List.Remove (item);
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
index a69a519761..c0f6c116fe 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
@@ -56,8 +56,6 @@ namespace MonoDevelop.Projects
internal object MemoryProbe = Counters.ItemsInMemory.CreateMemoryProbe ();
int loading;
- ProjectItemCollection items;
- ProjectItemCollection wildcardItems;
ItemCollection<SolutionItem> dependencies = new ItemCollection<SolutionItem> ();
SolutionItemEventArgs thisItemArgs;
@@ -88,8 +86,6 @@ namespace MonoDevelop.Projects
TypeGuid = MSBuildProjectService.GetTypeGuidForItem (this);
SetSolutionFormat ((MSBuildFileFormat)fmt.Format, true);
- items = new ProjectItemCollection (this);
- wildcardItems = new ProjectItemCollection (this);
thisItemArgs = new SolutionItemEventArgs (this);
configurations = new SolutionItemConfigurationCollection (this);
configurations.ConfigurationAdded += OnConfigurationAddedToCollection;
@@ -125,12 +121,6 @@ namespace MonoDevelop.Projects
base.Dispose ();
Counters.ItemsLoaded--;
- foreach (var item in items.Concat (wildcardItems)) {
- IDisposable disp = item as IDisposable;
- if (disp != null)
- disp.Dispose ();
- }
-
// items = null;
// wildcardItems = null;
// thisItemArgs = null;
@@ -170,6 +160,33 @@ namespace MonoDevelop.Projects
}
/// <summary>
+ /// Called when an item has been fully created and/or loaded
+ /// </summary>
+ /// <remarks>>
+ /// This method is invoked when all operations required for creating or loading this item have finished.
+ /// If the item is being created in memory, this method will be called just after OnExtensionChainInitialized.
+ /// If the item is being loaded from a file, it will be called after OnEndLoad.
+ /// If the item is being created from a template, it will be called after InitializeNew
+ /// </remarks>
+ protected virtual void OnItemReady ()
+ {
+ SetShared ();
+ }
+
+ internal void NotifyItemReady ()
+ {
+ ItemExtension.ItemReady ();
+ OnItemReady ();
+ }
+
+ protected override void SetShared ()
+ {
+ base.SetShared ();
+ configurations.SetShared ();
+ }
+
+
+ /// <summary>
/// Called when a load operation for this solution item has started
/// </summary>
protected virtual void OnBeginLoad ()
@@ -295,14 +312,6 @@ namespace MonoDevelop.Projects
return null;
}
- public ProjectItemCollection Items {
- get { return items; }
- }
-
- internal ProjectItemCollection WildcardItems {
- get { return wildcardItems; }
- }
-
/// <summary>
/// Projects that need to be built before building this one
/// </summary>
@@ -380,22 +389,20 @@ namespace MonoDevelop.Projects
/// <param name='template'>
/// The template
/// </param>
- public void InitializeFromTemplate (XmlElement template)
+ public void InitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
{
- ItemExtension.OnInitializeFromTemplate (template);
+ // TODO NPM: should be internal
+ ItemExtension.OnInitializeFromTemplate (projectCreateInfo, template);
}
- protected virtual void OnInitializeFromTemplate (XmlElement template)
+ protected virtual void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
{
}
- internal protected virtual void InitializeNew (ProjectCreateInformation projectCreateInfo, XmlElement projectOptions)
+ protected sealed override FilePath GetDefaultBaseDirectory ( )
{
- }
-
- protected override FilePath GetDefaultBaseDirectory ( )
- {
- return ItemExtension.OnGetDefaultBaseDirectory ();
+ var file = FileName;
+ return file.IsNullOrEmpty ? FilePath.Empty : file.ParentDirectory;
}
internal Task LoadAsync (ProgressMonitor monitor, FilePath fileName, MSBuildFileFormat format)
@@ -1246,14 +1253,9 @@ namespace MonoDevelop.Projects
class DefaultMSBuildItemExtension: SolutionItemExtension
{
- internal protected override void OnInitializeFromTemplate (XmlElement template)
- {
- Item.OnInitializeFromTemplate (template);
- }
-
- internal protected override FilePath OnGetDefaultBaseDirectory ()
+ internal protected override void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
{
- return Item.FileName.IsNullOrEmpty ? FilePath.Empty : Item.FileName.ParentDirectory;
+ Item.OnInitializeFromTemplate (projectCreateInfo, template);
}
internal protected override IEnumerable<IBuildTarget> OnGetExecutionDependencies ()
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemConfigurationCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemConfigurationCollection.cs
index 0e0a37dd06..5eddb0d447 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemConfigurationCollection.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemConfigurationCollection.cs
@@ -49,18 +49,22 @@ namespace MonoDevelop.Projects
this.parentItem = parentItem;
}
- protected override void OnItemAdded (SolutionItemConfiguration conf)
+ protected override void OnItemsAdded (IEnumerable<SolutionItemConfiguration> confs)
{
- if (parentItem != null)
- conf.SetParentItem (parentItem);
- base.OnItemAdded (conf);
+ if (parentItem != null) {
+ foreach (var conf in confs)
+ conf.SetParentItem (parentItem);
+ }
+ base.OnItemsAdded (confs);
}
- protected override void OnItemRemoved (SolutionItemConfiguration conf)
+ protected override void OnItemsRemoved (IEnumerable<SolutionItemConfiguration> confs)
{
- if (parentItem != null)
- conf.SetParentItem (null);
- base.OnItemRemoved (conf);
+ if (parentItem != null) {
+ foreach (var conf in confs)
+ conf.SetParentItem (null);
+ }
+ base.OnItemsRemoved (confs);
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs
index 021acb3878..c4e2fc8fa3 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs
@@ -61,14 +61,20 @@ namespace MonoDevelop.Projects
get { return (SolutionItem) Owner; }
}
- internal protected virtual void OnInitializeNew (string languageName, ProjectCreateInformation info, XmlElement projectOptions)
+ internal protected virtual void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
{
- next.OnInitializeNew (languageName, info, projectOptions);
+ next.OnInitializeFromTemplate (projectCreateInfo, template);
}
- internal protected virtual void OnInitializeFromTemplate (XmlElement template)
+ internal void ItemReady ()
+ {
+ OnItemReady ();
+ if (next != null)
+ next.ItemReady ();
+ }
+
+ protected virtual void OnItemReady ()
{
- next.OnInitializeFromTemplate (template);
}
internal void BeginLoad ()
@@ -96,11 +102,6 @@ namespace MonoDevelop.Projects
#region Project model
- internal protected virtual FilePath OnGetDefaultBaseDirectory ()
- {
- return next.OnGetDefaultBaseDirectory ();
- }
-
internal protected virtual IEnumerable<IBuildTarget> OnGetExecutionDependencies ()
{
return next.OnGetExecutionDependencies ();
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs
index 3fc6a47039..584908a11e 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs
@@ -311,7 +311,27 @@ namespace MonoDevelop.Projects
fileStatusTracker.ResetLoadTimes ();
LoadUserProperties ();
}
-
+
+ /// <summary>
+ /// Called when an item has been fully created and/or loaded
+ /// </summary>
+ /// <remarks>>
+ /// This method is invoked when all operations required for creating or loading this item have finished.
+ /// If the item is being created in memory, this method will be called just after OnExtensionChainInitialized.
+ /// If the item is being loaded from a file, it will be called after OnEndLoad.
+ /// If the item is being created from a template, it will be called after InitializeNew
+ /// </remarks>
+ protected virtual void OnItemReady ()
+ {
+ SetShared ();
+ }
+
+ internal void NotifyItemReady ()
+ {
+ ItemExtension.ItemReady ();
+ OnItemReady ();
+ }
+
public virtual void LoadUserProperties ()
{
if (userProperties != null)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItemExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItemExtension.cs
index 5d3d7643ac..ba539e7ad4 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItemExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItemExtension.cs
@@ -53,6 +53,17 @@ namespace MonoDevelop.Projects
return next.SupportsItem (item);
}
+ internal void ItemReady ()
+ {
+ OnItemReady ();
+ if (next != null)
+ next.OnItemReady ();
+ }
+
+ protected virtual void OnItemReady ()
+ {
+ }
+
internal protected virtual Task Save (ProgressMonitor monitor)
{
return next.Save (monitor);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs
index 7cb7b795db..a92cf07e40 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObject.cs
@@ -43,6 +43,7 @@ namespace MonoDevelop.Projects
{
Hashtable extendedProperties;
bool initializeCalled;
+ bool isShared;
internal protected void Initialize<T> (T instance)
{
@@ -64,6 +65,18 @@ namespace MonoDevelop.Projects
}
}
+ protected void AssertMainThread ()
+ {
+ if (isShared)
+ Runtime.AssertMainThread ();
+ }
+
+ protected virtual void SetShared ()
+ {
+ isShared = true;
+ ItemExtension.NotifyShared ();
+ }
+
public string Name {
get { return OnGetName (); }
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs
index 427c49f7eb..d0f4ac436c 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectExtension.cs
@@ -69,6 +69,17 @@ namespace MonoDevelop.Projects
{
return t.IsInstanceOfType (this) ? this : next.GetService (t);
}
+
+ internal void NotifyShared ()
+ {
+ SetShared ();
+ if (next != null)
+ next.SetShared ();
+ }
+
+ protected virtual void SetShared ()
+ {
+ }
}
}
diff --git a/main/src/core/MonoDevelop.Core/packages.config b/main/src/core/MonoDevelop.Core/packages.config
new file mode 100644
index 0000000000..591f985ff1
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Microsoft.Bcl.Immutable" version="1.0.34" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs
index 9093c1d77f..55f50cc0a3 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewProjectController.cs
@@ -460,17 +460,20 @@ namespace MonoDevelop.Ide.Projects
// Inherit the file format from the solution
eitem.FileFormat = ParentFolder.ParentSolution.FileFormat;
- // Remove any references to other projects and add them back after the
- // project is saved because a project reference cannot be resolved until
- // the project has a parent solution.
- List<ProjectReference> projectReferences = GetProjectReferences (eitem);
- if (projectReferences.Any ())
- eitem.Items.RemoveRange (projectReferences);
-
- await IdeApp.ProjectOperations.SaveAsync (eitem);
-
- if (projectReferences.Any ())
- eitem.Items.AddRange (projectReferences);
+ var project = eitem as Project;
+ if (project != null) {
+ // Remove any references to other projects and add them back after the
+ // project is saved because a project reference cannot be resolved until
+ // the project has a parent solution.
+ List<ProjectReference> projectReferences = GetProjectReferences (project);
+ if (projectReferences.Any ())
+ project.Items.RemoveRange (projectReferences);
+
+ await IdeApp.ProjectOperations.SaveAsync (eitem);
+
+ if (projectReferences.Any ())
+ project.Items.AddRange (projectReferences);
+ }
}
ParentFolder.AddItem (currentEntry, true);
}
@@ -515,7 +518,7 @@ namespace MonoDevelop.Ide.Projects
}
}
- List<ProjectReference> GetProjectReferences (SolutionItem solutionItem)
+ List<ProjectReference> GetProjectReferences (Project solutionItem)
{
return solutionItem.Items.OfType<ProjectReference> ()
.Where (item => item.ReferenceType == ReferenceType.Project)
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SolutionItemDescriptor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SolutionItemDescriptor.cs
index 9a5eba1eeb..5ec29b0146 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SolutionItemDescriptor.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Templates/SolutionItemDescriptor.cs
@@ -68,9 +68,10 @@ namespace MonoDevelop.Ide.Templates
MessageService.ShowError (GettextCatalog.GetString ("Can't create project with type : {0}", typeName));
return null;
}
-
+
+ // TODO NPM: should use the project service
SolutionItem item = (SolutionItem) Activator.CreateInstance (type);
- item.InitializeFromTemplate (template);
+ item.InitializeFromTemplate (projectCreateInformation, template);
string newProjectName = StringParserService.Parse (name, new string[,] {
{"ProjectName", projectCreateInformation.ProjectName}
diff --git a/main/tests/UnitTests/TestBase.cs b/main/tests/UnitTests/TestBase.cs
index 90b1549d45..45aafa7d73 100644
--- a/main/tests/UnitTests/TestBase.cs
+++ b/main/tests/UnitTests/TestBase.cs
@@ -32,6 +32,7 @@ using MonoDevelop.Core;
using MonoDevelop.Ide;
using MonoDevelop.Core.Assemblies;
using MonoDevelop.Ide.TypeSystem;
+using System.Threading;
namespace UnitTests
{
@@ -67,6 +68,7 @@ namespace UnitTests
Environment.SetEnvironmentVariable ("MONO_ADDINS_REGISTRY", rootDir);
Environment.SetEnvironmentVariable ("XDG_CONFIG_HOME", rootDir);
Runtime.Initialize (true);
+ Runtime.MainSynchronizationContext = SynchronizationContext.Current;
Gtk.Application.Init ();
TypeSystemService.TrackFileChanges = true;
DesktopService.Initialize ();