diff --git a/SharpDevelop.Tests.sln b/SharpDevelop.Tests.sln
index e63f4fc36c..c16bcc493c 100644
--- a/SharpDevelop.Tests.sln
+++ b/SharpDevelop.Tests.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
-# SharpDevelop 5.0
+# SharpDevelop 4.3
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
diff --git a/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/WebProjectTests.cs b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/WebProjectTests.cs
index 7206d00021..13cc2f4abd 100644
--- a/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/WebProjectTests.cs
+++ b/src/AddIns/BackendBindings/AspNet.Mvc/Test/Src/WebProjectTests.cs
@@ -55,7 +55,8 @@ namespace AspNet.Mvc.Tests
{
var fileContentsBuilder = new StringBuilder();
var stringWriter = new StringWriter(fileContentsBuilder);
- msbuildProject.MSBuildProjectFile.Save(stringWriter);
+ lock (msbuildProject.SyncRoot)
+ msbuildProject.MSBuildProjectFile.Save(stringWriter);
return GetProjectExtensions(fileContentsBuilder.ToString());
}
diff --git a/src/AddIns/BackendBindings/WixBinding/Test/Project/CreateNewWixProjectObjectTestFixture.cs b/src/AddIns/BackendBindings/WixBinding/Test/Project/CreateNewWixProjectObjectTestFixture.cs
index 967dce17ab..3779eb487a 100644
--- a/src/AddIns/BackendBindings/WixBinding/Test/Project/CreateNewWixProjectObjectTestFixture.cs
+++ b/src/AddIns/BackendBindings/WixBinding/Test/Project/CreateNewWixProjectObjectTestFixture.cs
@@ -129,10 +129,12 @@ namespace WixBinding.Tests.Project
///
ProjectPropertyElement GetMSBuildProperty(string name)
{
- foreach (ProjectPropertyGroupElement propertyGroup in project.MSBuildProjectFile.PropertyGroups) {
- foreach (ProjectPropertyElement element in propertyGroup.Properties) {
- if (element.Name == name) {
- return element;
+ lock (project.SyncRoot) {
+ foreach (ProjectPropertyGroupElement propertyGroup in project.MSBuildProjectFile.PropertyGroups) {
+ foreach (ProjectPropertyElement element in propertyGroup.Properties) {
+ if (element.Name == name) {
+ return element;
+ }
}
}
}
@@ -145,10 +147,12 @@ namespace WixBinding.Tests.Project
ProjectPropertyElement GetLastMSBuildProperty(string name)
{
ProjectPropertyElement matchedElement = null;
- foreach (ProjectPropertyGroupElement propertyGroup in project.MSBuildProjectFile.PropertyGroups) {
- foreach (ProjectPropertyElement element in propertyGroup.Properties) {
- if (element.Name == name) {
- matchedElement = element;
+ lock (project.SyncRoot) {
+ foreach (ProjectPropertyGroupElement propertyGroup in project.MSBuildProjectFile.PropertyGroups) {
+ foreach (ProjectPropertyElement element in propertyGroup.Properties) {
+ if (element.Name == name) {
+ matchedElement = element;
+ }
}
}
}
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
index bf9782f5f8..771e944bbf 100755
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
@@ -80,6 +80,8 @@
class="ICSharpCode.SharpDevelop.Project.MSBuildEngine"/>
+
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
index 559bfb27c3..17b9919bdc 100644
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
@@ -233,6 +233,7 @@
OutputWindowOptionsPanel.xaml
Code
+
diff --git a/src/Main/Base/Project/Project/Build/ProjectBuildOptions.cs b/src/Main/Base/Project/Project/Build/ProjectBuildOptions.cs
index bfb47392eb..e19d0fbfd1 100644
--- a/src/Main/Base/Project/Project/Build/ProjectBuildOptions.cs
+++ b/src/Main/Base/Project/Project/Build/ProjectBuildOptions.cs
@@ -12,7 +12,7 @@ namespace ICSharpCode.SharpDevelop.Project
public class ProjectBuildOptions
{
BuildTarget target;
- IDictionary properties = new SortedList();
+ IDictionary properties = new SortedList(MSBuildInternals.PropertyNameComparer);
public BuildTarget Target {
get { return target; }
diff --git a/src/Main/Base/Project/Project/Configuration/ConfigurationAndPlatform.cs b/src/Main/Base/Project/Project/Configuration/ConfigurationAndPlatform.cs
index 7be777bb14..02dfe6db18 100644
--- a/src/Main/Base/Project/Project/Configuration/ConfigurationAndPlatform.cs
+++ b/src/Main/Base/Project/Project/Configuration/ConfigurationAndPlatform.cs
@@ -12,7 +12,7 @@ namespace ICSharpCode.SharpDevelop.Project
///
public struct ConfigurationAndPlatform : IEquatable
{
- public static readonly StringComparer ConfigurationNameComparer = StringComparer.Ordinal;
+ public static readonly StringComparer ConfigurationNameComparer = StringComparer.OrdinalIgnoreCase;
public static bool IsValidName(string name)
{
diff --git a/src/Main/Base/Project/Src/Project/CompilableProject.cs b/src/Main/Base/Project/Src/Project/CompilableProject.cs
index 1ff019c8ca..3c2579e16f 100644
--- a/src/Main/Base/Project/Src/Project/CompilableProject.cs
+++ b/src/Main/Base/Project/Src/Project/CompilableProject.cs
@@ -84,7 +84,7 @@ namespace ICSharpCode.SharpDevelop.Project
PropertyStorageLocations.ConfigurationSpecific, true);
SetProperty("Release", null, "OutputPath", @"bin\Release\",
PropertyStorageLocations.ConfigurationSpecific, true);
- InvalidateConfigurationPlatformNames();
+ LoadConfigurationPlatformNamesFromMSBuild();
SetProperty("Debug", null, "DebugSymbols", "True",
PropertyStorageLocations.ConfigurationSpecific, true);
diff --git a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs
index 47fe0b0b25..b61907369e 100644
--- a/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs
+++ b/src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
@@ -13,16 +12,14 @@ using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
+
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Dom;
-using ICSharpCode.SharpDevelop.Gui;
-using ICSharpCode.SharpDevelop.Internal.Templates;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;
using MSBuild = Microsoft.Build.Evaluation;
-using StringPair = System.Tuple;
namespace ICSharpCode.SharpDevelop.Project
{
@@ -57,7 +54,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// Use this for properties that could reference other properties, e.g.
/// PostBuildEvent references OutputPath.
///
- protected readonly ISet saveAfterImportsProperties = new SortedSet {
+ protected readonly ISet saveAfterImportsProperties = new SortedSet(MSBuildInternals.PropertyNameComparer) {
"PostBuildEvent",
"PreBuildEvent"
};
@@ -85,6 +82,7 @@ namespace ICSharpCode.SharpDevelop.Project
get {
if (projectFile == null)
throw new ObjectDisposedException("MSBuildBasedProject");
+ Debug.Assert(Monitor.IsEntered(SyncRoot));
return projectFile;
}
}
@@ -98,6 +96,7 @@ namespace ICSharpCode.SharpDevelop.Project
get {
if (projectFile == null)
throw new ObjectDisposedException("MSBuildBasedProject");
+ Debug.Assert(Monitor.IsEntered(SyncRoot));
return userProjectFile;
}
}
@@ -161,6 +160,8 @@ namespace ICSharpCode.SharpDevelop.Project
: base(information)
{
this.itemsCollection = new ProjectItemCollection(this);
+ this.configurationNames = new MSBuildConfigurationOrPlatformNameCollection(this, false);
+ this.platformNames = new MSBuildConfigurationOrPlatformNameCollection(this, true);
this.projectFile = ProjectRootElement.Create(MSBuildProjectCollection);
this.userProjectFile = ProjectRootElement.Create(MSBuildProjectCollection);
@@ -174,10 +175,11 @@ namespace ICSharpCode.SharpDevelop.Project
AddGuardedProperty("Platform", information.ActiveProjectConfiguration.Platform);
string platform = information.ActiveProjectConfiguration.Platform;
- if (platform == "x86")
+ if (ConfigurationAndPlatform.ConfigurationNameComparer.Equals(platform, "x86"))
SetProperty(null, platform, "PlatformTarget", "x86", PropertyStorageLocations.PlatformSpecific, false);
else
SetProperty(null, platform, "PlatformTarget", "AnyCPU", PropertyStorageLocations.PlatformSpecific, false);
+ LoadConfigurationPlatformNamesFromMSBuild();
}
///
@@ -391,7 +393,7 @@ namespace ICSharpCode.SharpDevelop.Project
if (platform == null)
platform = this.ActiveConfiguration.Platform;
- bool openCurrentConfiguration = configuration == this.ActiveConfiguration.Configuration && platform == this.ActiveConfiguration.Platform;
+ bool openCurrentConfiguration = new ConfigurationAndPlatform(configuration, platform) == this.ActiveConfiguration;
if (currentlyOpenProject != null && openCurrentConfiguration) {
// use currently open project
@@ -399,7 +401,7 @@ namespace ICSharpCode.SharpDevelop.Project
return new ConfiguredProject(this, currentlyOpenProject, false);
}
- Dictionary globalProps = new Dictionary();
+ Dictionary globalProps = new Dictionary(MSBuildInternals.PropertyNameComparer);
var msbuildEngine = SD.Services.GetService();
if (msbuildEngine != null)
globalProps.AddRange(msbuildEngine.GlobalBuildProperties);
@@ -534,8 +536,9 @@ namespace ICSharpCode.SharpDevelop.Project
var configFromCondition = ConfigurationAndPlatform.FromCondition(g.Condition);
string gConfiguration = configFromCondition.Configuration;
string gPlatform = configFromCondition.Platform;
- if ((configuration == null || configuration == gConfiguration || gConfiguration == null)
- && (platform == null || platform == gPlatform || gPlatform == null))
+ StringComparer comparer = ConfigurationAndPlatform.ConfigurationNameComparer;
+ if ((configuration == null || comparer.Equals(configuration, gConfiguration) || gConfiguration == null)
+ && (platform == null || comparer.Equals(platform, gPlatform) || gPlatform == null))
{
if (gConfiguration == null && gPlatform == null) {
location = PropertyStorageLocations.Base;
@@ -597,12 +600,12 @@ namespace ICSharpCode.SharpDevelop.Project
PropertyStorageLocations FindExistingPropertyInAllConfigurations(string propertyName)
{
foreach (var g in projectFile.PropertyGroups) {
- if (g.Properties.Any(p => MSBuildInternals.PropertyNameComparer.Equals(p.Name == propertyName))) {
+ if (g.Properties.Any(p => MSBuildInternals.PropertyNameComparer.Equals(p.Name, propertyName))) {
return MSBuildInternals.GetLocationFromCondition(g.Condition);
}
}
foreach (var g in userProjectFile.PropertyGroups) {
- if (g.Properties.Any(p => MSBuildInternals.PropertyNameComparer.Equals(p.Name == propertyName))) {
+ if (g.Properties.Any(p => MSBuildInternals.PropertyNameComparer.Equals(p.Name, propertyName))) {
return MSBuildInternals.GetLocationFromCondition(g.Condition)
| PropertyStorageLocations.UserFile;
}
@@ -713,7 +716,7 @@ namespace ICSharpCode.SharpDevelop.Project
break;
case PropertyStorageLocations.ConfigurationSpecific:
// Get any value usable as existing property value (once per configuration)
- Dictionary oldValuesConf = new Dictionary();
+ Dictionary oldValuesConf = new Dictionary(ConfigurationAndPlatform.ConfigurationNameComparer);
foreach (string conf in this.ConfigurationNames) {
oldValuesConf[conf] = GetAnyUnevaluatedPropertyValue(conf, null, propertyName);
}
@@ -733,7 +736,7 @@ namespace ICSharpCode.SharpDevelop.Project
break;
case PropertyStorageLocations.PlatformSpecific:
// Get any value usable as existing property value (once per platform)
- Dictionary oldValuesPlat = new Dictionary();
+ Dictionary oldValuesPlat = new Dictionary(ConfigurationAndPlatform.ConfigurationNameComparer);
foreach (string plat in this.PlatformNames) {
oldValuesPlat[plat] = GetAnyUnevaluatedPropertyValue(null, plat, propertyName);
}
@@ -753,10 +756,10 @@ namespace ICSharpCode.SharpDevelop.Project
break;
case PropertyStorageLocations.ConfigurationAndPlatformSpecific:
// Get any value usable as existing property value (once per configuration+platform)
- Dictionary oldValues = new Dictionary();
+ Dictionary oldValues = new Dictionary();
foreach (string conf in this.ConfigurationNames) {
foreach (string plat in this.PlatformNames) {
- oldValues[new StringPair(conf, plat)] = GetAnyUnevaluatedPropertyValue(conf, plat, propertyName);
+ oldValues[new ConfigurationAndPlatform(conf, plat)] = GetAnyUnevaluatedPropertyValue(conf, plat, propertyName);
}
}
@@ -764,10 +767,10 @@ namespace ICSharpCode.SharpDevelop.Project
RemovePropertyCompletely(propertyName);
// Recreate the property using the saved value
- foreach (KeyValuePair pair in oldValues) {
+ foreach (KeyValuePair pair in oldValues) {
if (pair.Value != null) {
MSBuildSetProperty(targetProject, propertyName, pair.Value,
- ConfigurationAndPlatform.CreateCondition(pair.Key.Item1, pair.Key.Item2, location),
+ ConfigurationAndPlatform.CreateCondition(pair.Key.Configuration, pair.Key.Platform, location),
propertyInsertionPosition,
false);
}
@@ -1087,7 +1090,7 @@ namespace ICSharpCode.SharpDevelop.Project
itemsReadOnly = null; // remove readonly variant of item list - will regenerate on next Items call
string newInclude = item.TreatIncludeAsLiteral ? MSBuildInternals.Escape(item.Include) : item.Include;
- var newMetadata = new Dictionary();
+ var newMetadata = new Dictionary(MSBuildInternals.PropertyNameComparer);
foreach (string name in item.MetadataNames) {
newMetadata[name] = item.GetMetadata(name);
}
@@ -1190,6 +1193,9 @@ namespace ICSharpCode.SharpDevelop.Project
: base(loadInformation)
{
this.itemsCollection = new ProjectItemCollection(this);
+ this.configurationNames = new MSBuildConfigurationOrPlatformNameCollection(this, false);
+ this.platformNames = new MSBuildConfigurationOrPlatformNameCollection(this, true);
+
isLoading = true;
bool success = false;
try {
@@ -1311,61 +1317,44 @@ namespace ICSharpCode.SharpDevelop.Project
#endregion
#region GetConfigurationNames / GetPlatformNames
- IReadOnlyCollection configurationNames, platformNames;
+ readonly MSBuildConfigurationOrPlatformNameCollection configurationNames, platformNames;
- #warning reimplement configuration management
- /*public override IReadOnlyCollection ConfigurationNames {
- get {
- lock (SyncRoot) {
- if (configurationNames == null) {
- LoadConfigurationPlatformNamesFromMSBuild();
- }
- return configurationNames;
- }
- }
+ public override IConfigurationOrPlatformNameCollection ConfigurationNames {
+ get { return configurationNames; }
}
- public override IReadOnlyCollection PlatformNames {
- get {
- lock (SyncRoot) {
- if (platformNames == null) {
- LoadConfigurationPlatformNamesFromMSBuild();
- }
- return platformNames;
- }
- }
- }
- */
- protected void InvalidateConfigurationPlatformNames()
- {
- lock (SyncRoot) {
- configurationNames = null;
- platformNames = null;
- }
+ public override IConfigurationOrPlatformNameCollection PlatformNames {
+ get { return platformNames; }
}
///
/// Load available configurations and platforms from the project file
/// by looking at which conditions are used.
///
- void LoadConfigurationPlatformNamesFromMSBuild()
+ protected internal void LoadConfigurationPlatformNamesFromMSBuild()
{
- ISet configurationNames = new SortedSet();
- ISet platformNames = new SortedSet();
-
- LoadConfigurationPlatformNamesFromMSBuildInternal(projectFile, configurationNames, platformNames);
- LoadConfigurationPlatformNamesFromMSBuildInternal(userProjectFile, configurationNames, platformNames);
-
- if (configurationNames.Count == 0) {
- configurationNames.Add("Debug");
- configurationNames.Add("Release");
- }
- if (platformNames.Count == 0) {
- platformNames.Add("AnyCPU");
+ lock (SyncRoot) {
+ ISet configurationNames = new SortedSet(ConfigurationAndPlatform.ConfigurationNameComparer);
+ ISet platformNames = new SortedSet(ConfigurationAndPlatform.ConfigurationNameComparer);
+
+ LoadConfigurationPlatformNamesFromMSBuildInternal(projectFile, configurationNames, platformNames);
+ LoadConfigurationPlatformNamesFromMSBuildInternal(userProjectFile, configurationNames, platformNames);
+
+ if (configurationNames.Count == 0) {
+ configurationNames.Add("Debug");
+ configurationNames.Add("Release");
+ }
+ if (platformNames.Count == 0) {
+ platformNames.Add("AnyCPU");
+ }
+
+ var oldConfigurationNames = this.configurationNames.CreateSnapshot();
+ var oldPlatformNames = this.platformNames.CreateSnapshot();
+ this.configurationNames.SetContents(configurationNames);
+ this.platformNames.SetContents(platformNames);
+ this.configurationNames.OnCollectionChanged(oldConfigurationNames, configurationNames.ToArray());
+ this.platformNames.OnCollectionChanged(oldPlatformNames, platformNames.ToArray());
}
-
- this.configurationNames = configurationNames.ToArray();
- this.platformNames = platformNames.ToArray();
}
static void LoadConfigurationPlatformNamesFromMSBuildInternal(
@@ -1395,200 +1384,6 @@ namespace ICSharpCode.SharpDevelop.Project
}
#endregion
- #region IProjectAllowChangeConfigurations interface implementation
- /*
- bool IProjectAllowChangeConfigurations.RenameProjectConfiguration(string oldName, string newName)
- {
- lock (SyncRoot) {
- foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.Concat(userProjectFile.PropertyGroups)) {
- // Rename the default configuration setting
- var prop = g.Properties.FirstOrDefault(p => p.Name == "Configuration");
- if (prop != null && prop.Value == oldName) {
- prop.Value = newName;
- }
-
- // Rename the configuration in conditions
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gConfiguration == oldName) {
- g.Condition = CreateCondition(newName, gPlatform);
- }
- }
- LoadConfigurationPlatformNamesFromMSBuild();
- return true;
- }
- }
-
- bool IProjectAllowChangeConfigurations.RenameProjectPlatform(string oldName, string newName)
- {
- lock (SyncRoot) {
- foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.Concat(userProjectFile.PropertyGroups)) {
- // Rename the default platform setting
- var prop = g.Properties.FirstOrDefault(p => p.Name == "Platform");
- if (prop != null && prop.Value == oldName) {
- prop.Value = newName;
- }
-
- // Rename the platform in conditions
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gPlatform == oldName) {
- g.Condition = CreateCondition(gConfiguration, newName);
- }
- }
- LoadConfigurationPlatformNamesFromMSBuild();
- return true;
- }
- }
-
- bool IProjectAllowChangeConfigurations.AddProjectConfiguration(string newName, string copyFrom)
- {
- lock (SyncRoot) {
- bool copiedGroupInMainFile = false;
- if (copyFrom != null) {
- foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.ToList()) {
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gConfiguration == copyFrom) {
- CopyProperties(projectFile, g, newName, gPlatform);
- copiedGroupInMainFile = true;
- }
- }
- foreach (ProjectPropertyGroupElement g in userProjectFile.PropertyGroups.ToList()) {
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gConfiguration == copyFrom) {
- CopyProperties(userProjectFile, g, newName, gPlatform);
- }
- }
- }
- if (!copiedGroupInMainFile) {
- projectFile.AddPropertyGroup().Condition = CreateCondition(newName, null);
- }
- LoadConfigurationPlatformNamesFromMSBuild();
- return true;
- }
- }
-
- bool IProjectAllowChangeConfigurations.AddProjectPlatform(string newName, string copyFrom)
- {
- lock (SyncRoot) {
- bool copiedGroupInMainFile = false;
- if (copyFrom != null) {
- foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.ToList()) {
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gPlatform == copyFrom) {
- CopyProperties(projectFile, g, gConfiguration, newName);
- copiedGroupInMainFile = true;
- }
- }
- foreach (ProjectPropertyGroupElement g in userProjectFile.PropertyGroups.ToList()) {
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gPlatform == copyFrom) {
- CopyProperties(userProjectFile, g, gConfiguration, newName);
- }
- }
- }
- if (!copiedGroupInMainFile) {
- projectFile.AddPropertyGroup().Condition = CreateCondition(null, newName);
- }
- LoadConfigurationPlatformNamesFromMSBuild();
- return true;
- }
- }
-
- ///
- /// copy properties from g into a new property group for newConfiguration and newPlatform
- ///
- void CopyProperties(ProjectRootElement project, ProjectPropertyGroupElement g, string newConfiguration, string newPlatform)
- {
- ProjectPropertyGroupElement ng = project.AddPropertyGroup();
- ng.Condition = CreateCondition(newConfiguration, newPlatform);
- foreach (var p in g.Properties) {
- ng.AddProperty(p.Name, p.Value).Condition = p.Condition;
- }
- }
-
- bool IProjectAllowChangeConfigurations.RemoveProjectConfiguration(string name)
- {
- lock (SyncRoot) {
- string otherConfigurationName = null;
- foreach (string configName in this.ConfigurationNames) {
- if (configName != name) {
- otherConfigurationName = name;
- break;
- }
- }
- if (otherConfigurationName == null) {
- throw new InvalidOperationException("cannot remove the last configuration");
- }
- foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.Concat(userProjectFile.PropertyGroups).ToList()) {
- ProjectPropertyElement prop = g.Properties.FirstOrDefault(p => p.Name == "Configuration");
- if (prop != null && prop.Value == name) {
- prop.Value = otherConfigurationName;
- }
-
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gConfiguration == name) {
- g.Parent.RemoveChild(g);
- }
- }
- LoadConfigurationPlatformNamesFromMSBuild();
- return true;
- }
- }
-
- bool IProjectAllowChangeConfigurations.RemoveProjectPlatform(string name)
- {
- lock (SyncRoot) {
- string otherPlatformName = null;
- foreach (string platformName in this.PlatformNames) {
- if (platformName != name) {
- otherPlatformName = name;
- break;
- }
- }
- if (otherPlatformName == null) {
- throw new InvalidOperationException("cannot remove the last platform");
- }
- foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.Concat(userProjectFile.PropertyGroups).ToList()) {
- ProjectPropertyElement prop = g.Properties.FirstOrDefault(p => p.Name == "Platform");
- if (prop != null && prop.Value == name) {
- prop.Value = otherPlatformName;
- }
-
- string gConfiguration, gPlatform;
- MSBuildInternals.GetConfigurationAndPlatformFromCondition(g.Condition,
- out gConfiguration,
- out gPlatform);
- if (gPlatform == name) {
- g.Parent.RemoveChild(g);
- }
- }
- LoadConfigurationPlatformNamesFromMSBuild();
- return true;
- }
- }
- */
- #endregion
-
#region ProjectExtensions
public override bool ContainsProjectExtension(string name)
{
diff --git a/src/Main/Base/Project/Src/Project/MSBuildConfigurationOrPlatformNameCollection.cs b/src/Main/Base/Project/Src/Project/MSBuildConfigurationOrPlatformNameCollection.cs
new file mode 100644
index 0000000000..1e2ab9a30b
--- /dev/null
+++ b/src/Main/Base/Project/Src/Project/MSBuildConfigurationOrPlatformNameCollection.cs
@@ -0,0 +1,250 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using ICSharpCode.NRefactory;
+using ICSharpCode.SharpDevelop.Dom;
+using Microsoft.Build.Construction;
+
+namespace ICSharpCode.SharpDevelop.Project
+{
+ ///
+ /// The collection for and .
+ ///
+ class MSBuildConfigurationOrPlatformNameCollection : IConfigurationOrPlatformNameCollection
+ {
+ public event ModelCollectionChangedEventHandler CollectionChanged;
+
+ volatile IReadOnlyList listSnapshot = EmptyList.Instance;
+ readonly MSBuildBasedProject project;
+ readonly bool isPlatform;
+
+ public MSBuildConfigurationOrPlatformNameCollection(MSBuildBasedProject project, bool isPlatform)
+ {
+ this.project = project;
+ this.isPlatform = isPlatform;
+ }
+
+ internal void SetContents(IEnumerable updatedItems)
+ {
+ this.listSnapshot = updatedItems.ToArray();
+ }
+
+ internal void OnCollectionChanged(IReadOnlyCollection oldItems, IReadOnlyCollection newItems)
+ {
+ if (oldItems.SequenceEqual(newItems))
+ return;
+ var eh = CollectionChanged;
+ if (eh != null)
+ eh(oldItems, newItems);
+ }
+
+ #region IReadOnlyCollection implementation
+
+ public IReadOnlyCollection CreateSnapshot()
+ {
+ return listSnapshot;
+ }
+
+ public int Count {
+ get {
+ return listSnapshot.Count;
+ }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return listSnapshot.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return listSnapshot.GetEnumerator();
+ }
+
+ #endregion
+
+ public string ValidateName(string name)
+ {
+ if (name == null)
+ return null;
+ name = name.Trim();
+ if (!ConfigurationAndPlatform.IsValidName(name))
+ return null;
+ if (isPlatform)
+ return MSBuildInternals.FixPlatformNameForProject(name);
+ else
+ return name;
+ }
+
+ string GetName(ConfigurationAndPlatform config)
+ {
+ return isPlatform ? config.Platform : config.Configuration;
+ }
+
+ bool HasName(ConfigurationAndPlatform config, string name)
+ {
+ return ConfigurationAndPlatform.ConfigurationNameComparer.Equals(GetName(config), name);
+ }
+
+ ConfigurationAndPlatform SetName(ConfigurationAndPlatform config, string newName)
+ {
+ if (isPlatform)
+ return new ConfigurationAndPlatform(config.Configuration, newName);
+ else
+ return new ConfigurationAndPlatform(newName, config.Platform);
+ }
+
+ void IConfigurationOrPlatformNameCollection.Add(string newName, string copyFrom)
+ {
+ SD.MainThread.VerifyAccess();
+ newName = ValidateName(newName);
+ if (newName == null)
+ throw new ArgumentException();
+ lock (project.SyncRoot) {
+ var projectFile = project.MSBuildProjectFile;
+ var userProjectFile = project.MSBuildUserProjectFile;
+ bool copiedGroupInMainFile = false;
+ if (copyFrom != null) {
+ foreach (ProjectPropertyGroupElement g in projectFile.PropertyGroups.ToList()) {
+ var gConfig = ConfigurationAndPlatform.FromCondition(g.Condition);
+ if (HasName(gConfig, copyFrom)) {
+ CopyProperties(projectFile, g, SetName(gConfig, newName));
+ copiedGroupInMainFile = true;
+ }
+ }
+ foreach (ProjectPropertyGroupElement g in userProjectFile.PropertyGroups.ToList()) {
+ var gConfig = ConfigurationAndPlatform.FromCondition(g.Condition);
+ if (HasName(gConfig, copyFrom)) {
+ CopyProperties(userProjectFile, g, SetName(gConfig, newName));
+ }
+ }
+ }
+ if (!copiedGroupInMainFile) {
+ projectFile.AddPropertyGroup().Condition = (isPlatform ? new ConfigurationAndPlatform(null, newName) : new ConfigurationAndPlatform(newName, null)).ToCondition();
+ }
+ project.LoadConfigurationPlatformNamesFromMSBuild();
+
+ // Adjust mapping:
+ // If the new config/platform already exists in the solution and is mapped to some old project config/platform,
+ // re-map it to the new config/platform.
+ var mapping = project.ConfigurationMapping;
+ if (isPlatform) {
+ string newNameForSolution = MSBuildInternals.FixPlatformNameForSolution(newName);
+ if (project.ParentSolution.PlatformNames.Contains(newNameForSolution, ConfigurationAndPlatform.ConfigurationNameComparer)) {
+ foreach (string solutionConfiguration in project.ParentSolution.ConfigurationNames) {
+ var solutionConfig = new ConfigurationAndPlatform(solutionConfiguration, newNameForSolution);
+ var projectConfig = mapping.GetProjectConfiguration(solutionConfig);
+ mapping.SetProjectConfiguration(solutionConfig, SetName(projectConfig, newName));
+ }
+ }
+ } else {
+ if (project.ParentSolution.ConfigurationNames.Contains(newName, ConfigurationAndPlatform.ConfigurationNameComparer)) {
+ foreach (string solutionPlatform in project.ParentSolution.PlatformNames) {
+ var solutionConfig = new ConfigurationAndPlatform(newName, solutionPlatform);
+ var projectConfig = mapping.GetProjectConfiguration(solutionConfig);
+ mapping.SetProjectConfiguration(solutionConfig, SetName(projectConfig, newName));
+ }
+ }
+ }
+ project.ActiveConfiguration = mapping.GetProjectConfiguration(project.ParentSolution.ActiveConfiguration);
+ }
+ }
+
+ ///
+ /// copy properties from g into a new property group for newConfiguration and newPlatform
+ ///
+ void CopyProperties(ProjectRootElement project, ProjectPropertyGroupElement g, ConfigurationAndPlatform newConfig)
+ {
+ ProjectPropertyGroupElement ng = project.AddPropertyGroup();
+ ng.Condition = newConfig.ToCondition();
+ foreach (var p in g.Properties) {
+ ng.AddProperty(p.Name, p.Value).Condition = p.Condition;
+ }
+ }
+
+ ///
+ /// Finds the <Configuration> or <Platform> element in this property group.
+ ///
+ ProjectPropertyElement FindConfigElement(ProjectPropertyGroupElement g)
+ {
+ return g.Properties.FirstOrDefault(p => MSBuildInternals.PropertyNameComparer.Equals(p.Name, isPlatform ? "Platform" : "Configuration"));
+ }
+
+ void IConfigurationOrPlatformNameCollection.Remove(string name)
+ {
+ SD.MainThread.VerifyAccess();
+ lock (project.SyncRoot) {
+ string otherName = null;
+ foreach (string configName in this) {
+ if (!ConfigurationAndPlatform.ConfigurationNameComparer.Equals(configName, name)) {
+ otherName = name;
+ break;
+ }
+ }
+ if (otherName == null) {
+ throw new InvalidOperationException("cannot remove the last configuration/platform");
+ }
+ foreach (ProjectPropertyGroupElement g in project.MSBuildProjectFile.PropertyGroups.Concat(project.MSBuildUserProjectFile.PropertyGroups).ToList()) {
+ ProjectPropertyElement prop = FindConfigElement(g);
+ if (prop != null && ConfigurationAndPlatform.ConfigurationNameComparer.Equals(prop.Value, name)) {
+ prop.Value = otherName;
+ }
+
+ var gConfig = ConfigurationAndPlatform.FromCondition(g.Condition);
+ if (HasName(gConfig, name)) {
+ g.Parent.RemoveChild(g);
+ }
+ }
+ project.LoadConfigurationPlatformNamesFromMSBuild();
+
+ AdjustMapping(name, otherName);
+ }
+ }
+
+ void IConfigurationOrPlatformNameCollection.Rename(string oldName, string newName)
+ {
+ newName = ValidateName(newName);
+ if (newName == null)
+ throw new ArgumentException();
+
+ lock (project.SyncRoot) {
+ foreach (ProjectPropertyGroupElement g in project.MSBuildProjectFile.PropertyGroups.Concat(project.MSBuildUserProjectFile.PropertyGroups)) {
+ // Rename the default configuration setting
+ ProjectPropertyElement prop = FindConfigElement(g);
+ if (prop != null && ConfigurationAndPlatform.ConfigurationNameComparer.Equals(prop.Value, oldName)) {
+ prop.Value = newName;
+ }
+
+ // Rename the configuration in conditions
+ var gConfig = ConfigurationAndPlatform.FromCondition(g.Condition);
+ if (HasName(gConfig, oldName)) {
+ g.Condition = SetName(gConfig, newName).ToCondition();
+ }
+ }
+ project.LoadConfigurationPlatformNamesFromMSBuild();
+
+ AdjustMapping(oldName, newName);
+ }
+ }
+
+ void AdjustMapping(string oldName, string newName)
+ {
+ var mapping = project.ConfigurationMapping;
+ foreach (string solutionConfiguration in project.ParentSolution.ConfigurationNames) {
+ foreach (string solutionPlatform in project.ParentSolution.PlatformNames) {
+ var solutionConfig = new ConfigurationAndPlatform(solutionConfiguration, solutionPlatform);
+ var projectConfig = mapping.GetProjectConfiguration(solutionConfig);
+ if (HasName(projectConfig, oldName))
+ mapping.SetProjectConfiguration(solutionConfig, SetName(projectConfig, newName));
+ }
+ }
+ // Adjust active configuration:
+ if (HasName(project.ActiveConfiguration, oldName))
+ project.ActiveConfiguration = SetName(project.ActiveConfiguration, newName);
+ }
+ }
+}
diff --git a/src/Main/Base/Project/Src/Project/MSBuildInternals.cs b/src/Main/Base/Project/Src/Project/MSBuildInternals.cs
index 7475b74477..385a4d79ca 100644
--- a/src/Main/Base/Project/Src/Project/MSBuildInternals.cs
+++ b/src/Main/Base/Project/Src/Project/MSBuildInternals.cs
@@ -25,6 +25,7 @@ namespace ICSharpCode.SharpDevelop.Project
// TODO: I think MSBuild actually uses OrdinalIgnoreCase. SharpDevelop 3.x just used string.operator ==, so I'm keeping
// that setting until all code is ported to use PropertyNameComparer and we've verified what MSBuild is actually using.
public readonly static StringComparer PropertyNameComparer = StringComparer.Ordinal;
+ public readonly static StringComparer ConfigurationNameComparer = ConfigurationAndPlatform.ConfigurationNameComparer;
internal static void UnloadProject(MSBuild.Evaluation.ProjectCollection projectCollection, MSBuild.Evaluation.Project project)
{
@@ -123,9 +124,9 @@ namespace ICSharpCode.SharpDevelop.Project
return PropertyStorageLocations.Base;
}
PropertyStorageLocations location = 0; // 0 is unknown
- if (condition.Contains("$(Configuration)"))
+ if (condition.IndexOf("$(Configuration)", StringComparison.OrdinalIgnoreCase) >= 0)
location |= PropertyStorageLocations.ConfigurationSpecific;
- if (condition.Contains("$(Platform)"))
+ if (condition.IndexOf("$(Platform)", StringComparison.OrdinalIgnoreCase) >= 0)
location |= PropertyStorageLocations.PlatformSpecific;
return location;
}
diff --git a/src/Main/SharpDevelop/Project/Configuration/EditAvailableConfigurationsDialog.cs b/src/Main/SharpDevelop/Project/Configuration/EditAvailableConfigurationsDialog.cs
index 71c95476f6..423075541e 100644
--- a/src/Main/SharpDevelop/Project/Configuration/EditAvailableConfigurationsDialog.cs
+++ b/src/Main/SharpDevelop/Project/Configuration/EditAvailableConfigurationsDialog.cs
@@ -106,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Project
return false;
}
foreach (string item in listBox.Items) {
- if (string.Equals(item, newName, StringComparison.OrdinalIgnoreCase)) {
+ if (ConfigurationAndPlatform.ConfigurationNameComparer.Equals(item, newName)) {
MessageService.ShowMessage("${res:Dialog.EditAvailableConfigurationsDialog.DuplicateName}");
return false;
}