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
diff options
context:
space:
mode:
authorLluis Sanchez <lluis@xamarin.com>2015-09-10 13:44:43 +0300
committerLluis Sanchez <lluis@xamarin.com>2015-09-10 13:45:03 +0300
commit25b732404d038f0b9cf166ec6834062dd4be75e2 (patch)
treeba9b3ae9f38fa772ed0efb092abdf41060068493 /main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild
parent9bfc594738571de676e01585c984cd526e9f66c8 (diff)
[Core] Make MSBuildProject thread safe for reading
Diffstat (limited to 'main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild')
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildChoose.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImport.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImportGroup.cs10
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItem.cs14
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItemGroup.cs9
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildObject.cs32
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs82
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectExtensions.cs10
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProperty.cs3
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildPropertyGroup.cs35
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildTarget.cs16
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildXmlNode.cs7
12 files changed, 145 insertions, 79 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildChoose.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildChoose.cs
index 036680196d..dec11b4c0a 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildChoose.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildChoose.cs
@@ -42,7 +42,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (op != null) {
op.ParentNode = this;
op.Read (reader);
- ChildNodes.Add (op);
+ ChildNodes = ChildNodes.Add (op);
} else
base.ReadChildElement (reader);
}
@@ -86,7 +86,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (ob != null) {
ob.ParentNode = this;
ob.Read (reader);
- ChildNodes.Add (ob);
+ ChildNodes = ChildNodes.Add (ob);
} else
reader.Read ();
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImport.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImport.cs
index 5db3d39c11..91bcbeaa9a 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImport.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImport.cs
@@ -64,7 +64,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public string Project {
get { return target; }
- set { target = value; NotifyChanged (); }
+ set { AssertCanModify (); target = value; NotifyChanged (); }
}
public string EvaluatedProject {
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImportGroup.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImportGroup.cs
index 58b801e693..afc3d07757 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImportGroup.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildImportGroup.cs
@@ -38,7 +38,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
var item = new MSBuildImport ();
item.ParentNode = this;
item.Read (reader);
- ChildNodes.Add (item);
+ ChildNodes = ChildNodes.Add (item);
} else
base.ReadChildElement (reader);
}
@@ -55,6 +55,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public MSBuildImport AddNewImport (string name, string condition = null, MSBuildImport beforeImport = null)
{
+ AssertCanModify ();
var import = new MSBuildImport ();
import.Project = name;
import.Condition = condition;
@@ -64,9 +65,9 @@ namespace MonoDevelop.Projects.Formats.MSBuild
insertIndex = ChildNodes.IndexOf (beforeImport);
if (insertIndex != -1)
- ChildNodes.Insert (insertIndex, import);
+ ChildNodes = ChildNodes.Insert (insertIndex, import);
else
- ChildNodes.Add (import);
+ ChildNodes = ChildNodes.Add (import);
import.ResetIndent (false);
NotifyChanged ();
@@ -75,9 +76,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void RemoveImport (MSBuildImport import)
{
+ AssertCanModify ();
if (import.ParentObject == this) {
import.RemoveIndent ();
- ChildNodes.Remove (import);
+ ChildNodes = ChildNodes.Remove (import);
NotifyChanged ();
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItem.cs
index c0a1a5ec9a..59b1a416b7 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItem.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItem.cs
@@ -35,7 +35,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public class MSBuildItem: MSBuildElement
{
MSBuildPropertyGroup metadata;
- MSBuildPropertyGroupEvaluated evaluatedMetadata;
string name;
string include;
string exclude;
@@ -113,6 +112,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public string Include {
get { return include; }
set {
+ AssertCanModify ();
include = value;
NotifyChanged ();
}
@@ -121,6 +121,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public string Exclude {
get { return exclude; }
set {
+ AssertCanModify ();
exclude = value;
NotifyChanged ();
}
@@ -141,14 +142,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
- public IMSBuildPropertyGroupEvaluated EvaluatedMetadata {
- get {
- if (evaluatedMetadata == null)
- evaluatedMetadata = new MSBuildPropertyGroupEvaluated (ParentProject);
- return evaluatedMetadata;
- }
- }
-
internal int EvaluatedItemCount { get; set; }
internal bool IsWildcardItem {
@@ -169,6 +162,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
this.include = include;
this.evaluatedInclude = evaluatedInclude;
this.parent = parent;
+ metadata = new MSBuildPropertyGroupEvaluated (parent);
Name = name;
}
@@ -193,8 +187,6 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public IMSBuildPropertyGroupEvaluated Metadata {
get {
- if (metadata == null)
- metadata = new MSBuildPropertyGroupEvaluated (parent);
return metadata;
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItemGroup.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItemGroup.cs
index 6fde109101..37bd43bea2 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItemGroup.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildItemGroup.cs
@@ -38,7 +38,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
var item = new MSBuildItem ();
item.ParentNode = this;
item.Read (reader);
- ChildNodes.Add (item);
+ ChildNodes = ChildNodes.Add (item);
}
internal override string GetElementName ()
@@ -53,6 +53,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public MSBuildItem AddNewItem (string name, string include)
{
+ AssertCanModify ();
var it = new MSBuildItem (name);
it.Include = include;
AddItem (it);
@@ -61,8 +62,9 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void AddItem (MSBuildItem item)
{
- ChildNodes.Add (item);
+ AssertCanModify ();
item.ParentNode = this;
+ ChildNodes = ChildNodes.Add (item);
item.ResetIndent (false);
if (ParentProject != null)
ParentProject.NotifyChanged ();
@@ -76,9 +78,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild
internal void RemoveItem (MSBuildItem item)
{
+ AssertCanModify ();
if (ChildNodes.Contains (item)) {
item.RemoveIndent ();
- ChildNodes.Remove (item);
+ ChildNodes = ChildNodes.Remove (item);
NotifyChanged ();
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildObject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildObject.cs
index d86e28ee0b..565de09aa3 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildObject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildObject.cs
@@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Linq;
using System.Xml;
@@ -38,7 +39,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
{
UnknownAttribute[] unknownAttributes;
string [] attributeOrder;
- List<MSBuildNode> children;
+ ImmutableList<MSBuildNode> children = ImmutableList<MSBuildNode>.Empty;
EmptyElementMode emptyElementMode;
enum EmptyElementMode : byte
@@ -185,7 +186,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
var tn = new MSBuildXmlTextNode ();
tn.Read (reader);
- ChildNodes.Add (tn);
+ ChildNodes = ChildNodes.Add (tn);
} else if (reader.NodeType == XmlNodeType.CDATA) {
if (!childFound) {
childFound = true;
@@ -193,7 +194,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
var tn = new MSBuildXmlCDataNode ();
tn.Read (reader);
- ChildNodes.Add (tn);
+ ChildNodes = ChildNodes.Add (tn);
} else if (reader.NodeType == XmlNodeType.Comment) {
if (!childFound) {
childFound = true;
@@ -201,7 +202,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
var tn = new MSBuildXmlCommentNode ();
tn.Read (reader);
- ChildNodes.Add (tn);
+ ChildNodes = ChildNodes.Add (tn);
} else if (reader.IsWhitespace) {
reader.ReadAndStoreWhitespace ();
} else if (reader.EOF)
@@ -311,19 +312,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
var n = new MSBuildXmlElement ();
n.Read (reader);
n.ParentNode = this;
- ChildNodes.Add (n);
- }
- }
-
- internal void RemoveUnknownAttribute (string name)
- {
- if (unknownAttributes == null)
- return;
- var list = new List<UnknownAttribute> (unknownAttributes);
- int i = list.FindIndex (a => a.LocalName == name);
- if (i != -1) {
- list.RemoveAt (i);
- unknownAttributes = list.ToArray ();
+ ChildNodes = ChildNodes.Add (n);
}
}
@@ -342,17 +331,18 @@ namespace MonoDevelop.Projects.Formats.MSBuild
internal abstract string GetElementName ();
- internal virtual List<MSBuildNode> ChildNodes {
+ internal virtual ImmutableList<MSBuildNode> ChildNodes {
get {
- if (children == null)
- children = new List<MSBuildNode> ();
return children;
}
+ set {
+ children = value;
+ }
}
internal override IEnumerable<MSBuildNode> GetChildren ()
{
- return children != null ? children : Enumerable.Empty<MSBuildNode> ();
+ return children;
}
internal void ResetIndent (bool closeInNewLine)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs
index 5743c14722..7dcb4bef45 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProject.cs
@@ -46,6 +46,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
MSBuildProjectInstance mainProjectInstance;
int changeStamp;
bool hadXmlDeclaration;
+ bool isShared;
MSBuildEngineManager engineManager;
bool engineManagerIsLocal;
@@ -74,7 +75,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public FilePath FileName
{
get { return file; }
- set { file = value; }
+ set { AssertCanModify (); file = value; }
}
public FilePath BaseDirectory
@@ -140,6 +141,30 @@ namespace MonoDevelop.Projects.Formats.MSBuild
}
}
+ internal override void AssertCanModify ()
+ {
+ if (isShared)
+ Runtime.AssertMainThread ();
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance is shared.
+ /// </summary>
+ /// <remarks>Shared objects can only be modified in the main thread</remarks>
+ public bool IsShared {
+ get { return isShared; }
+ }
+
+ /// <summary>
+ /// Sets this object as shared, which means that it is accessible from several threads for reading,
+ /// but it can only be modified in the main thread
+ /// </summary>
+ public void SetShared ()
+ {
+ isShared = true;
+ }
+
+
void EnableChangeTracking ()
{
}
@@ -176,6 +201,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
internal void Load (string file, MSBuildXmlReader reader)
{
+ AssertCanModify ();
try {
this.file = file;
IsNewProject = false;
@@ -199,6 +225,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
internal void LoadXml (string xml, MSBuildXmlReader reader)
{
+ AssertCanModify ();
try {
DisableChangeTracking ();
var xr = new XmlTextReader (new StringReader (xml));
@@ -215,8 +242,9 @@ namespace MonoDevelop.Projects.Formats.MSBuild
void LoadFromXml (MSBuildXmlReader reader)
{
+ AssertCanModify ();
DisposeMainInstance ();
- ChildNodes.Clear ();
+ ChildNodes = ChildNodes.Clear ();
bestGroups = null;
hadXmlDeclaration = false;
initialWhitespace = null;
@@ -292,7 +320,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (ob != null) {
ob.ParentNode = this;
ob.Read (reader);
- ChildNodes.Add (ob);
+ ChildNodes = ChildNodes.Add (ob);
} else
base.ReadChildElement (reader);
}
@@ -452,7 +480,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public string DefaultTargets
{
get { return defaultTargets; }
- set { defaultTargets = value; NotifyChanged (); }
+ set { AssertCanModify (); defaultTargets = value; NotifyChanged (); }
}
string toolsVersion;
@@ -462,6 +490,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
get { return toolsVersion; }
set
{
+ AssertCanModify ();
toolsVersion = value;
NotifyChanged ();
}
@@ -500,6 +529,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public MSBuildImport AddNewImport (string name, string condition = null, MSBuildObject beforeObject = null)
{
+ AssertCanModify ();
var import = new MSBuildImport {
Project = name,
Condition = condition
@@ -513,12 +543,14 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (index != -1)
index++;
}
+
+ import.ParentNode = this;
+
if (index != -1)
- ChildNodes.Insert (index, import);
+ ChildNodes = ChildNodes.Insert (index, import);
else
- ChildNodes.Add (import);
+ ChildNodes = ChildNodes.Add (import);
- import.ParentNode = this;
import.ResetIndent (false);
NotifyChanged ();
return import;
@@ -531,22 +563,24 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void RemoveImport (string name, string condition = null)
{
+ AssertCanModify ();
var i = GetImport (name, condition);
if (i != null) {
i.RemoveIndent ();
- ChildNodes.Remove (i);
+ ChildNodes = ChildNodes.Remove (i);
NotifyChanged ();
}
}
public void RemoveImport (MSBuildImport import)
{
+ AssertCanModify ();
if (import.ParentProject != this)
throw new InvalidOperationException ("Import object does not belong to this project");
if (import.ParentObject == this) {
import.RemoveIndent ();
- ChildNodes.Remove (import);
+ ChildNodes = ChildNodes.Remove (import);
NotifyChanged ();
} else
((MSBuildImportGroup)import.ParentObject).RemoveImport (import);
@@ -595,20 +629,23 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void AddPropertyGroup (MSBuildPropertyGroup group, bool insertAtEnd)
{
+ AssertCanModify ();
if (group.ParentProject != null)
throw new InvalidOperationException ("Group already belongs to a project");
+ group.ParentNode = this;
+
bool added = false;
if (insertAtEnd) {
var last = ChildNodes.FindLastIndex (g => g is MSBuildPropertyGroup);
if (last != -1) {
- ChildNodes.Insert (last + 1, group);
+ ChildNodes = ChildNodes.Insert (last + 1, group);
added = true;
}
} else {
var first = ChildNodes.FindIndex (g => g is MSBuildPropertyGroup);
if (first != -1) {
- ChildNodes.Insert (first, group);
+ ChildNodes = ChildNodes.Insert (first, group);
added = true;
}
}
@@ -616,12 +653,11 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (!added) {
var first = ChildNodes.FindIndex (g => g is MSBuildItemGroup);
if (first != -1)
- ChildNodes.Insert (first, group);
+ ChildNodes = ChildNodes.Insert (first, group);
else
- ChildNodes.Add (group);
+ ChildNodes = ChildNodes.Add (group);
}
- group.ParentNode = this;
group.ResetIndent (true);
NotifyChanged ();
}
@@ -678,6 +714,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public MSBuildItemGroup AddNewItemGroup ()
{
+ AssertCanModify ();
var group = new MSBuildItemGroup ();
MSBuildObject refNode = null;
@@ -689,12 +726,13 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (g != null)
refNode = g;
}
+
+ group.ParentNode = this;
if (refNode != null)
- ChildNodes.Insert (ChildNodes.IndexOf (refNode) + 1, group);
+ ChildNodes = ChildNodes.Insert (ChildNodes.IndexOf (refNode) + 1, group);
else
- ChildNodes.Add (group);
+ ChildNodes = ChildNodes.Add (group);
- group.ParentNode = this;
group.ResetIndent (true);
NotifyChanged ();
return group;
@@ -764,11 +802,12 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetProjectExtension (XmlElement value)
{
+ AssertCanModify ();
var ext = (MSBuildProjectExtensions)ChildNodes.FirstOrDefault (ob => ob is MSBuildProjectExtensions);
if (ext == null) {
ext = new MSBuildProjectExtensions ();
ext.ParentNode = this;
- ChildNodes.Add (ext);
+ ChildNodes = ChildNodes.Add (ext);
ext.ResetIndent (false);
}
ext.SetProjectExtension (value);
@@ -777,6 +816,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetMonoDevelopProjectExtension (string section, XmlElement value)
{
+ AssertCanModify ();
var elem = GetProjectExtension ("MonoDevelop");
if (elem == null) {
XmlDocument doc = new XmlDocument ();
@@ -807,6 +847,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void RemoveProjectExtension (string section)
{
+ AssertCanModify ();
var ext = (MSBuildProjectExtensions)ChildNodes.FirstOrDefault (ob => ob is MSBuildProjectExtensions);
if (ext != null) {
ext.RemoveProjectExtension (section);
@@ -817,6 +858,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void RemoveMonoDevelopProjectExtension (string section)
{
+ AssertCanModify ();
var md = GetProjectExtension ("MonoDevelop");
if (md == null)
return;
@@ -834,14 +876,16 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void Remove (MSBuildObject ob)
{
+ AssertCanModify ();
if (ob.ParentObject == this) {
ob.RemoveIndent ();
- ChildNodes.Remove (ob);
+ ChildNodes = ChildNodes.Remove (ob);
}
}
public void RemoveItem (MSBuildItem item)
{
+ AssertCanModify ();
if (item.ParentGroup != null) {
item.RemoveIndent ();
var g = item.ParentGroup;
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectExtensions.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectExtensions.cs
index 9c93dd64d3..dfed253c66 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectExtensions.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProjectExtensions.cs
@@ -72,6 +72,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetProjectExtension (XmlElement value)
{
+ AssertCanModify ();
var sr = new StringReader (value.OuterXml);
var xr = new XmlTextReader (sr);
xr.MoveToContent ();
@@ -83,10 +84,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild
int i = ChildNodes.FindIndex (n => (n is MSBuildXmlElement) && ((MSBuildXmlElement)n).Name == section);
if (i == -1)
- ChildNodes.Add (elem);
+ ChildNodes = ChildNodes.Add (elem);
else {
- ChildNodes.RemoveAt (i);
- ChildNodes.Insert (i, elem);
+ ChildNodes = ChildNodes.RemoveAt (i);
+ ChildNodes = ChildNodes.Insert (i, elem);
}
elem.ParentNode = this;
elem.ResetIndent (false);
@@ -95,9 +96,10 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void RemoveProjectExtension (string section)
{
+ AssertCanModify ();
int i = ChildNodes.FindIndex (n => (n is MSBuildXmlElement) && ((MSBuildXmlElement)n).Name == section);
if (i != -1) {
- ChildNodes.RemoveAt (i);
+ ChildNodes = ChildNodes.RemoveAt (i);
NotifyChanged ();
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProperty.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProperty.cs
index f9f25b388c..2b49640aac 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProperty.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildProperty.cs
@@ -209,6 +209,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetValue (string value, bool preserveCase = false, bool mergeToMainGroup = false)
{
+ AssertCanModify ();
MergeToMainGroup = mergeToMainGroup;
this.preserverCase = preserveCase;
valueType = preserveCase ? MSBuildValueType.Default : MSBuildValueType.DefaultPreserveCase;
@@ -230,6 +231,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetValue (FilePath value, bool relativeToProject = true, FilePath relativeToPath = default(FilePath), bool mergeToMainGroup = false)
{
+ AssertCanModify ();
MergeToMainGroup = mergeToMainGroup;
this.preserverCase = false;
valueType = MSBuildValueType.Path;
@@ -268,6 +270,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetValue (object value, bool mergeToMainGroup = false)
{
+ AssertCanModify ();
if (value is bool) {
if (Owner != null && Owner.UppercaseBools)
SetValue ((bool)value ? "True" : "False", preserveCase: true, mergeToMainGroup: mergeToMainGroup);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildPropertyGroup.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildPropertyGroup.cs
index 365eee48af..0ec4ea07bb 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildPropertyGroup.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildPropertyGroup.cs
@@ -32,7 +32,8 @@ using System.Xml;
using MonoDevelop.Core;
using System.Xml.Linq;
using Microsoft.Build.BuildEngine;
-
+using System.Collections.Immutable;
+
namespace MonoDevelop.Projects.Formats.MSBuild
{
public class MSBuildPropertyGroup: MSBuildElement, IMSBuildPropertySet, IMSBuildEvaluatedPropertyCollection
@@ -43,12 +44,17 @@ namespace MonoDevelop.Projects.Formats.MSBuild
{
}
- internal override List<MSBuildNode> ChildNodes {
+ internal override ImmutableList<MSBuildNode> ChildNodes {
get {
if (ParentNode is MSBuildItem)
return ((MSBuildItem)ParentNode).ChildNodes;
return base.ChildNodes;
}
+ set {
+ if (ParentNode is MSBuildItem)
+ ((MSBuildItem)ParentNode).ChildNodes = value;
+ base.ChildNodes = value;
+ }
}
internal MSBuildObject PropertiesParent {
@@ -67,7 +73,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
prop.ParentNode = PropertiesParent;
prop.Owner = this;
prop.Read (reader);
- ChildNodes.Add (prop);
+ ChildNodes = ChildNodes.Add (prop);
properties [prop.Name] = prop; // If a property is defined more than once, we only care about the last registered value
}
@@ -85,6 +91,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
internal void CopyFrom (MSBuildPropertyGroup other)
{
+ AssertCanModify ();
foreach (var node in other.ChildNodes) {
var prop = node as MSBuildProperty;
if (prop != null) {
@@ -92,16 +99,16 @@ namespace MonoDevelop.Projects.Formats.MSBuild
var currentPropIndex = ChildNodes.FindIndex (p => (p is MSBuildProperty) && ((MSBuildProperty)p).Name == prop.Name);
if (currentPropIndex != -1) {
var currentProp = (MSBuildProperty) ChildNodes [currentPropIndex];
- ChildNodes [currentPropIndex] = cp;
+ ChildNodes = ChildNodes.SetItem (currentPropIndex, cp);
} else {
- ChildNodes.Add (cp);
+ ChildNodes = ChildNodes.Add (cp);
}
properties [cp.Name] = cp;
cp.ParentNode = PropertiesParent;
cp.Owner = this;
cp.ResetIndent (false);
} else
- ChildNodes.Add (node);
+ ChildNodes = ChildNodes.Add (node);
}
foreach (var prop in ChildNodes.OfType<MSBuildProperty> ().ToArray ()) {
if (!other.HasProperty (prop.Name))
@@ -214,6 +221,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
MSBuildProperty AddProperty (string name, string condition = null)
{
+ AssertCanModify ();
int i = propertyOrder.IndexOf (name);
int insertIndex = -1;
if (i != -1) {
@@ -233,9 +241,9 @@ namespace MonoDevelop.Projects.Formats.MSBuild
properties [name] = prop;
if (insertIndex != -1)
- ChildNodes.Insert (insertIndex, prop);
+ ChildNodes = ChildNodes.Insert (insertIndex, prop);
else
- ChildNodes.Add (prop);
+ ChildNodes = ChildNodes.Add (prop);
if (condition != null)
prop.Condition = condition;
@@ -272,6 +280,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetValue (string name, string value, string defaultValue = null, bool preserveExistingCase = false, bool mergeToMainGroup = false, string condition = null)
{
+ AssertCanModify ();
if (value == null && defaultValue == "")
value = "";
var prop = GetProperty (name, condition);
@@ -295,6 +304,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetValue (string name, FilePath value, FilePath defaultValue = default(FilePath), bool relativeToProject = true, FilePath relativeToPath = default(FilePath), bool mergeToMainGroup = false, string condition = null)
{
+ AssertCanModify ();
var prop = GetProperty (name, condition);
var isDefault = value.CanonicalPath == defaultValue.CanonicalPath;
if (isDefault && !mergeToMainGroup) {
@@ -316,6 +326,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetValue (string name, object value, object defaultValue = null, bool mergeToMainGroup = false, string condition = null)
{
+ AssertCanModify ();
var prop = GetProperty (name, condition);
var isDefault = object.Equals (value, defaultValue);
if (isDefault && !mergeToMainGroup) {
@@ -347,21 +358,24 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void RemoveProperty (MSBuildProperty prop)
{
+ AssertCanModify ();
prop.RemoveIndent ();
properties.Remove (prop.Name);
- ChildNodes.Remove (prop);
+ ChildNodes = ChildNodes.Remove (prop);
NotifyChanged ();
}
public void RemoveAllProperties ()
{
+ AssertCanModify ();
properties.Clear ();
- ChildNodes.Clear ();
+ ChildNodes = ChildNodes.Clear ();
NotifyChanged ();
}
public void UnMerge (IMSBuildPropertySet baseGrp, ISet<string> propsToExclude)
{
+ AssertCanModify ();
HashSet<string> baseProps = new HashSet<string> ();
foreach (MSBuildProperty prop in baseGrp.GetProperties ()) {
if (propsToExclude != null && propsToExclude.Contains (prop.Name))
@@ -398,6 +412,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void SetPropertyOrder (params string[] propertyNames)
{
+ AssertCanModify ();
int i = 0;
foreach (var name in propertyNames) {
if (i < propertyOrder.Count) {
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildTarget.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildTarget.cs
index 269086c445..8405304be5 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildTarget.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildTarget.cs
@@ -62,6 +62,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
return this.afterTargets;
}
set {
+ AssertCanModify ();
this.afterTargets = value;
NotifyChanged ();
}
@@ -72,6 +73,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
return this.inputs;
}
set {
+ AssertCanModify ();
this.inputs = value;
NotifyChanged ();
}
@@ -82,6 +84,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
return this.outputs;
}
set {
+ AssertCanModify ();
this.outputs = value;
NotifyChanged ();
}
@@ -92,6 +95,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
return this.beforeTargets;
}
set {
+ AssertCanModify ();
this.beforeTargets = value;
NotifyChanged ();
}
@@ -103,6 +107,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
return this.dependsOnTargets;
}
set {
+ AssertCanModify ();
this.dependsOnTargets = value;
NotifyChanged ();
}
@@ -113,6 +118,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
return this.returns;
}
set {
+ AssertCanModify ();
this.returns = value;
NotifyChanged ();
}
@@ -123,6 +129,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
return this.keepDuplicateOutputs;
}
set {
+ AssertCanModify ();
this.keepDuplicateOutputs = value;
NotifyChanged ();
}
@@ -173,14 +180,14 @@ namespace MonoDevelop.Projects.Formats.MSBuild
if (ob != null) {
ob.ParentNode = this;
ob.Read (reader);
- ChildNodes.Add (ob);
+ ChildNodes = ChildNodes.Add (ob);
return;
}
var task = new MSBuildTask ();
task.ParentNode = this;
task.Read (reader);
- ChildNodes.Add (task);
+ ChildNodes = ChildNodes.Add (task);
}
internal override void Write (XmlWriter writer, WriteContext context)
@@ -195,7 +202,7 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public MSBuildTarget (string name, IEnumerable<MSBuildTask> tasks)
{
this.name = name;
- ChildNodes.AddRange (tasks);
+ ChildNodes = ChildNodes.AddRange (tasks);
}
public string Name {
@@ -210,10 +217,11 @@ namespace MonoDevelop.Projects.Formats.MSBuild
public void RemoveTask (MSBuildTask task)
{
+ AssertCanModify ();
if (task.ParentObject != this)
throw new InvalidOperationException ("Task doesn't belong to the target");
task.RemoveIndent ();
- ChildNodes.Remove (task);
+ ChildNodes = ChildNodes.Remove (task);
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildXmlNode.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildXmlNode.cs
index b146ee7f56..89db16f5a0 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildXmlNode.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Formats.MSBuild/MSBuildXmlNode.cs
@@ -51,6 +51,13 @@ namespace MonoDevelop.Projects.Formats.MSBuild
{
}
+ internal virtual void AssertCanModify ()
+ {
+ var pp = ParentProject;
+ if (pp != null)
+ pp.AssertCanModify ();
+ }
+
internal MSBuildNode ParentNode {
get {
return parentObject;