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>2016-07-13 16:39:30 +0300
committerLluis Sanchez <lluis@xamarin.com>2016-07-13 16:39:30 +0300
commitd04e8a42146c183fae438a196bd7213517ce9de7 (patch)
treee3a86c18e2817d67075523e8f34fdce9c8605f23 /main/src/core/MonoDevelop.Core
parent2b0cf79be1c546ec18129188aecde7e3bcd3821d (diff)
parent7446a7c8606c95180d7f2c89461ee3d3d44ec05d (diff)
Merge remote-tracking branch 'origin/run-configurations'
Diffstat (limited to 'main/src/core/MonoDevelop.Core')
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/ExecutionModeSetNode.cs13
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionCommand.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs8
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionModeSet.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs14
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ClassDataType.cs1
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/DataValue.cs16
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemProperty.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemPropertyAttribute.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs46
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml5
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj14
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs11
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs14
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs9
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectExtensions.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildPropertyGroup.cs5
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTask.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/AssemblyRunConfiguration.cs137
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs161
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectExtension.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/EnvironmentVariableCollection.cs189
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExecutionContext.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/IRunTarget.cs83
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs560
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MultiItemSolutionRunConfiguration.cs (renamed from main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/CustomRuntimeExecutionModeSet.cs)45
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProcessRunConfiguration.cs88
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs412
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectCreateInformation.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs15
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFeature.cs3
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectRunConfiguration.cs156
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfiguration.cs59
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfigurationCollection.cs65
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SingleItemSolutionRunConfiguration.cs45
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs372
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionExtension.cs43
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs231
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs48
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemRunConfiguration.cs72
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfiguration.cs66
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfigurationCollection.cs65
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/UnknownProject.cs2
44 files changed, 2802 insertions, 313 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/ExecutionModeSetNode.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/ExecutionModeSetNode.cs
index e9dfe7addd..0dd6fca37d 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/ExecutionModeSetNode.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.AddIns/ExecutionModeSetNode.cs
@@ -32,6 +32,7 @@ using MonoDevelop.Core.Execution;
namespace MonoDevelop.Core.AddIns
{
[ExtensionNodeChild (typeof(ExecutionModeNode), "Mode")]
+ [ExtensionNodeChild (typeof(TypeExtensionNode), "ModeSetType")]
class ExecutionModeSetNode: ExtensionNode, IExecutionModeSet
{
[NodeAttribute ("_name", Localizable=true)]
@@ -43,8 +44,16 @@ namespace MonoDevelop.Core.AddIns
public IEnumerable<IExecutionMode> ExecutionModes {
get {
- foreach (ExecutionModeNode node in ChildNodes)
- yield return node;
+ foreach (ExtensionNode node in ChildNodes) {
+ if (node is ExecutionModeNode)
+ yield return (ExecutionModeNode)node;
+ else if (node is TypeExtensionNode) {
+ var mset = ((TypeExtensionNode)node).GetInstance () as IExecutionModeSet;
+ if (mset != null)
+ foreach (var h in mset.ExecutionModes)
+ yield return h;
+ }
+ }
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionCommand.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionCommand.cs
index d6d06cb63e..2c30d2900c 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionCommand.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/DotNetExecutionCommand.cs
@@ -74,5 +74,9 @@ namespace MonoDevelop.Core.Execution
public string RuntimeArguments { get; set; }
public IList<string> UserAssemblyPaths { get; set; }
+
+ public bool PauseConsoleOutput { get; set; }
+
+ public bool ExternalConsole { get; set; }
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs
index fbde4d74ec..1d27b28859 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionHandler.cs
@@ -29,6 +29,9 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using System.Threading.Tasks;
+using Mono.Addins;
+using MonoDevelop.Projects;
namespace MonoDevelop.Core.Execution
{
@@ -70,4 +73,9 @@ namespace MonoDevelop.Core.Execution
/// </summary>
ExecutionTarget Target { get; }
}
+
+ public interface IConfigurableExecutionHandler
+ {
+ Task<IExecutionHandler> Configure (IRunTarget target, MonoDevelop.Projects.ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration);
+ }
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionModeSet.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionModeSet.cs
index bcad34dda9..ab5337b8fe 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionModeSet.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/IExecutionModeSet.cs
@@ -54,7 +54,7 @@ namespace MonoDevelop.Core.Execution
class DefaultExecutionModeSet: IExecutionModeSet
{
public string Name {
- get { return GettextCatalog.GetString ("Default"); }
+ get { return GettextCatalog.GetString ("Run"); }
}
public IEnumerable<IExecutionMode> ExecutionModes {
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs
index a84f5846d7..c04dfa427e 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Execution/ProcessService.cs
@@ -222,9 +222,17 @@ namespace MonoDevelop.Core.Execution
if (environmentVariables != null)
foreach (KeyValuePair<string, string> kvp in environmentVariables)
psi.EnvironmentVariables [kvp.Key] = kvp.Value;
- ProcessWrapper pw = StartProcess (psi, console.Out, console.Error, null);
- new ProcessMonitor (console, pw.ProcessAsyncOperation, exited);
- return pw.ProcessAsyncOperation;
+ try {
+ ProcessWrapper pw = StartProcess (psi, console.Out, console.Error, null);
+ new ProcessMonitor (console, pw.ProcessAsyncOperation, exited);
+ return pw.ProcessAsyncOperation;
+ } catch (Exception ex) {
+ // If the process can't be started, dispose the console now since ProcessMonitor won't do it
+ console.Error.WriteLine (GettextCatalog.GetString ("The application could not be started"));
+ LoggingService.LogError ("Could not start process for command: " + psi.FileName + " " + psi.Arguments, ex);
+ console.Dispose ();
+ return NullProcessAsyncOperation.Failure;
+ }
}
public IExecutionHandler GetDefaultExecutionHandler (ExecutionCommand command)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ClassDataType.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ClassDataType.cs
index c1d0954759..944d53eb36 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ClassDataType.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ClassDataType.cs
@@ -123,6 +123,7 @@ namespace MonoDevelop.Core.Serialization
prop.SkipEmpty = at.SkipEmpty;
prop.ReadOnly = at.ReadOnly;
prop.WriteOnly = at.WriteOnly;
+ prop.WrapObject = at.WrapObject;
if (prop.ExpandedCollection) {
ICollectionHandler handler = Context.GetCollectionHandler (memberType);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/DataValue.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/DataValue.cs
index 68dd002dce..2f4f290364 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/DataValue.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/DataValue.cs
@@ -34,7 +34,7 @@ namespace MonoDevelop.Core.Serialization
public class DataValue: DataNode
{
string value;
- bool storeAsAttribute;
+ bool? storeAsAttribute;
public DataValue (string name, string value)
{
@@ -45,8 +45,8 @@ namespace MonoDevelop.Core.Serialization
public string Value {
get { return value; }
}
-
- internal bool StoreAsAttribute {
+
+ internal bool? StoreAsAttribute {
get {
return storeAsAttribute;
}
@@ -54,7 +54,15 @@ namespace MonoDevelop.Core.Serialization
storeAsAttribute = value;
}
}
-
+
+ internal bool StoreAsAttributeRequired {
+ get { return storeAsAttribute.HasValue && storeAsAttribute.Value; }
+ }
+
+ internal bool StoreAsElementRequired {
+ get { return storeAsAttribute.HasValue && !storeAsAttribute.Value; }
+ }
+
public override string ToString ()
{
return ToString (0);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemProperty.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemProperty.cs
index 8e88dc3b2d..219dfb21ed 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemProperty.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemProperty.cs
@@ -135,6 +135,8 @@ namespace MonoDevelop.Core.Serialization
get { return dataType; }
set { CheckReadOnly (); dataType = value; }
}
+
+ public bool WrapObject { get; set; }
public bool SkipEmpty { get; set; }
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemPropertyAttribute.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemPropertyAttribute.cs
index bbd9a3c7b5..b24faf0bc2 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemPropertyAttribute.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/ItemPropertyAttribute.cs
@@ -98,7 +98,9 @@ namespace MonoDevelop.Core.Serialization
get { return writeOnly; }
set { writeOnly = value; }
}
-
+
+ public bool WrapObject { get; set; } = true;
+
public Type FallbackType {
get { return fallbackType; }
set { fallbackType = value; }
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs
index 4765c079fc..909dc252fd 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Serialization/XmlDataSerializer.cs
@@ -163,20 +163,20 @@ namespace MonoDevelop.Core.Serialization
protected virtual void WriteAttributes (XmlElement elem, DataItem item)
{
- if (StoreAllInElements)
- return;
+ var defaultIsAtt = item.UniqueNames && !StoreAllInElements;
foreach (DataNode data in item.ItemData) {
DataValue val = data as DataValue;
- if (val != null && (item.UniqueNames || val.StoreAsAttribute))
+ if (val != null && (StoreAsAttribute (val) || (defaultIsAtt && !val.StoreAsElementRequired)))
WriteAttribute (elem, val.Name, val.Value);
}
}
protected virtual void WriteAttributes (XmlWriter writer, DataItem item)
{
+ var defaultIsAtt = item.UniqueNames && !StoreAllInElements;
foreach (DataNode data in item.ItemData) {
DataValue val = data as DataValue;
- if (val != null && (item.UniqueNames || val.StoreAsAttribute) && StoreAsAttribute (val))
+ if (val != null && (StoreAsAttribute (val) || (defaultIsAtt && !val.StoreAsElementRequired)))
WriteAttribute (writer, val.Name, val.Value);
}
}
@@ -193,33 +193,21 @@ namespace MonoDevelop.Core.Serialization
protected virtual void WriteChildren (XmlWriter writer, DataItem item)
{
- if (item.UniqueNames) {
- foreach (DataNode data in item.ItemData) {
- if (!(data is DataValue) || !StoreAsAttribute ((DataValue)data))
- WriteChild (writer, data);
- }
- } else {
- foreach (DataNode data in item.ItemData) {
- DataValue dval = data as DataValue;
- if (dval == null || !dval.StoreAsAttribute || !StoreAsAttribute (dval))
- WriteChild (writer, data);
- }
+ var defaultIsAtt = item.UniqueNames && !StoreAllInElements;
+ foreach (DataNode data in item.ItemData) {
+ DataValue dval = data as DataValue;
+ if (dval == null || !(StoreAsAttribute (dval) || (defaultIsAtt && !dval.StoreAsElementRequired)))
+ WriteChild (writer, data);
}
}
protected virtual void WriteChildren (XmlElement elem, DataItem item)
{
- if (item.UniqueNames) {
- foreach (DataNode data in item.ItemData) {
- if (!(data is DataValue) || !StoreAsAttribute ((DataValue)data))
- WriteChild (elem, data);
- }
- } else {
- foreach (DataNode data in item.ItemData) {
- DataValue dval = data as DataValue;
- if (dval == null || !dval.StoreAsAttribute || !StoreAsAttribute (dval))
- WriteChild (elem, data);
- }
+ var defaultIsAtt = item.UniqueNames && !StoreAllInElements;
+ foreach (DataNode data in item.ItemData) {
+ DataValue dval = data as DataValue;
+ if (dval == null || !(StoreAsAttribute (dval) || (defaultIsAtt && !dval.StoreAsElementRequired)))
+ WriteChild (elem, data);
}
}
@@ -235,10 +223,12 @@ namespace MonoDevelop.Core.Serialization
public virtual bool StoreAsAttribute (DataValue val)
{
- if (StoreAllInElements)
+ if (val.StoreAsAttributeRequired)
+ return true;
+ else if (StoreAllInElements)
return StoreInElementExceptions != null && ((IList)StoreInElementExceptions).Contains (val.Name);
else
- return true;
+ return false;
}
protected virtual XmlConfigurationWriter GetChildWriter (DataNode data)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml
index 95b81c4706..c575762361 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.addin.xml
@@ -160,8 +160,9 @@
<Extension path = "/MonoDevelop/Core/ExecutionModes">
-<!-- <Mode id="Default" _name="Default" class="MonoDevelop.Core.Execution.DefaultExecutionHandlerFactory"/>-->
- <ModeSetType class="MonoDevelop.Core.Assemblies.CustomRuntimeExecutionModeSet"/>
+ <ModeSet id="Run" _name="Run" />
+ <ModeSet id="Debug" _name="Debug" />
+ <ModeSet id="Profile" _name="Profile" />
</Extension>
<Extension path = "/MonoDevelop/Core/Runtimes">
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
index 00d711ef7e..e025833a7f 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
@@ -210,7 +210,6 @@
<Compile Include="MonoDevelop.Core.Assemblies\SystemAssemblyService.cs" />
<Compile Include="MonoDevelop.Core.Assemblies\MonoRuntimeInfo.cs" />
<Compile Include="MonoDevelop.Core.Execution\IExecutionModeSet.cs" />
- <Compile Include="MonoDevelop.Core.Assemblies\CustomRuntimeExecutionModeSet.cs" />
<Compile Include="MonoDevelop.Core.Execution\ExecutionMode.cs" />
<Compile Include="MonoDevelop.Core.Execution\ExecutionCommand.cs" />
<Compile Include="MonoDevelop.Core.Execution\DotNetExecutionCommand.cs" />
@@ -562,6 +561,19 @@
<Compile Include="MonoDevelop.Core.Execution\RemoteProcessConnection.cs" />
<Compile Include="MonoDevelop.Core.Execution\RemoteProcessServer.cs" />
<Compile Include="MonoDevelop.Projects\AssemblyReference.cs" />
+ <Compile Include="MonoDevelop.Projects\SolutionItemRunConfiguration.cs" />
+ <Compile Include="MonoDevelop.Projects\ProjectRunConfiguration.cs" />
+ <Compile Include="MonoDevelop.Projects\RunConfigurationCollection.cs" />
+ <Compile Include="MonoDevelop.Projects\AssemblyRunConfiguration.cs" />
+ <Compile Include="MonoDevelop.Projects\MonoExecutionParameters.cs" />
+ <Compile Include="MonoDevelop.Projects\SolutionRunConfiguration.cs" />
+ <Compile Include="MonoDevelop.Projects\SingleItemSolutionRunConfiguration.cs" />
+ <Compile Include="MonoDevelop.Projects\MultiItemSolutionRunConfiguration.cs" />
+ <Compile Include="MonoDevelop.Projects\SolutionRunConfigurationCollection.cs" />
+ <Compile Include="MonoDevelop.Projects\EnvironmentVariableCollection.cs" />
+ <Compile Include="MonoDevelop.Projects\RunConfiguration.cs" />
+ <Compile Include="MonoDevelop.Projects\IRunTarget.cs" />
+ <Compile Include="MonoDevelop.Projects\ProcessRunConfiguration.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.am" />
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
index aec39b743e..e0a76f53ad 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
@@ -173,13 +173,18 @@ namespace MonoDevelop.Projects.MSBuild
void EvaluateProject (ProjectInfo pi, MSBuildEvaluationContext context)
{
context.InitEvaluation (pi.Project);
- EvaluateObjects (pi, context, pi.Project.GetAllObjects (), false);
- EvaluateObjects (pi, context, pi.Project.GetAllObjects (), true);
+ var objects = pi.Project.GetAllObjects ();
+
+ // If there is a .user project file load it using a fake import item added at the end of the objects list
+ if (File.Exists (pi.Project.FileName + ".user"))
+ objects = objects.Concat (new MSBuildImport {Project = pi.Project.FileName + ".user" });
+
+ EvaluateObjects (pi, context, objects, false);
+ EvaluateObjects (pi, context, objects, true);
}
void EvaluateProject (ProjectInfo pi, MSBuildEvaluationContext context, bool evalItems)
{
- // XmlDocument is not thread safe, so we need to lock while evaluating
context.InitEvaluation (pi.Project);
EvaluateObjects (pi, context, pi.Project.GetAllObjects (), evalItems);
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs
index 386b018710..e466073a95 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IMSBuildPropertySet.cs
@@ -57,6 +57,7 @@ namespace MonoDevelop.Projects.MSBuild
DataSerializer ser = new DataSerializer (Services.ProjectService.DataContext);
var props = Services.ProjectService.DataContext.GetProperties (ser.SerializationContext, ob);
XmlConfigurationWriter cwriter = null;
+ XmlDocument xdoc = null;
var mso = pset as IMSBuildProjectObject;
if (mso != null && mso.ParentProject != null)
@@ -84,13 +85,14 @@ namespace MonoDevelop.Projects.MSBuild
} else {
var val = prop.GetValue (ob);
if (val != null) {
- if (cwriter == null)
- cwriter = new XmlConfigurationWriter { Namespace = MSBuildProject.Schema };
- var w = new StringWriter ();
+ if (cwriter == null) {
+ cwriter = new XmlConfigurationWriter { Namespace = MSBuildProject.Schema, StoreAllInElements = true };
+ xdoc = new XmlDocument ();
+ }
var data = prop.Serialize (ser.SerializationContext, ob, val);
if (data != null) {
- cwriter.Write (new XmlTextWriter (w), data);
- pset.SetValue (prop.Name, w.ToString ());
+ var elem = cwriter.Write (xdoc, data);
+ pset.SetValue (prop.Name, prop.WrapObject ? elem.OuterXml : elem.InnerXml);
} else
pset.RemoveProperty (prop.Name);
} else
@@ -130,6 +132,8 @@ namespace MonoDevelop.Projects.MSBuild
var val = pset.GetValue (prop.Name);
if (!string.IsNullOrEmpty (val)) {
try {
+ if (!prop.WrapObject)
+ val = "<a>" + val + "</a>";
var data = XmlConfigurationReader.DefaultReader.Read (new XmlTextReader (new StringReader (val)));
if (prop.HasSetter && prop.DataType.CanCreateInstance) {
readVal = prop.Deserialize (ser.SerializationContext, ob, data);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs
index 4b8de4f6a6..40894626db 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildObject.cs
@@ -60,15 +60,16 @@ namespace MonoDevelop.Projects.MSBuild
internal object EndInnerWhitespace { get; set; }
internal virtual bool PreferEmptyElement { get { return true; } }
+ internal virtual bool ContentRequiredForEvaluation { get { return true; } }
- #if ATTR_STATS
+#if ATTR_STATS
public static StringCounter UnknownAtts = new StringCounter ();
public static StringCounter KnownAttOrder = new StringCounter ();
- #endif
+#endif
internal override void Read (MSBuildXmlReader reader)
{
- if (reader.ForEvaluation) {
+ if (reader.ForEvaluation && !ContentRequiredForEvaluation) {
if (reader.MoveToFirstAttribute ()) {
do {
ReadAttribute (reader.LocalName, reader.Value);
@@ -319,7 +320,7 @@ namespace MonoDevelop.Projects.MSBuild
internal virtual void ReadChildElement (MSBuildXmlReader reader)
{
- if (reader.ForEvaluation)
+ if (reader.ForEvaluation && !ContentRequiredForEvaluation)
reader.Skip ();
else {
var n = new MSBuildXmlElement ();
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectExtensions.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectExtensions.cs
index 2f0a36142a..104282143e 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectExtensions.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectExtensions.cs
@@ -45,6 +45,12 @@ namespace MonoDevelop.Projects.MSBuild
base.Read (reader);
}
+ internal override bool ContentRequiredForEvaluation {
+ get {
+ return false;
+ }
+ }
+
internal override string GetElementName ()
{
return "ProjectExtensions";
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildPropertyGroup.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildPropertyGroup.cs
index de81e5f52c..ae3e2f1dfd 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildPropertyGroup.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildPropertyGroup.cs
@@ -259,6 +259,11 @@ namespace MonoDevelop.Projects.MSBuild
internal IPropertyGroupListener PropertyGroupListener { get; set; }
+ internal void UnlinkFromProjectInstance ()
+ {
+ PropertyGroupListener = null;
+ }
+
MSBuildProperty FindExistingProperty (int index, int inc)
{
while (index >= 0 && index < propertyOrder.Count) {
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTask.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTask.cs
index 95716a4644..36a7d28a83 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTask.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildTask.cs
@@ -50,6 +50,12 @@ namespace MonoDevelop.Projects.MSBuild
this.Name = name;
}
+ internal override bool ContentRequiredForEvaluation {
+ get {
+ return false;
+ }
+ }
+
static readonly string [] knownAttributes = { "Condition", "Label" };
internal override string [] GetKnownAttributes ()
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/AssemblyRunConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/AssemblyRunConfiguration.cs
new file mode 100644
index 0000000000..6a970419ff
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/AssemblyRunConfiguration.cs
@@ -0,0 +1,137 @@
+//
+// DotNetRunConfiguration.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.Linq;
+using MonoDevelop.Core;
+using MonoDevelop.Core.StringParsing;
+using MonoDevelop.Projects.MSBuild;
+using MonoDevelop.Core.Serialization;
+using System.Linq;
+using MonoDevelop.Core.Execution;
+
+namespace MonoDevelop.Projects
+{
+ public class AssemblyRunConfiguration: ProcessRunConfiguration
+ {
+ MonoExecutionParameters monoParameters = new MonoExecutionParameters ();
+
+ public AssemblyRunConfiguration (string name): base (name)
+ {
+ }
+
+ internal protected override void Initialize (Project project)
+ {
+ base.Initialize (project);
+ StartAction = StartActions.Project;
+ }
+
+ [ItemProperty (DefaultValue = "")]
+ public string StartAction { get; set; }
+
+ [ItemProperty (DefaultValue = "")]
+ public FilePath StartProgram { get; set; } = "";
+
+ public class StartActions
+ {
+ public const string Project = "Project";
+ public const string Program = "Program";
+ }
+
+ public override string Summary {
+ get {
+ string envVars = null;
+ if (EnvironmentVariables.Count > 0) {
+ var v = EnvironmentVariables.First ();
+ envVars = v.Key + "=" + v.Value;
+ if (EnvironmentVariables.Count > 1)
+ envVars += "...";
+ }
+ if (StartAction == StartActions.Project) {
+ if (!string.IsNullOrEmpty (StartArguments) && envVars != null)
+ return GettextCatalog.GetString ("Start the project with arguments '{0}' and environment variables '{1}'", StartArguments, envVars);
+ else if (!string.IsNullOrEmpty (StartArguments))
+ return GettextCatalog.GetString ("Start the project with arguments '{0}'", StartArguments);
+ else if (envVars != null)
+ return GettextCatalog.GetString ("Start the project with environment variables '{0}''", envVars);
+ else
+ return GettextCatalog.GetString ("Start the project");
+ } else {
+ if (StartProgram.IsNullOrEmpty)
+ return GettextCatalog.GetString ("Selected startup program is not valid");
+ var app = StartProgram.FileName;
+ if (!string.IsNullOrEmpty (StartArguments) && EnvironmentVariables.Count > 0)
+ return GettextCatalog.GetString ("Run {0} with arguments '{1}' and custom environment variables '{2}'", app, StartArguments, envVars);
+ else if (!string.IsNullOrEmpty (StartArguments))
+ return GettextCatalog.GetString ("Run {0} with arguments '{1}'", app, StartArguments);
+ else if (envVars != null)
+ return GettextCatalog.GetString ("Run {0} with environment variables '{1}'", app, envVars);
+ else
+ return GettextCatalog.GetString ("Run {0}", app);
+ }
+ }
+ }
+
+ public bool IsEmpty {
+ get { return string.IsNullOrEmpty (StartArguments) && string.IsNullOrEmpty (StartWorkingDirectory) && StartAction == StartActions.Project && EnvironmentVariables.Count == 0 && string.IsNullOrEmpty (TargetRuntimeId); }
+ }
+
+ internal protected override void Read (IPropertySet pset)
+ {
+ base.Read (pset);
+ pset.ReadObjectProperties (monoParameters, monoParameters.GetType (), false);
+ }
+
+ internal protected override void Write (IPropertySet pset)
+ {
+ pset.SetPropertyOrder ("StartAction", "StartProgram", "StartArguments", "StartWorkingDirectory", "ExternalConsole", "ConsolePause", "EnvironmentVariables");
+ pset.WriteObjectProperties (monoParameters, monoParameters.GetType (), false);
+ base.Write (pset);
+ }
+
+ public MonoExecutionParameters MonoParameters {
+ get { return monoParameters; }
+ set { monoParameters = value; }
+ }
+
+ [ItemProperty (DefaultValue = "")]
+ public string TargetRuntimeId { get; set; } = "";
+
+ protected override void OnCopyFrom (ProjectRunConfiguration config, bool isRename)
+ {
+ base.OnCopyFrom (config, isRename);
+
+ var other = (AssemblyRunConfiguration)config;
+
+ StartProgram = other.StartProgram;
+ StartAction = other.StartAction;
+ monoParameters = other.monoParameters.Clone ();
+ TargetRuntimeId = other.TargetRuntimeId;
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs
index 6b5226d49c..bd2a34afa5 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs
@@ -143,7 +143,7 @@ namespace MonoDevelop.Projects
return Task.FromResult (BuildResult.CreateSuccess ());
}
- protected async override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ protected async override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
ProjectConfiguration conf = (ProjectConfiguration) GetConfiguration (configuration);
monitor.Log.WriteLine (GettextCatalog.GetString ("Running {0} ...", FileName));
@@ -178,7 +178,7 @@ namespace MonoDevelop.Projects
}
}
- protected override bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration)
+ protected override bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
ProjectConfiguration config = (ProjectConfiguration) GetConfiguration (configuration);
if (config == null)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
index 1c35c9fe5b..2efcbbca18 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProject.cs
@@ -142,14 +142,12 @@ namespace MonoDevelop.Projects
DotNetProjectConfiguration configDebug = CreateConfiguration ("Debug" + platformSuffix, ConfigurationKind.Debug) as DotNetProjectConfiguration;
DefineSymbols (configDebug.CompilationParameters, projectOptions, "DefineConstantsDebug");
configDebug.ExternalConsole = externalConsole;
- configDebug.PauseConsoleOutput = externalConsole;
Configurations.Add (configDebug);
DotNetProjectConfiguration configRelease = CreateConfiguration ("Release" + platformSuffix, ConfigurationKind.Release) as DotNetProjectConfiguration;
DefineSymbols (configRelease.CompilationParameters, projectOptions, "DefineConstantsRelease");
configRelease.CompilationParameters.RemoveDefineSymbol ("DEBUG");
configRelease.ExternalConsole = externalConsole;
- configRelease.PauseConsoleOutput = externalConsole;
Configurations.Add (configRelease);
}
@@ -1027,6 +1025,10 @@ namespace MonoDevelop.Projects
return conf;
}
+ protected override ProjectRunConfiguration OnCreateRunConfiguration (string name)
+ {
+ return new AssemblyRunConfiguration (name);
+ }
protected override FilePath OnGetOutputFileName (ConfigurationSelector configuration)
{
@@ -1110,9 +1112,15 @@ namespace MonoDevelop.Projects
.Where (d => !string.IsNullOrEmpty (d)).ToList ();
}
+ [Obsolete("Use the overload that takes a RunConfiguration")]
public ExecutionCommand CreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration)
{
- return ProjectExtension.OnCreateExecutionCommand (configSel, configuration);
+ return CreateExecutionCommand (configSel, configuration, GetDefaultRunConfiguration () as ProjectRunConfiguration);
+ }
+
+ public ExecutionCommand CreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration, ProjectRunConfiguration runConfiguration)
+ {
+ return ProjectExtension.OnCreateExecutionCommand (configSel, configuration, runConfiguration);
}
internal protected virtual ExecutionCommand OnCreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration)
@@ -1125,16 +1133,85 @@ namespace MonoDevelop.Projects
return cmd;
}
- protected override bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration)
+ internal protected virtual ExecutionCommand OnCreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration, ProjectRunConfiguration runConfiguration)
{
- DotNetProjectConfiguration config = (DotNetProjectConfiguration) GetConfiguration (configuration);
+ ExecutionCommand rcmd;
+ var rc = runConfiguration as AssemblyRunConfiguration;
+ if (rc != null && rc.StartAction == AssemblyRunConfiguration.StartActions.Program) {
+ var pcmd = Runtime.ProcessService.CreateCommand (rc.StartProgram);
+ pcmd.Arguments = rc.StartArguments;
+ pcmd.WorkingDirectory = rc.StartWorkingDirectory;
+ pcmd.EnvironmentVariables = rc.EnvironmentVariables;
+ rcmd = pcmd;
+ } else {
+#pragma warning disable 618 // Type or member is obsolete
+ rcmd = ProjectExtension.OnCreateExecutionCommand (configSel, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ var cmd = rcmd as DotNetExecutionCommand;
+ if (cmd == null)
+ return rcmd;
+
+ if (rc != null) {
+ // Don't directly overwrite the settings, since those may have been set by the OnCreateExecutionCommand
+ // overload that doesn't take a runConfiguration.
+
+ string monoOptions;
+ rc.MonoParameters.GenerateOptions (cmd.EnvironmentVariables, out monoOptions);
+ cmd.RuntimeArguments = monoOptions;
+ if (!string.IsNullOrEmpty (rc.StartArguments))
+ cmd.Arguments = rc.StartArguments;
+ if (!rc.StartWorkingDirectory.IsNullOrEmpty)
+ cmd.WorkingDirectory = rc.StartWorkingDirectory;
+ foreach (var env in rc.EnvironmentVariables)
+ cmd.EnvironmentVariables [env.Key] = env.Value;
+ cmd.PauseConsoleOutput = rc.PauseConsoleOutput;
+ cmd.ExternalConsole = rc.ExternalConsole;
+ cmd.TargetRuntime = Runtime.SystemAssemblyService.GetTargetRuntime (rc.TargetRuntimeId);
+ }
+ return cmd;
+ }
+
+ protected override bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+ DotNetProjectConfiguration config = (DotNetProjectConfiguration)GetConfiguration (configuration);
if (config == null)
return false;
- ExecutionCommand cmd = CreateExecutionCommand (configuration, config);
- if (context.ExecutionTarget != null)
- cmd.Target = context.ExecutionTarget;
+
+ var runConfig = runConfiguration as ProjectRunConfiguration;
+ if (runConfig == null)
+ return false;
+
+ var asmRunConfig = runConfiguration as AssemblyRunConfiguration;
+
+ ExecutionCommand executionCommand;
+
+ if (asmRunConfig != null && asmRunConfig.StartAction == AssemblyRunConfiguration.StartActions.Program) {
+ executionCommand = Runtime.ProcessService.CreateCommand (asmRunConfig.StartProgram);
+ // If it is command for executing an assembly, add runtime options
+ var dcmd = executionCommand as DotNetExecutionCommand;
+ if (dcmd != null) {
+ string monoOptions;
+ asmRunConfig.MonoParameters.GenerateOptions (dcmd.EnvironmentVariables, out monoOptions);
+ dcmd.RuntimeArguments = monoOptions;
+ }
+ // If it is command for executing a process, add arguments, work directory and env vars
+ var pcmd = executionCommand as ProcessExecutionCommand;
+ if (pcmd != null) {
+ pcmd.Arguments = asmRunConfig.StartArguments;
+ pcmd.WorkingDirectory = asmRunConfig.StartWorkingDirectory;
+
+ foreach (var env in asmRunConfig.EnvironmentVariables)
+ pcmd.EnvironmentVariables [env.Key] = env.Value;
+ }
+ } else {
+ executionCommand = CreateExecutionCommand (configuration, config, runConfig);
+ if (context.ExecutionTarget != null)
+ executionCommand.Target = context.ExecutionTarget;
+ }
- return (compileTarget == CompileTarget.Exe || compileTarget == CompileTarget.WinExe) && context.ExecutionHandler.CanExecute (cmd);
+ return executionCommand != null && context.ExecutionHandler.CanExecute (executionCommand);
}
protected override ProjectFeatures OnGetSupportedFeatures ()
@@ -1142,12 +1219,31 @@ namespace MonoDevelop.Projects
var sf = base.OnGetSupportedFeatures ();
// Libraries are not executable by default, unless the project has a custom execution command
- if (compileTarget == CompileTarget.Library && !Configurations.OfType<ProjectConfiguration> ().Any (c => c.CustomCommands.HasCommands (CustomCommandType.Execute)))
+ if (compileTarget == CompileTarget.Library
+ && !Configurations.OfType<ProjectConfiguration> ().Any (c => c.CustomCommands.HasCommands (CustomCommandType.Execute))
+ && !GetRunConfigurations ().Any ()
+ )
sf &= ~ProjectFeatures.Execute;
return sf;
}
+ protected override IEnumerable<SolutionItemRunConfiguration> OnGetRunConfigurations ()
+ {
+ var configs = base.OnGetRunConfigurations ();
+ if (compileTarget == CompileTarget.Library) {
+ // A library project can't run by itself, so discard configurations which have "Project" as startup action
+ foreach (var c in configs) {
+ var dc = c as AssemblyRunConfiguration;
+ if (dc != null && (dc.StartAction == AssemblyRunConfiguration.StartActions.Project || string.IsNullOrEmpty (dc.StartProgram)))
+ continue;
+ yield return c;
+ }
+ } else
+ foreach (var c in configs)
+ yield return c;
+ }
+
protected override IEnumerable<FilePath> OnGetItemFiles (bool includeReferencedFiles)
{
var baseFiles = base.OnGetItemFiles (includeReferencedFiles);
@@ -1505,7 +1601,7 @@ namespace MonoDevelop.Projects
CheckReferenceChange (ei.FileName);
}
- protected async override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ protected async override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
DotNetProjectConfiguration dotNetProjectConfig = GetConfiguration (configuration) as DotNetProjectConfiguration;
if (dotNetProjectConfig == null) {
@@ -1515,7 +1611,7 @@ namespace MonoDevelop.Projects
monitor.Log.WriteLine (GettextCatalog.GetString ("Running {0} ...", dotNetProjectConfig.CompiledOutputName));
- ExecutionCommand executionCommand = CreateExecutionCommand (configuration, dotNetProjectConfig);
+ ExecutionCommand executionCommand = CreateExecutionCommand (configuration, dotNetProjectConfig, runConfiguration as ProjectRunConfiguration);
if (context.ExecutionTarget != null)
executionCommand.Target = context.ExecutionTarget;
@@ -1534,15 +1630,18 @@ namespace MonoDevelop.Projects
protected virtual async Task OnExecuteCommand (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, ExecutionCommand executionCommand)
{
+ bool externalConsole = false, pauseConsole = false;
+
var dotNetExecutionCommand = executionCommand as DotNetExecutionCommand;
if (dotNetExecutionCommand != null) {
dotNetExecutionCommand.UserAssemblyPaths = GetUserAssemblyPaths (configuration);
+ externalConsole = dotNetExecutionCommand.ExternalConsole;
+ pauseConsole = dotNetExecutionCommand.PauseConsoleOutput;
}
- var dotNetProjectConfig = GetConfiguration (configuration) as DotNetProjectConfiguration;
- var console = dotNetProjectConfig.ExternalConsole
- ? context.ExternalConsoleFactory.CreateConsole (!dotNetProjectConfig.PauseConsoleOutput, monitor.CancellationToken)
- : context.ConsoleFactory.CreateConsole (monitor.CancellationToken);
+ var console = externalConsole ? context.ExternalConsoleFactory.CreateConsole (!pauseConsole, monitor.CancellationToken)
+ : context.ConsoleFactory.CreateConsole (monitor.CancellationToken);
+
using (console) {
ProcessAsyncOperation asyncOp = context.ExecutionHandler.Execute (executionCommand, console);
@@ -1584,6 +1683,29 @@ namespace MonoDevelop.Projects
TargetFramework = Runtime.SystemAssemblyService.GetTargetFramework (targetFx);
}
+ internal override void ImportDefaultRunConfiguration (ProjectRunConfiguration config)
+ {
+ base.ImportDefaultRunConfiguration (config);
+ if (config is AssemblyRunConfiguration) {
+ var defaultConf = (DefaultConfiguration ?? Configurations.FirstOrDefault<SolutionItemConfiguration> ()) as DotNetProjectConfiguration;
+ if (defaultConf != null) {
+ var drc = (AssemblyRunConfiguration)config;
+ var cmd = defaultConf.CustomCommands.FirstOrDefault (cc => cc.Type == CustomCommandType.Execute);
+ if (cmd != null) {
+ drc.StartAction = AssemblyRunConfiguration.StartActions.Program;
+ drc.StartProgram = cmd.GetCommandFile (this, defaultConf.Selector);
+ drc.StartArguments = cmd.GetCommandArgs (this, defaultConf.Selector);
+ foreach (var v in cmd.EnvironmentVariables)
+ drc.EnvironmentVariables.Add (v.Key, v.Value);
+ drc.StartWorkingDirectory = cmd.GetCommandWorkingDir (this, defaultConf.Selector);
+ drc.ExternalConsole = cmd.ExternalConsole;
+ drc.PauseConsoleOutput = cmd.PauseExternalConsole;
+ defaultConf.CustomCommands.Remove (cmd);
+ }
+ }
+ }
+ }
+
protected override void OnWriteProjectHeader (ProgressMonitor monitor, MSBuildProject msproject)
{
base.OnWriteProjectHeader (monitor, msproject);
@@ -1652,10 +1774,17 @@ namespace MonoDevelop.Projects
return Project.OnGetReferencedAssemblyProjects (configuration);
}
+#pragma warning disable 672 // Member overrides obsolete member
internal protected override ExecutionCommand OnCreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration)
{
return Project.OnCreateExecutionCommand (configSel, configuration);
}
+#pragma warning restore 672 // Member overrides obsolete member
+
+ internal protected override ExecutionCommand OnCreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration, ProjectRunConfiguration runConfiguration)
+ {
+ return Project.OnCreateExecutionCommand (configSel, configuration, runConfiguration);
+ }
internal protected override void OnReferenceRemovedFromProject (ProjectReferenceEventArgs e)
{
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectExtension.cs
index 51e5a24b4f..bdbf68ccef 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectExtension.cs
@@ -82,11 +82,17 @@ namespace MonoDevelop.Projects
return next.OnGetReferencedAssemblyProjects (configuration);
}
+ [Obsolete("User overload that takes a RunConfiguration")]
internal protected virtual ExecutionCommand OnCreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration)
{
return next.OnCreateExecutionCommand (configSel, configuration);
}
+ internal protected virtual ExecutionCommand OnCreateExecutionCommand (ConfigurationSelector configSel, DotNetProjectConfiguration configuration, ProjectRunConfiguration runConfiguration)
+ {
+ return next.OnCreateExecutionCommand (configSel, configuration, runConfiguration);
+ }
+
internal protected virtual void OnReferenceRemovedFromProject (ProjectReferenceEventArgs e)
{
next.OnReferenceRemovedFromProject (e);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/EnvironmentVariableCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/EnvironmentVariableCollection.cs
new file mode 100644
index 0000000000..63f0fcd6a4
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/EnvironmentVariableCollection.cs
@@ -0,0 +1,189 @@
+//
+// EnvironmentVariableCollection.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using MonoDevelop.Core.Serialization;
+using System.Linq;
+using System.Collections.Generic;
+using System.Collections;
+
+namespace MonoDevelop.Projects
+{
+ public class EnvironmentVariableCollection: ICustomDataItem, IDictionary<string,string>
+ {
+ List<KeyValuePair<string, string>> dict;
+
+ public EnvironmentVariableCollection ()
+ {
+ dict = new List<KeyValuePair<string, string>> ();
+ }
+
+ public EnvironmentVariableCollection (IDictionary<string,string> dictionary)
+ {
+ dict = dictionary.ToList ();
+ }
+
+ void ICustomDataItem.Deserialize (ITypeSerializer handler, DataCollection data)
+ {
+ foreach (var v in data.OfType<DataItem> ()) {
+ var name = v.ItemData ["name"] as DataValue;
+ var value = v.ItemData ["value"] as DataValue;
+ if (name != null && value != null)
+ this [name.Value] = value.Value;
+ }
+ }
+
+ DataCollection ICustomDataItem.Serialize (ITypeSerializer handler)
+ {
+ // Add known keys first, then new keys
+ var col = new DataCollection ();
+ foreach (var ev in dict) {
+ var vi = new DataItem ();
+ vi.Name = "Variable";
+ vi.ItemData.Add (new DataValue ("name", ev.Key) { StoreAsAttribute = true });
+ vi.ItemData.Add (new DataValue ("value", ev.Value) { StoreAsAttribute = true });
+ col.Add (vi);
+ }
+ return col;
+ }
+
+ public string this [string key] {
+ get {
+ for (int n = 0; n < dict.Count; n++)
+ if (dict [n].Key == key)
+ return dict [n].Value;
+ throw new KeyNotFoundException ();
+ }
+ set {
+ for (int n = 0; n < dict.Count; n++) {
+ if (dict [n].Key == key) {
+ dict [n] = new KeyValuePair<string, string> (key, value);
+ return;
+ }
+ }
+ dict.Add (new KeyValuePair<string, string> (key, value));
+ }
+ }
+
+ public int Count {
+ get {
+ return dict.Count;
+ }
+ }
+
+ bool ICollection<KeyValuePair<string, string>>.IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public ICollection<string> Keys {
+ get {
+ return dict.Select (ev => ev.Key).ToList ();
+ }
+ }
+
+ public ICollection<string> Values {
+ get {
+ return dict.Select (ev => ev.Value).ToList ();
+ }
+ }
+
+ void ICollection<KeyValuePair<string, string>>.Add (KeyValuePair<string, string> item)
+ {
+ dict.Add (item);
+ }
+
+ public void Add (string key, string value)
+ {
+ dict.Add (new KeyValuePair<string, string> (key, value));
+ }
+
+ public void Clear ()
+ {
+ dict.Clear ();
+ }
+
+ bool ICollection<KeyValuePair<string, string>>.Contains (KeyValuePair<string, string> item)
+ {
+ return dict.Any (ev => ev.Key == item.Key && ev.Value == item.Value);
+ }
+
+ public bool ContainsKey (string key)
+ {
+ return FindKey (key) != -1;
+ }
+
+ void ICollection<KeyValuePair<string, string>>.CopyTo (KeyValuePair<string, string> [] array, int arrayIndex)
+ {
+ ((ICollection<KeyValuePair<string, string>>)dict).CopyTo (array, arrayIndex);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return ((IEnumerable)dict).GetEnumerator ();
+ }
+
+ IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator ()
+ {
+ return ((IEnumerable<KeyValuePair<string, string>>)dict).GetEnumerator ();
+ }
+
+ bool ICollection<KeyValuePair<string, string>>.Remove (KeyValuePair<string, string> item)
+ {
+ return dict.RemoveAll (ev => ev.Key == item.Key && ev.Value == item.Value) > 0;
+ }
+
+ public bool Remove (string key)
+ {
+ var i = FindKey (key);
+ if (i != -1) {
+ dict.RemoveAt (i);
+ return true;
+ }
+ return false;
+ }
+
+ bool IDictionary<string, string>.TryGetValue (string key, out string value)
+ {
+ var i = FindKey (key);
+ if (i != -1) {
+ value = dict [i].Value;
+ return true;
+ }
+ value = null;
+ return false;
+ }
+
+ int FindKey (string key)
+ {
+ for (int n = 0; n < dict.Count; n++)
+ if (dict [n].Key == key)
+ return n;
+ return -1;
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExecutionContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExecutionContext.cs
index ae1334fe5f..1ec0889b12 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExecutionContext.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExecutionContext.cs
@@ -69,5 +69,7 @@ namespace MonoDevelop.Projects
public ExternalConsoleFactory ExternalConsoleFactory {
get { return MonoDevelop.Core.Execution.ExternalConsoleFactory.Instance; }
}
+
+ internal object RunConfiguration { get; set; }
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/IRunTarget.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/IRunTarget.cs
new file mode 100644
index 0000000000..d2e0172dd5
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/IRunTarget.cs
@@ -0,0 +1,83 @@
+//
+// IRunTarget.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System.Collections.Generic;
+using MonoDevelop.Core;
+using System.Threading.Tasks;
+using System;
+using MonoDevelop.Core.Execution;
+
+namespace MonoDevelop.Projects
+{
+ public interface IRunTarget
+ {
+ /// <summary>
+ /// Executes the target
+ /// </summary>
+ /// <param name="monitor">Monitor for tracking progress</param>
+ /// <param name="context">Execution context</param>
+ /// <param name="configuration">Configuration to execute</param>
+ /// <param name="runConfiguration">Run configuration to use</param>
+ Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration);
+
+ /// <summary>
+ /// Determines whether this target can be executed using the specified execution context and configuration.
+ /// </summary>
+ /// <returns><c>true</c> if this instance can be executed; otherwise, <c>false</c>.</returns>
+ /// <param name="context">An execution context</param>
+ /// <param name="configuration">Configuration to execute</param>
+ /// <param name="runConfiguration">Run configuration to use</param>
+ bool CanExecute (ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration);
+
+ /// <summary>
+ /// Prepares the target for execution
+ /// </summary>
+ /// <returns>The execution.</returns>
+ /// <param name="monitor">Monitor for tracking progress</param>
+ /// <param name="context">Execution context</param>
+ /// <param name="configuration">Configuration to execute</param>
+ /// <param name="runConfiguration">Run configuration to use</param>
+ /// <remarks>This method can be called (it is not mandatory) before Execute() to give the target a chance
+ /// to asynchronously prepare the execution that is going to be done later on. It can be used for example
+ /// to start the simulator that is going to be used for execution. Calling this method is optional, and
+ /// there is no guarantee that Execute() will actually be called.</remarks>
+ Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration);
+
+ /// <summary>
+ /// Gets the run configurations that can be used to execute this item
+ /// </summary>
+ /// <returns>The run configurations.</returns>
+ IEnumerable<RunConfiguration> GetRunConfigurations ();
+
+ /// <summary>
+ /// Gets the execution targets available for this item
+ /// </summary>
+ /// <returns>The execution targets.</returns>
+ /// <param name="configuration">Configuration to execute</param>
+ /// <param name="runConfiguration">Run configuration to use</param>
+ IEnumerable<ExecutionTarget> GetExecutionTargets (ConfigurationSelector configuration, RunConfiguration runConfiguration);
+ }
+}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs
new file mode 100644
index 0000000000..321d694c14
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MonoExecutionParameters.cs
@@ -0,0 +1,560 @@
+//
+// AdvancedMonoParameters.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@novell.com>
+//
+// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.ComponentModel;
+using MonoDevelop.Core;
+using MonoDevelop.Core.Serialization;
+using System.Text;
+
+
+namespace MonoDevelop.Projects
+{
+ public sealed class MonoExecutionParameters
+ {
+ class EnvVarAttribute : Attribute
+ {
+ public string Name;
+ public string TrueValue = string.Empty;
+
+ public EnvVarAttribute (string name)
+ {
+ this.Name = name;
+ }
+
+ public EnvVarAttribute (string name, string trueValue)
+ {
+ this.Name = name;
+ this.TrueValue = trueValue;
+ }
+ }
+
+ class MonoArgAttribute : Attribute
+ {
+ public string Name;
+
+ public MonoArgAttribute (string name)
+ {
+ Name = name;
+ }
+ }
+
+ public enum LogLevel
+ {
+ [MonoArg (null)]
+ [LocalizedDescription ("Default")]
+ Default,
+ [MonoArg ("error")]
+ Error,
+ [MonoArg ("critical")]
+ Critical,
+ [MonoArg ("warning")]
+ Warning,
+ [MonoArg ("message")]
+ Message,
+ [MonoArg ("info")]
+ Info,
+ [MonoArg ("debug")]
+ Debug
+ }
+
+ [Flags]
+ public enum LogMask
+ {
+ [MonoArg (null)]
+ None = 0,
+ [MonoArg ("asm")]
+ AssemblyLoader = 0x01,
+ [MonoArg ("type")]
+ Type = 0x02,
+ [MonoArg ("dll")]
+ NativeLibraryLoader = 0x04,
+ [MonoArg ("cfg")]
+ ConfigFileLoader = 0x08,
+ [MonoArg ("gc")]
+ GarbageCollector = 0x10,
+ [MonoArg ("aot")]
+ Aot = 0x20,
+ [MonoArg ("all")]
+ All = 0xff
+ }
+
+ public enum SecurityMode
+ {
+ [MonoArg (null)]
+ [LocalizedDescription ("Disabled")]
+ Disabled,
+ [MonoArg ("cas")]
+ Cas,
+ [MonoArg ("core-clr")]
+ CoreClr,
+ [MonoArg ("verifiable")]
+ Verifiable,
+ [MonoArg ("validil")]
+ ValidIL
+ }
+
+ public enum GcType
+ {
+ [MonoArg (null)]
+ [LocalizedDescription ("Default")]
+ Default,
+ [MonoArg ("boehm")]
+ Boehm,
+ [MonoArg ("sgen")]
+ SGen
+ }
+
+ public MonoExecutionParameters ()
+ {
+ foreach (PropertyInfo prop in GetType ().GetProperties ()) {
+ ItemPropertyAttribute propAttr = (ItemPropertyAttribute) Attribute.GetCustomAttribute (prop, typeof(ItemPropertyAttribute));
+ if (propAttr != null) {
+ if (propAttr.DefaultValue != null)
+ prop.SetValue (this, propAttr.DefaultValue, null);
+ }
+ }
+ }
+
+ public void GenerateOptions (IDictionary<string,string> envVars, out string options)
+ {
+ StringBuilder ops = new StringBuilder ();
+ if (MonoStripDriveLetters || MonoCaseInsensitivePaths) {
+ if (MonoStripDriveLetters && MonoCaseInsensitivePaths)
+ envVars ["MONO_IOMAP"] = "all";
+ else if (MonoStripDriveLetters)
+ envVars ["MONO_IOMAP"] = "drive";
+ else if (MonoCaseInsensitivePaths)
+ envVars ["MONO_IOMAP"] = "case";
+ }
+ for (int n=0; n< MonoVerboseLevel; n++)
+ ops.Append ("-v ");
+
+ if (MonoDebugMode || MonoDebugMdbOptimizations || MonoDebugCasts || MonoGdbInfo) {
+ ops.Append ("--debug=");
+ if (MonoDebugMdbOptimizations)
+ ops.Append ("mdb-optimizations,");
+ if (MonoDebugCasts)
+ ops.Append ("casts,");
+ if (MonoGdbInfo)
+ ops.Append ("gdb,");
+ ops.Remove (ops.Length - 1, 1);
+ ops.Append (' ');
+ }
+
+ foreach (PropertyInfo prop in GetType ().GetProperties ()) {
+ MonoArgAttribute argAttr = (MonoArgAttribute) Attribute.GetCustomAttribute (prop, typeof(MonoArgAttribute));
+ if (argAttr != null) {
+ object val = GetValue (prop.GetValue (this, null));
+ if ((val is bool) && (bool)val)
+ ops.Append (argAttr.Name).Append (' ');
+ else if ((val is string) && !string.IsNullOrEmpty ((string)val))
+ ops.AppendFormat (argAttr.Name, val).Append (' ');
+ } else {
+ EnvVarAttribute envVar = (EnvVarAttribute) Attribute.GetCustomAttribute (prop, typeof(EnvVarAttribute));
+ if (envVar != null) {
+ object val = GetValue (prop.GetValue (this, null));
+ if ((val is bool) && (bool)val)
+ envVars [envVar.Name] = envVar.TrueValue;
+ else if ((val is string) && !string.IsNullOrEmpty ((string)val))
+ envVars [envVar.Name] = val.ToString ();
+ }
+ }
+ }
+ options = ops.ToString ().Trim ();
+ }
+
+ object GetValue (object val)
+ {
+ if (val.GetType ().IsEnum) {
+ long ival = Convert.ToInt64 (val);
+ Type etype = val.GetType ();
+ bool isFlags = val.GetType ().IsDefined (typeof(FlagsAttribute), false);
+ string flags = "";
+ IList names = Enum.GetNames (etype);
+ foreach (FieldInfo f in val.GetType ().GetFields ()) {
+ if (!names.Contains (f.Name))
+ continue;
+ long v = Convert.ToInt64 (Enum.Parse (val.GetType(), f.Name));
+ MonoArgAttribute attr = (MonoArgAttribute) Attribute.GetCustomAttribute (f, typeof(MonoArgAttribute));
+ string sval = attr != null ? attr.Name : f.Name;
+ if (ival == v) {
+ return sval;
+ }
+ else if (isFlags && (v & ival) != 0) {
+ if (flags.Length > 0)
+ flags += ",";
+ flags += sval;
+ }
+ }
+ if (isFlags)
+ return flags;
+ }
+ return val;
+ }
+
+ public string GenerateDescription ()
+ {
+ StringBuilder ops = new StringBuilder ();
+
+ foreach (PropertyInfo prop in GetType ().GetProperties ()) {
+ ItemPropertyAttribute propAttr = (ItemPropertyAttribute)Attribute.GetCustomAttribute (prop, typeof (ItemPropertyAttribute));
+ var pval = prop.GetValue (this, null);
+ if (object.Equals (pval, propAttr.DefaultValue))
+ continue;
+ if (ops.Length > 0)
+ ops.Append (", ");
+ var nameAttr = (LocalizedDisplayNameAttribute)Attribute.GetCustomAttribute (prop, typeof (LocalizedDisplayNameAttribute));
+ ops.Append (nameAttr.DisplayName);
+ if (!(pval is bool))
+ ops.Append (": " + GetValue (pval));
+ }
+ return ops.ToString ();
+ }
+ public MonoExecutionParameters Clone ()
+ {
+ return (MonoExecutionParameters) MemberwiseClone ();
+ }
+
+ [LocalizedCategory ("Debug")]
+ [LocalizedDisplayName ("Debug Mode")]
+ [LocalizedDescription ("Enable debugging support.")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoDebugMode { get; set; }
+
+ [LocalizedCategory ("Debug")]
+ [LocalizedDisplayName ("Debug Casts")]
+ [LocalizedDescription ("Enable more detailed InvalidCastException messages.")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoDebugCasts { get; set; }
+
+ [LocalizedCategory ("Debug")]
+ [LocalizedDisplayName ("MDB Mode")]
+ [LocalizedDescription ("Disable some JIT optimizations which are normally " +
+ "disabled when running inside the debugger. This is useful " +
+ "if you plan to attach to the running process with the debugger.")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoDebugMdbOptimizations { get; set; }
+
+ [LocalizedCategory ("Debug")]
+ [LocalizedDisplayName ("GDB Symbols")]
+ [LocalizedDescription ("Generate and register debugging information with gdb. " +
+ "This is only supported on some platforms, and only when " +
+ "using gdb 7.0 or later.")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoGdbInfo { get; set; }
+
+ [LocalizedCategory ("Runtime")]
+ [LocalizedDisplayName ("Profiler")]
+ [LocalizedDescription ("Runs in profiling mode with the specified profiler module.")]
+ [ItemProperty (DefaultValue="")]
+ [MonoArg ("--profile={0}")]
+ public string MonoProfile { get; set; }
+
+ [LocalizedCategory ("Debug")]
+ [LocalizedDisplayName ("Verbose Level")]
+ [LocalizedDescription ("Increases the verbosity level.")]
+ [ItemProperty (DefaultValue=0)]
+ public int MonoVerboseLevel { get; set; }
+
+ [LocalizedCategory ("Runtime")]
+ [LocalizedDisplayName ("Runtime Version")]
+ [LocalizedDescription ("Use the specified runtime version, instead of autodetecting")]
+ [ItemProperty (DefaultValue="")]
+ [MonoArg ("--runtime={0}")]
+ public string MonoRuntimeVersion { get; set; }
+
+ [LocalizedCategory ("Security")]
+ [LocalizedDisplayName ("Security Mode")]
+ [LocalizedDescription ("Turns on the unsupported security manager (off by default).")]
+ [MonoArg ("--security={0}")]
+ [ItemProperty (DefaultValue=SecurityMode.Disabled)]
+ public SecurityMode MonoSecurityMode { get; set; }
+
+ [LocalizedCategory ("Security")]
+ [LocalizedDisplayName ("Verify All")]
+ [LocalizedDescription ("Verifies mscorlib and assemblies in the global assembly cache " +
+ "for valid IL, and all user code for IL verifiability.")]
+ [MonoArg ("--verifyAll")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoVerifyAll { get; set; }
+
+ [LocalizedCategory ("Tracing")]
+ [LocalizedDisplayName ("Trace Expression")]
+ [LocalizedDescription ("Comma separated list of expressions to trace. " +
+ "'all' all assemlies, " +
+ "'none' no assemblies, " +
+ "'program' entry point assembly, " +
+ "'assembly' specifies an assembly, " +
+ "'T:Type' specifies a type, " +
+ "'M:Type:Method' a method, " +
+ "'N:Namespace' a namespace. " +
+ "'disabled' don't print any output until toggled via SIGUSR2. " +
+ "Prefix with '-' to exclude and expression.")]
+ [MonoArg ("--trace={0}")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoTraceExpressions { get; set; }
+
+ [LocalizedCategory ("Logging")]
+ [LocalizedDisplayName ("Log Level")]
+ [LocalizedDescription ("Possible values are 'error', 'critical', 'warning', " +
+ "'message', 'info', 'debug'. The default value is 'error'. " +
+ "Messages with a logging level greater then or equal to the log level " +
+ "will be printed to stdout/stderr.")]
+ [EnvVar ("MONO_LOG_LEVEL")]
+ [ItemProperty (DefaultValue=LogLevel.Default)]
+ public LogLevel MonoLogLevel { get; set; }
+
+ [LocalizedCategory ("Logging")]
+ [LocalizedDisplayName ("Log Mask")]
+ [LocalizedDescription ("Possible values are 'asm' (assembly loader), 'type'," +
+ " 'dll' (native library loader), 'gc' (garbage collector), " +
+ "'cfg' (config file loader), 'aot' (precompiler) and 'all'. " +
+ "The default value is 'all'. Changing the mask value allows you " +
+ "to display only messages for a certain component. You can use " +
+ "multiple masks by comma separating them. For example to see " +
+ "config file messages and assembly loader messages set you mask " +
+ "to 'asm,cfg'.")]
+ [EnvVar ("MONO_LOG_MASK")]
+ [ItemProperty (DefaultValue=LogMask.None)]
+ public LogMask MonoLogMask { get; set; }
+
+ [LocalizedCategory ("Library Options")]
+ [LocalizedDisplayName ("Serializer Generation")]
+ [LocalizedDescription ("The possible values are `no' to disable the use of a C# customized " +
+ "serializer, or an integer that is the minimum number of uses before the " +
+ "runtime will produce a custom serializer (0 will produce a custom " +
+ "serializer on the first access, 50 will produce a serializer on the 50th " +
+ "use). Mono will fallback to an interpreted serializer if the serializer " +
+ "generation somehow fails. This behavior can be disabled by setting the " +
+ "option `nofallback' (for example: '0,nofallback').")]
+ [EnvVar ("MONO_XMLSERIALIZER_THS")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoXmlSerializerGeneration { get; set; }
+
+ [LocalizedCategory ("Configuration")]
+ [LocalizedDisplayName ("Mono Configuration Directory")]
+ [LocalizedDescription ("Overrides the default system configuration directory ($PREFIX/etc). " +
+ "It's used to locate machine.config file.")]
+ [EnvVar ("MONO_CFG_DIR")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoConfigDir { get; set; }
+
+ [LocalizedCategory ("Configuration")]
+ [LocalizedDisplayName ("Mono Configuration File")]
+ [LocalizedDescription ("Overrides the default runtime configuration file ($PREFIX/etc/mono/config).")]
+ [MonoArg ("--config {0}")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoConfigFile { get; set; }
+
+ [LocalizedCategory ("Runtime")]
+ [LocalizedDisplayName ("Disable AIO")]
+ [LocalizedDescription ("If set, tells mono NOT to attempt using native asynchronous I/O " +
+ "services. In that case, a default select/poll implementation is " +
+ "used. Currently only epoll() is supported.")]
+ [EnvVar ("MONO_DISABLE_AIO")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoDisableAIO { get; set; }
+
+ [LocalizedCategory ("Library Options")]
+ [LocalizedDisplayName ("Disable Managed Collation")]
+ [LocalizedDescription ("If set, the runtime uses unmanaged collation (which actually " +
+ "means no culture-sensitive collation). It internally disables " +
+ "managed collation functionality invoked via the members of " +
+ "System.Globalization.CompareInfo class.")]
+ [EnvVar ("MONO_DISABLE_MANAGED_COLLATION", "yes")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoDisableManagedCollation { get; set; }
+
+ [LocalizedCategory ("Library Options")]
+ [LocalizedDisplayName ("External Encodings")]
+ [LocalizedDescription ("A colon-separated list of text encodings to try when turning " +
+ "externally-generated text (e.g. command-line arguments or " +
+ "filenames) into Unicode.")]
+ [EnvVar ("MONO_EXTERNAL_ENCODINGS")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoExternalEncodings { get; set; }
+
+ [LocalizedCategory ("Configuration")]
+ [LocalizedDisplayName ("GAC Prefix")]
+ [LocalizedDescription ("Provides a prefix the runtime uses to look for Global Assembly " +
+ "Caches. Directories are separated by the platform path separator " +
+ "(colons on unix). MONO_GAC_PREFIX should point to the top " +
+ "directory of a prefixed install. Or to the directory provided in " +
+ "the gacutil /gacdir command. Example: /home/username/.mono:/usr/local/mono/")]
+ [EnvVar ("MONO_GAC_PREFIX")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoGacPrefix { get; set; }
+
+ [LocalizedCategory ("Compatibility")]
+ [LocalizedDisplayName ("Strip Drive Letters")]
+ [LocalizedDescription ("When enabled, Mono removes the drive letter from Windows paths.")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoStripDriveLetters { get; set; }
+
+ [LocalizedCategory ("Compatibility")]
+ [LocalizedDisplayName ("Case Insensitive Paths")]
+ [LocalizedDescription ("When enabled, Mono does case-insensitive file matching in every directory in a path.")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoCaseInsensitivePaths { get; set; }
+
+ [LocalizedCategory ("Library Options")]
+ [LocalizedDisplayName ("Managed Watcher")]
+ [LocalizedDescription ("When set, System.IO.FileSystemWatcher will use the default managed " +
+ "implementation (slow).")]
+ [EnvVar ("MONO_MANAGED_WATCHER", "yes")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoManagedWatcher { get; set; }
+
+ [LocalizedCategory ("Runtime")]
+ [LocalizedDisplayName ("No SMP")]
+ [LocalizedDescription ("If set, causes the mono process to be bound to a single processor. " +
+ "This may be useful when debugging or working around race conditions.")]
+ [EnvVar ("MONO_NO_SMP")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoNoSmp { get; set; }
+
+ [LocalizedCategory ("Configuration")]
+ [LocalizedDisplayName ("Mono Path")]
+ [LocalizedDescription ("Provides a search path to the runtime where to look for library " +
+ "files. This is a tool convenient for debugging applications, " +
+ "but should not be used by deployed applications as it breaks the " +
+ "assembly loader in subtle ways. Directories are separated by " +
+ "the platform path separator (colons on unix). Example: " +
+ "/home/username/lib:/usr/local/mono/lib")]
+ [EnvVar ("MONO_PATH")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoPath { get; set; }
+
+ [LocalizedCategory ("Library Options")]
+ [LocalizedDisplayName ("Windows Forms Theme")]
+ [LocalizedDescription ("The name of the theme to be used by Windows.Forms. Available " +
+ "themes include 'clearlooks', 'nice' and 'win32'. The default is 'win32'")]
+ [EnvVar ("MONO_THEME")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoWindowsFormsTheme { get; set; }
+
+ [LocalizedCategory ("Runtime")]
+ [LocalizedDisplayName ("Threads Per Cpu")]
+ [LocalizedDescription ("The maximum number of threads in the general threadpool will be " +
+ "20 + (ThreadsPerCpu * number of CPUs). The default value" +
+ "for this variable is 10.")]
+ [EnvVar ("MONO_THREADS_PER_CPU")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoThreadsPerCpu { get; set; }
+
+ [LocalizedCategory ("Library Options")]
+ [LocalizedDisplayName ("Keep ASP.NET Temporary Files")]
+ [LocalizedDescription ("If set, temporary source files generated by ASP.NET support " +
+ "classes will not be removed. They will be kept in the " +
+ "user's temporary directory.")]
+ [EnvVar ("MONO_ASPNET_NODELETE")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoAspNetNoDelete { get; set; }
+
+ [LocalizedCategory ("Tracing")]
+ [LocalizedDisplayName ("Trace Listener")]
+ [LocalizedDescription ("If set, enables the System.Diagnostics.DefaultTraceListener, " +
+ "which will print the output of the System.Diagnostics Trace and " +
+ "Debug classes. It can be set to a filename, and to Console.Out " +
+ "or Console.Error to display output to standard output or standard " +
+ "error, respectively. If it's set to Console.Out or Console.Error " +
+ "you can append an optional prefix that will be used when writing " +
+ "messages like this: Console.Error:MyProgramName.")]
+ [EnvVar ("MONO_TRACE_LISTENER")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoTraceListener { get; set; }
+
+ [LocalizedCategory ("Runtime")]
+ [LocalizedDisplayName ("X11 Exceptions")]
+ [LocalizedDescription ("If set, an exception is thrown when a X11 error is encountered. " +
+ "By default a message is displayed but execution continues.")]
+ [EnvVar ("MONO_XEXCEPTIONS")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoXExceptions { get; set; }
+
+ [LocalizedCategory ("Debug")]
+ [LocalizedDisplayName ("XDebug")]
+ [LocalizedDescription ("When the the MONO_XDEBUG env var is set, debugging info for JITted " +
+ "code is emitted into a shared library, loadable into gdb. " +
+ "This enables, for example, to see managed frame names on gdb backtraces.")]
+ [EnvVar ("MONO_XDEBUG")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoXDebug { get; set; }
+
+ [LocalizedCategory ("Runtime")]
+ [LocalizedDisplayName ("Garbage Collector")]
+ [LocalizedDescription ("Selects the Garbage Collector engine for Mono to use.")]
+ [MonoArg ("--gc={0}")]
+ [ItemProperty (DefaultValue=GcType.Default)]
+ public GcType MonoGcType { get; set; }
+
+ [LocalizedCategory ("LLVM")]
+ [LocalizedDisplayName ("Enable LLVM")]
+ [LocalizedDescription ("If the Mono runtime has been compiled with LLVM support (not " +
+ "available in all configurations), this option enables use the LLVM optimization " +
+ "and code generation engine to JIT or AOT compile. For more information " +
+ "consult: http://www.mono-project.com/Mono_LLVM")]
+ [MonoArg ("--llvm")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoLlvm { get; set; }
+
+ [LocalizedCategory ("LLVM")]
+ [LocalizedDisplayName ("Disable LLVM")]
+ [LocalizedDescription ("When using a Mono that has been compiled with LLVM support, it " +
+ "forces Mono to fallback to its JIT engine and not use the LLVM backend")]
+ [MonoArg ("--nollvm")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoNoLlvm { get; set; }
+
+ [LocalizedCategory ("Optimizations")]
+ [LocalizedDisplayName ("Desktop Mode")]
+ [LocalizedDescription ("Configures the virtual machine to be better suited for desktop " +
+ "applications. Currently this sets the GC system to avoid " +
+ "expanding the heap as much as possible at the expense of slowing " +
+ "down garbage collection a bit.")]
+ [MonoArg ("--desktop")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoDesktopMode { get; set; }
+
+ [LocalizedCategory ("Optimizations")]
+ [LocalizedDisplayName ("Server Mode")]
+ [LocalizedDescription ("Configures the virtual machine to be better suited for server operations.")]
+ [MonoArg ("--server")]
+ [ItemProperty (DefaultValue=false)]
+ public bool MonoServerMode { get; set; }
+
+ [LocalizedCategory ("Additional Options")]
+ [LocalizedDisplayName ("Additional Options")]
+ [LocalizedDescription ("Additional command line options to be provided to the Mono command.")]
+ [MonoArg ("{0}")]
+ [ItemProperty (DefaultValue="")]
+ public string MonoAdditionalOptions { get; set; }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/CustomRuntimeExecutionModeSet.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MultiItemSolutionRunConfiguration.cs
index 830bd492b3..99b88483df 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/CustomRuntimeExecutionModeSet.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MultiItemSolutionRunConfiguration.cs
@@ -1,21 +1,21 @@
-//
-// CustomRuntimeExecutionModeSet.cs
-//
+//
+// MultiItemSolutionRunConfiguration.cs
+//
// Author:
-// Lluis Sanchez Gual <lluis@novell.com>
-//
-// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
-//
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -23,30 +23,19 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-
using System;
using System.Collections.Generic;
-using MonoDevelop.Core.Execution;
-using MonoDevelop.Core.Assemblies;
-namespace MonoDevelop.Core.Assemblies
+namespace MonoDevelop.Projects
{
- public class CustomRuntimeExecutionModeSet: IExecutionModeSet
+ class MultiItemSolutionRunConfiguration: SolutionRunConfiguration
{
- #region IExecutionModeSet implementation
- public string Name {
- get {
- return "Custom Runtime";
- }
- }
-
- public IEnumerable<IExecutionMode> ExecutionModes {
- get {
- foreach (TargetRuntime tr in Runtime.SystemAssemblyService.GetTargetRuntimes ()) {
- yield return new ExecutionMode (tr.Id, tr.DisplayName, tr.GetExecutionHandler ());
- }
- }
+ public MultiItemSolutionRunConfiguration (string id, string name): base (id, name)
+ {
+ Items = new List<SolutionItem> ();
}
- #endregion
+
+ public List<SolutionItem> Items { get; set; }
}
}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProcessRunConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProcessRunConfiguration.cs
new file mode 100644
index 0000000000..70967baf7d
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProcessRunConfiguration.cs
@@ -0,0 +1,88 @@
+//
+// ProcessRunConfiguration.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Linq;
+using MonoDevelop.Core;
+using MonoDevelop.Core.Serialization;
+
+namespace MonoDevelop.Projects
+{
+ public class ProcessRunConfiguration: ProjectRunConfiguration
+ {
+ public ProcessRunConfiguration (string name): base (name)
+ {
+ }
+
+ [ItemProperty (DefaultValue = "")]
+ public string StartArguments { get; set; } = "";
+
+ [ItemProperty (DefaultValue = "")]
+ public FilePath StartWorkingDirectory { get; set; } = "";
+
+ [ItemProperty ("ConsolePause", DefaultValue = true)]
+ public bool PauseConsoleOutput { get; set; } = true;
+
+ [ItemProperty (DefaultValue = false)]
+ public bool ExternalConsole { get; set; } = false;
+
+ [ItemProperty (SkipEmpty = true, WrapObject = false)]
+ public EnvironmentVariableCollection EnvironmentVariables { get; private set; } = new EnvironmentVariableCollection ();
+
+ public override string Summary {
+ get {
+ string envVars = null;
+ if (EnvironmentVariables.Count > 0) {
+ var v = EnvironmentVariables.First ();
+ envVars = v.Key + "=" + v.Value;
+ if (EnvironmentVariables.Count > 1)
+ envVars += "...";
+ }
+ if (!string.IsNullOrEmpty (StartArguments) && envVars != null)
+ return GettextCatalog.GetString ("Run with arguments '{0}' and environment variables '{1}'", StartArguments, envVars);
+ else if (!string.IsNullOrEmpty (StartArguments))
+ return GettextCatalog.GetString ("Run with arguments '{0}'", StartArguments);
+ else if (envVars != null)
+ return GettextCatalog.GetString ("Run with environment variables '{0}''", envVars);
+ else
+ return GettextCatalog.GetString ("Run with no additional arguments");
+ }
+ }
+
+ protected override void OnCopyFrom (ProjectRunConfiguration config, bool isRename)
+ {
+ base.OnCopyFrom (config, isRename);
+
+ var other = (ProcessRunConfiguration)config;
+
+ StartArguments = other.StartArguments;
+ StartWorkingDirectory = other.StartWorkingDirectory;
+ EnvironmentVariables = new EnvironmentVariableCollection (other.EnvironmentVariables);
+ ExternalConsole = other.ExternalConsole;
+ PauseConsoleOutput = other.PauseConsoleOutput;
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
index 662a47f01f..b42f62272f 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
@@ -61,12 +61,15 @@ namespace MonoDevelop.Projects
string[] buildActions;
MSBuildProject sourceProject;
+ MSBuildProject userProject;
string productVersion;
string schemaVersion;
bool modifiedInMemory;
bool msbuildUpdatePending;
ProjectExtension projectExtension;
+ RunConfigurationCollection runConfigurations;
+ bool defaultRunConfigurationCreated;
List<string> defaultImports;
@@ -76,6 +79,7 @@ namespace MonoDevelop.Projects
protected Project ()
{
+ runConfigurations = new RunConfigurationCollection (this);
items = new ProjectItemCollection (this);
FileService.FileChanged += HandleFileChanged;
Runtime.SystemAssemblyService.DefaultRuntimeChanged += OnDefaultRuntimeChanged;
@@ -88,6 +92,13 @@ namespace MonoDevelop.Projects
get { return items; }
}
+ public RunConfigurationCollection RunConfigurations {
+ get {
+ CreateDefaultConfiguration ();
+ return runConfigurations;
+ }
+ }
+
protected Project (params string[] flavorGuids): this()
{
this.flavorGuids = flavorGuids;
@@ -289,6 +300,75 @@ namespace MonoDevelop.Projects
base.OnConfigurationRemoved (args);
}
+ protected override void OnItemReady ()
+ {
+ base.OnItemReady ();
+ }
+
+ internal virtual void ImportDefaultRunConfiguration (ProjectRunConfiguration config)
+ {
+ }
+
+ public ProjectRunConfiguration CreateRunConfiguration (string name)
+ {
+ var c = CreateRunConfigurationInternal (name);
+
+ // When creating a ProcessRunConfiguration, set the value of ExternalConsole and PauseConsoleOutput from the default configuration
+ var pc = c as ProcessRunConfiguration;
+ if (pc != null) {
+ var dc = RunConfigurations.FirstOrDefault (rc => rc.IsDefaultConfiguration) as ProcessRunConfiguration;
+ if (dc != null) {
+ pc.ExternalConsole = dc.ExternalConsole;
+ pc.PauseConsoleOutput = dc.PauseConsoleOutput;
+ }
+ }
+ return c;
+ }
+
+ ProjectRunConfiguration CreateRunConfigurationInternal (string name)
+ {
+ var c = CreateUninitializedRunConfiguration (name);
+ c.Initialize (this);
+ return c;
+ }
+
+ public ProjectRunConfiguration CreateUninitializedRunConfiguration (string name)
+ {
+ return ProjectExtension.OnCreateRunConfiguration (name);
+ }
+
+ public ProjectRunConfiguration CloneRunConfiguration (ProjectRunConfiguration runConfig)
+ {
+ var clone = CreateUninitializedRunConfiguration (runConfig.Name);
+ clone.CopyFrom (runConfig, false);
+ return clone;
+ }
+
+ public ProjectRunConfiguration CloneRunConfiguration (ProjectRunConfiguration runConfig, string newName)
+ {
+ var clone = CreateUninitializedRunConfiguration (newName);
+ clone.CopyFrom (runConfig, true);
+ return clone;
+ }
+
+ void CreateDefaultConfiguration ()
+ {
+ // If the project doesn't have a Default run configuration, create one
+ if (!defaultRunConfigurationCreated) {
+ defaultRunConfigurationCreated = true;
+ if (!runConfigurations.Any (c => c.IsDefaultConfiguration)) {
+ var rc = CreateRunConfigurationInternal ("Default");
+ ImportDefaultRunConfiguration (rc);
+ runConfigurations.Insert (0, rc);
+ }
+ }
+ }
+
+ protected override IEnumerable<SolutionItemRunConfiguration> OnGetRunConfigurations ()
+ {
+ return RunConfigurations;
+ }
+
protected virtual void OnGetDefaultImports (List<string> imports)
{
}
@@ -531,6 +611,13 @@ namespace MonoDevelop.Projects
// Doesn't save the file to disk if the content did not change
if (await sourceProject.SaveAsync (FileName)) {
+ if (userProject != null) {
+ if (!userProject.GetAllObjects ().Any ())
+ File.Delete (userProject.FileName);
+ else
+ await userProject.SaveAsync (userProject.FileName);
+ }
+
var pb = GetCachedProjectBuilder ();
if (pb != null) {
try {
@@ -1744,7 +1831,7 @@ namespace MonoDevelop.Projects
return Task.FromResult (BuildResult.CreateSuccess ());
}
- protected override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ protected override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
ProjectConfiguration config = GetConfiguration (configuration) as ProjectConfiguration;
if (config == null)
@@ -2022,6 +2109,10 @@ namespace MonoDevelop.Projects
void ReadProject (ProgressMonitor monitor, MSBuildProject msproject)
{
+ if (File.Exists (msproject.FileName + ".user")) {
+ userProject = new MSBuildProject (msproject.EngineManager);
+ userProject.Load (msproject.FileName + ".user");
+ }
ProjectExtension.OnReadProjectHeader (monitor, msproject);
modifiedInMemory = false;
msbuildUpdatePending = false;
@@ -2068,6 +2159,8 @@ namespace MonoDevelop.Projects
InitMainGroupProperties (globalGroup);
foreach (ProjectConfiguration conf in Configurations)
InitConfiguration (conf);
+ foreach (var es in runConfigurations)
+ InitRunConfiguration ((ProjectRunConfiguration)es);
}
sourceProject.IsNewProject = false;
@@ -2080,7 +2173,7 @@ namespace MonoDevelop.Projects
class ConfigData
{
- public ConfigData (string conf, string plt, IMSBuildPropertySet grp)
+ public ConfigData (string conf, string plt, MSBuildPropertyGroup grp)
{
Config = conf;
Platform = plt;
@@ -2089,7 +2182,7 @@ namespace MonoDevelop.Projects
public string Config;
public string Platform;
- public IMSBuildPropertySet Group;
+ public MSBuildPropertyGroup Group;
public bool Exists;
public bool IsNew; // The group did not exist in the original file
}
@@ -2150,8 +2243,6 @@ namespace MonoDevelop.Projects
disableFastUpToDateCheck = msproject.EvaluatedProperties.GetValue ("DisableFastUpToDateCheck", false);
msproject.EvaluatedProperties.ReadObjectProperties (this, GetType (), true);
-
- RemoveDuplicateItems (msproject);
}
protected virtual void OnReadProject (ProgressMonitor monitor, MSBuildProject msproject)
@@ -2166,6 +2257,15 @@ namespace MonoDevelop.Projects
foreach (var cgrp in configData)
LoadConfiguration (monitor, cgrp, cgrp.Config, cgrp.Platform);
+ timer.Trace ("Read run configurations");
+
+ List<ConfigData> runConfigData = new List<ConfigData> ();
+ GetRunConfigData (runConfigData, msproject, true);
+ GetRunConfigData (runConfigData, userProject, true);
+
+ foreach (var cgrp in runConfigData)
+ LoadRunConfiguration (monitor, cgrp, cgrp.Config);
+
// Read extended properties
timer.Trace ("Read extended properties");
@@ -2319,50 +2419,110 @@ namespace MonoDevelop.Projects
config.Read (grp);
}
- void RemoveDuplicateItems (MSBuildProject msproject)
+ void GetRunConfigData (List<ConfigData> configData, MSBuildProject msproject, bool includeEvaluated)
{
-/* timer.Trace ("Checking for duplicate items");
-
- var uniqueIncludes = new Dictionary<string,object> ();
- var toRemove = new List<MSBuildItem> ();
- foreach (MSBuildItem bi in msproject.GetAllItems ()) {
- object existing;
- string key = bi.Name + "<" + bi.Include;
- if (!uniqueIncludes.TryGetValue (key, out existing)) {
- uniqueIncludes[key] = bi;
- continue;
- }
- var exBi = existing as MSBuildItem;
- if (exBi != null) {
- if (exBi.Condition != bi.Condition || exBi.Element.InnerXml != bi.Element.InnerXml) {
- uniqueIncludes[key] = new List<MSBuildItem> { exBi, bi };
- } else {
- toRemove.Add (bi);
- }
- continue;
+ if (msproject == null)
+ return;
+
+ foreach (MSBuildPropertyGroup cgrp in msproject.PropertyGroups) {
+ string configName;
+ if (ParseRunConfigurationCondition (cgrp.Condition, out configName)) {
+ // If a group for this configuration already was found, set the new group. If there are changes we want to modify the last group.
+ var existing = configData.FirstOrDefault (cd => cd.Config == configName);
+ if (existing == null)
+ configData.Add (new ConfigData (configName, null, cgrp));
+ else
+ existing.Group = cgrp;
}
+ }
+ if (includeEvaluated) {
+ var configValues = msproject.ConditionedProperties.GetAllPropertyValues ("RunConfiguration");
- var exList = (List<MSBuildItem>)existing;
- bool found = false;
- foreach (var m in (exList)) {
- if (m.Condition == bi.Condition && m.Element.InnerXml == bi.Element.InnerXml) {
- found = true;
- break;
- }
- }
- if (!found) {
- exList.Add (bi);
- } else {
- toRemove.Add (bi);
+ foreach (var c in configValues) {
+ if (!configData.Any (cd => cd.Config == c))
+ configData.Add (new ConfigData (c, "", null));
}
}
- if (toRemove.Count == 0)
- return;
+ }
+
+ bool ParseRunConfigurationCondition (string cond, out string configName)
+ {
+ configName = null;
+ int i = cond.IndexOf ("==", StringComparison.Ordinal);
+ if (i == -1)
+ return false;
+ if (cond.Substring (0, i).Trim () == "'$(RunConfiguration)'")
+ return ExtractConfigName (cond.Substring (i + 2), out configName);
+ return false;
+ }
+
+ void LoadRunConfiguration (ProgressMonitor monitor, ConfigData cgrp, string configName)
+ {
+ var runConfig = (ProjectRunConfiguration)CreateUninitializedRunConfiguration (configName);
+ if (cgrp.Group != null) {
+ runConfig.MainPropertyGroup = cgrp.Group;
+ runConfig.StoreInUserFile = cgrp.Group.ParentProject == userProject;
+ }
+ runConfig.MainPropertyGroup.ResetIsNewFlags ();
+ InitRunConfiguration (runConfig);
+ projectExtension.OnReadRunConfiguration (monitor, runConfig, runConfig.Properties);
+ runConfigurations.Add (runConfig);
+ }
+
+ void InitRunConfiguration (ProjectRunConfiguration config)
+ {
+ var pi = CreateProjectInstaceForRunConfiguration (config.Name);
+ config.Properties = pi.GetPropertiesLinkedToGroup (config.MainPropertyGroup);
+ config.ProjectInstance = pi;
+ }
+
+ MSBuildProjectInstance CreateProjectInstaceForRunConfiguration (string name, bool onlyEvaluateProperties = true)
+ {
+ var pi = PrepareProjectInstaceForRunConfiguration (name, onlyEvaluateProperties);
+ pi.Evaluate ();
+ return pi;
+ }
+
+ async Task<MSBuildProjectInstance> CreateProjectInstaceForRunConfigurationAsync (string name, bool onlyEvaluateProperties = true)
+ {
+ var pi = PrepareProjectInstaceForRunConfiguration (name, onlyEvaluateProperties);
+ await pi.EvaluateAsync ();
+ return pi;
+ }
+
+ MSBuildProjectInstance PrepareProjectInstaceForRunConfiguration (string name, bool onlyEvaluateProperties)
+ {
+ var pi = sourceProject.CreateInstance ();
+ pi.SetGlobalProperty ("BuildingInsideVisualStudio", "true");
+ pi.SetGlobalProperty ("RunConfiguration", name);
+ pi.OnlyEvaluateProperties = onlyEvaluateProperties;
+ return pi;
+ }
+
+ protected virtual ProjectRunConfiguration OnCreateRunConfiguration (string name)
+ {
+ return new ProjectRunConfiguration (name);
+ }
+
+ protected virtual void OnReadRunConfiguration (ProgressMonitor monitor, ProjectRunConfiguration runConfig, IPropertySet grp)
+ {
+ runConfig.Read (grp);
+ }
+
+ internal void OnRunConfigurationsAdded (IEnumerable<SolutionItemRunConfiguration> items)
+ {
+ // Initialize the property group only if the project is not being loaded (in which case it will
+ // be initialized by the ReadProject method) or if the project is new (because it will be initialized
+ // after the project is fully written, since only then all imports are in place
+ if (!Loading && !sourceProject.IsNewProject) {
+ foreach (var s in items)
+ InitRunConfiguration ((ProjectRunConfiguration)s);
+ }
+ }
- timer.Trace ("Removing duplicate items");
+ internal void OnRunConfigurationRemoved (IEnumerable<SolutionItemRunConfiguration> items)
+ {
- foreach (var t in toRemove)
- msproject.RemoveItem (t);*/
}
internal void LoadProjectItems (MSBuildProject msproject, ProjectItemFlags flags, HashSet<MSBuildItem> loadedItems)
@@ -2458,6 +2618,20 @@ namespace MonoDevelop.Projects
}
}
+/* if (runConfigurations.Count > 0) {
+ // Set the default configuration of the project.
+ // First of the properties that defines the default run configuration
+ var defaultConfProp = globalGroup.GetProperties ().FirstOrDefault (p => p.Name == "RunConfiguration" && IsDefaultSetter (p));
+
+ if (msproject.IsNewProject || (defaultConfProp != null)) {
+ // If there is no run configuration property, or if the configuration doesn't exist anymore, give it a new value
+ if (defaultConfProp == null || !runConfigurations.Any (c => c.Name == defaultConfProp.UnevaluatedValue)) {
+ var runConfig = runConfigurations.FirstOrDefault (c => c.Name == "Default") ?? runConfigurations [0];
+ globalGroup.SetValue ("RunConfiguration", runConfig.Name, condition: " '$(RunConfiguration)' == '' ");
+ }
+ }
+ }*/
+
if (TypeGuid == MSBuildProjectService.GenericItemGuid) {
DataType dt = MSBuildProjectService.DataContext.GetConfigurationDataType (GetType ());
globalGroup.SetValue ("ItemType", dt.Name);
@@ -2496,10 +2670,35 @@ namespace MonoDevelop.Projects
{
IMSBuildPropertySet globalGroup = msproject.GetGlobalPropertyGroup ();
- // Configurations
+ WriteConfigurations (monitor, msproject, globalGroup);
+
+ WriteRunConfigurations (monitor, msproject, globalGroup);
+
+ SaveProjectItems (monitor, msproject, usedMSBuildItems);
+
+ if (msproject.IsNewProject) {
+ foreach (var im in DefaultImports)
+ msproject.AddNewImport (im);
+ }
+
+ foreach (var im in importsAdded) {
+ if (msproject.GetImport (im.Name, im.Condition) == null)
+ msproject.AddNewImport (im.Name, im.Condition);
+ }
+ foreach (var im in importsRemoved) {
+ var i = msproject.GetImport (im.Name, im.Condition);
+ if (i != null)
+ msproject.RemoveImport (i);
+ }
+ importsAdded.Clear ();
+ importsRemoved.Clear ();
+ msproject.WriteExternalProjectProperties (this, GetType (), true);
+ }
+ void WriteConfigurations (ProgressMonitor monitor, MSBuildProject msproject, IMSBuildPropertySet globalGroup)
+ {
if (Configurations.Count > 0) {
-
+
List<ConfigData> configData = GetConfigData (msproject, false);
// Write configuration data, creating new property groups if necessary
@@ -2515,7 +2714,7 @@ namespace MonoDevelop.Projects
int i = Configurations.IndexOf (conf);
if (i != -1 && i + 1 < Configurations.Count)
nextConf = ((ProjectConfiguration)Configurations [i + 1]).MainPropertyGroup;
-
+
msproject.AddPropertyGroup (pg, true, nextConf);
pg.Condition = BuildConfigCondition (conf.Name, conf.Platform);
cdata = new ConfigData (conf.Name, conf.Platform, pg);
@@ -2579,26 +2778,85 @@ namespace MonoDevelop.Projects
foreach (ProjectConfiguration config in Configurations)
config.MainPropertyGroup.ResetIsNewFlags ();
}
+ }
- SaveProjectItems (monitor, msproject, usedMSBuildItems);
+ void WriteRunConfigurations (ProgressMonitor monitor, MSBuildProject msproject, IMSBuildPropertySet globalGroup)
+ {
+ List<ConfigData> configData = new List<ConfigData> ();
+ GetRunConfigData (configData, msproject, false);
+ GetRunConfigData (configData, userProject, false);
- if (msproject.IsNewProject) {
- foreach (var im in DefaultImports)
- msproject.AddNewImport (im);
- }
+ if (RunConfigurations.Count > 0) {
- foreach (var im in importsAdded) {
- if (msproject.GetImport (im.Name, im.Condition) == null)
- msproject.AddNewImport (im.Name, im.Condition);
+ // Write configuration data, creating new property groups if necessary
+
+ var defaultConfig = CreateRunConfigurationInternal ("Default");
+
+ foreach (ProjectRunConfiguration runConfig in RunConfigurations) {
+
+ MSBuildPropertyGroup pg = runConfig.MainPropertyGroup;
+ ConfigData cdata = configData.FirstOrDefault (cd => cd.Group == pg);
+ var targetProject = runConfig.StoreInUserFile ? userProject : msproject;
+
+ if (runConfig.IsDefaultConfiguration && runConfig.Equals (defaultConfig)) {
+ // If the default configuration has the default values, then there is no need to save it.
+ // If this configuration was added after loading the project, we are not adding it to the msproject and we are done.
+ // If this configuration was loaded from the project and later modified to the default values, we dont set cdata.Exists=true,
+ // so it will be removed from the msproject below.
+ continue;
+ }
+
+ // Create the user project file if it doesn't yet exist
+ if (targetProject == null)
+ targetProject = userProject = CreateUserProject (msproject);
+
+ if (cdata == null) {
+ // Try to keep the groups in the same order as the config list
+ MSBuildObject nextConfig = null;
+ int i = runConfigurations.IndexOf (runConfig);
+ if (i != -1 && i + 1 < runConfigurations.Count)
+ nextConfig = runConfigurations.Skip (i).Cast<ProjectRunConfiguration> ().FirstOrDefault (s => s.MainPropertyGroup.ParentProject == targetProject)?.MainPropertyGroup;
+ targetProject.AddPropertyGroup (pg, true, nextConfig);
+ pg.Condition = BuildRunConfigurationCondition (runConfig.Name);
+ cdata = new ConfigData (runConfig.Name, null, pg);
+ cdata.IsNew = true;
+ configData.Add (cdata);
+ } else {
+ // The configuration name may have changed
+ if (cdata.Config != runConfig.Name) {
+ ((MSBuildPropertyGroup)cdata.Group).Condition = BuildRunConfigurationCondition (runConfig.Name);
+ cdata.Config = runConfig.Name;
+ }
+ var groupInUserProject = cdata.Group.ParentProject == userProject;
+ if (groupInUserProject != runConfig.StoreInUserFile) {
+ cdata.Group.ParentProject.Remove (cdata.Group);
+ targetProject.AddPropertyGroup (cdata.Group);
+ }
+ }
+
+ cdata.Exists = true;
+ ProjectExtension.OnWriteRunConfiguration (monitor, runConfig, runConfig.Properties);
+ runConfig.MainPropertyGroup.PurgeDefaultProperties ();
+ }
}
- foreach (var im in importsRemoved) {
- var i = msproject.GetImport (im.Name, im.Condition);
- if (i != null)
- msproject.RemoveImport (i);
+
+ // Remove groups corresponding to configurations that have been removed
+ foreach (ConfigData cd in configData) {
+ if (!cd.Exists)
+ cd.Group.ParentProject.Remove (cd.Group);
}
- importsAdded.Clear ();
- importsRemoved.Clear ();
- msproject.WriteExternalProjectProperties (this, GetType (), true);
+
+ foreach (ProjectRunConfiguration runConfig in runConfigurations)
+ runConfig.MainPropertyGroup.ResetIsNewFlags ();
+ }
+
+ MSBuildProject CreateUserProject (MSBuildProject msproject)
+ {
+ var p = new MSBuildProject (msproject.EngineManager);
+ // Remove the main property group
+ p.Remove (p.PropertyGroups.First ());
+ p.FileName = msproject.FileName + ".user";
+ return p;
}
protected virtual void OnWriteConfiguration (ProgressMonitor monitor, ProjectConfiguration config, IPropertySet pset)
@@ -2606,6 +2864,11 @@ namespace MonoDevelop.Projects
config.Write (pset);
}
+ protected virtual void OnWriteRunConfiguration (ProgressMonitor monitor, ProjectRunConfiguration config, IPropertySet pset)
+ {
+ config.Write (pset);
+ }
+
IEnumerable<MergedProperty> GetMergeToProjectProperties (List<ConfigData> configData)
{
Dictionary<string,MergedProperty> mergeProps = new Dictionary<string, MergedProperty> ();
@@ -2781,6 +3044,15 @@ namespace MonoDevelop.Projects
return null;
}
+ ConfigData FindPropertyGroup (List<ConfigData> configData, ProjectRunConfiguration config)
+ {
+ foreach (ConfigData data in configData) {
+ if (data.Config == config.Name)
+ return data;
+ }
+ return null;
+ }
+
string BuildConfigCondition (string config, string platform)
{
if (platform.Length == 0)
@@ -2788,6 +3060,11 @@ namespace MonoDevelop.Projects
return " '$(Configuration)|$(Platform)' == '" + config + "|" + platform + "' ";
}
+ string BuildRunConfigurationCondition (string name)
+ {
+ return " '$(RunConfiguration)' == '" + name + "' ";
+ }
+
bool IsMergeToProjectProperty (ItemProperty prop)
{
foreach (object at in prop.CustomAttributes) {
@@ -2950,6 +3227,21 @@ namespace MonoDevelop.Projects
Project.OnGetTypeTags (types);
}
+ internal protected override ProjectRunConfiguration OnCreateRunConfiguration (string name)
+ {
+ return Project.OnCreateRunConfiguration (name);
+ }
+
+ internal protected override void OnReadRunConfiguration (ProgressMonitor monitor, ProjectRunConfiguration runConfig, IPropertySet properties)
+ {
+ Project.OnReadRunConfiguration (monitor, runConfig, properties);
+ }
+
+ internal protected override void OnWriteRunConfiguration (ProgressMonitor monitor, ProjectRunConfiguration runConfig, IPropertySet properties)
+ {
+ Project.OnWriteRunConfiguration (monitor, runConfig, properties);
+ }
+
internal protected override Task<TargetEvaluationResult> OnRunTarget (ProgressMonitor monitor, string target, ConfigurationSelector configuration, TargetEvaluationContext context)
{
return Project.DoRunTarget (monitor, target, configuration, context);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectCreateInformation.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectCreateInformation.cs
index 316dda8010..db86bf242e 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectCreateInformation.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectCreateInformation.cs
@@ -25,6 +25,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
+using System;
using MonoDevelop.Core;
using MonoDevelop.Core.StringParsing;
@@ -82,5 +83,10 @@ namespace MonoDevelop.Projects
ActiveConfiguration = projectCreateInformation.ActiveConfiguration;
Parameters = projectCreateInformation.Parameters;
}
+
+ /// <summary>
+ /// A callback that will be invoked to initialize the project
+ /// </summary>
+ public Action<SolutionItem> TemplateInitializationCallback { get; set; }
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs
index 957f06616c..a4a234ccd5 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectExtension.cs
@@ -60,6 +60,21 @@ namespace MonoDevelop.Projects
return next.SupportsFlavor (guid);
}
+ internal protected virtual ProjectRunConfiguration OnCreateRunConfiguration (string name)
+ {
+ return next.OnCreateRunConfiguration (name);
+ }
+
+ internal protected virtual void OnReadRunConfiguration (ProgressMonitor monitor, ProjectRunConfiguration config, IPropertySet properties)
+ {
+ next.OnReadRunConfiguration (monitor, config, properties);
+ }
+
+ internal protected virtual void OnWriteRunConfiguration (ProgressMonitor monitor, ProjectRunConfiguration config, IPropertySet properties)
+ {
+ next.OnWriteRunConfiguration (monitor, config, properties);
+ }
+
internal protected virtual Task<TargetEvaluationResult> OnRunTarget (ProgressMonitor monitor, string target, ConfigurationSelector configuration, TargetEvaluationContext context)
{
return next.OnRunTarget (monitor, target, configuration, context);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFeature.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFeature.cs
index 75ac1a1b7e..fd9becc607 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFeature.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectFeature.cs
@@ -33,7 +33,8 @@ namespace MonoDevelop.Projects
None = 0,
Build = 1,
Execute = 2,
- Configurations = 4
+ Configurations = 4,
+ RunConfigurations = 8
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectRunConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectRunConfiguration.cs
new file mode 100644
index 0000000000..efaa559a58
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectRunConfiguration.cs
@@ -0,0 +1,156 @@
+//
+// ProjectRunConfiguration.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using MonoDevelop.Projects.MSBuild;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace MonoDevelop.Projects
+{
+ public class ProjectRunConfiguration: SolutionItemRunConfiguration
+ {
+ IPropertySet properties;
+ MSBuildPropertyGroup mainPropertyGroup;
+
+ public ProjectRunConfiguration (string name): base (name)
+ {
+ }
+
+ internal protected virtual void Initialize (Project project)
+ {
+ // There may be run configuration properties defined in the
+ // main property group in the project. Those values have to
+ // be initially loaded in new run configurations.
+
+ using (var pi = project.MSBuildProject.CreateInstance ()) {
+ pi.SetGlobalProperty ("BuildingInsideVisualStudio", "true");
+ pi.SetGlobalProperty ("RunConfiguration", "");
+ pi.OnlyEvaluateProperties = true;
+ pi.Evaluate ();
+ var lg = pi.GetPropertiesLinkedToGroup (MainPropertyGroup);
+ Read (lg);
+ properties = MainPropertyGroup;
+ MainPropertyGroup.UnlinkFromProjectInstance ();
+ }
+ }
+
+ public new Project ParentItem {
+ get { return (Project)base.ParentItem; }
+ }
+
+ /// <summary>
+ /// Copies the data of a run configuration into this configuration
+ /// </summary>
+ /// <param name="config">Configuration from which to get the data.</param>
+ /// <param name="isRename">If true, it means that the copy is being made as a result of a rename or clone operation. In this case,
+ /// the overriden method may change the value of some properties that depend on the configuration name.</param>
+ public void CopyFrom (ProjectRunConfiguration config, bool isRename = false)
+ {
+ StoreInUserFile = config.StoreInUserFile;
+ OnCopyFrom (config, isRename);
+ }
+
+ protected virtual void OnCopyFrom (ProjectRunConfiguration config, bool isRename)
+ {
+ }
+
+ internal protected virtual void Read (IPropertySet pset)
+ {
+ properties = pset;
+ pset.ReadObjectProperties (this, GetType (), true);
+ }
+
+ internal protected virtual void Write (IPropertySet pset)
+ {
+ pset.WriteObjectProperties (this, GetType (), true);
+ }
+
+ internal bool Equals (ProjectRunConfiguration other)
+ {
+ var dict1 = new Dictionary<string, string> ();
+ var dict2 = new Dictionary<string, string> ();
+
+ var thisData = new ProjectItemMetadata ();
+ Write (thisData);
+ GetProps (MainPropertyGroup, dict1);
+ GetProps (thisData, dict1);
+
+ var otherData = new ProjectItemMetadata ();
+ other.Write (otherData);
+ GetProps (other.MainPropertyGroup, dict2);
+ GetProps (otherData, dict2);
+
+ if (dict1.Count != dict2.Count)
+ return false;
+ foreach (var tp in dict1) {
+ string v;
+ if (!dict2.TryGetValue (tp.Key, out v) || tp.Value != v)
+ return false;
+ }
+ return true;
+ }
+
+ void GetProps (IPropertySet p, Dictionary<string,string> dict)
+ {
+ foreach (var prop in p.GetProperties ())
+ dict [prop.Name] = prop.Value;
+ }
+
+ /// <summary>
+ /// Property set where the properties for this configuration are defined.
+ /// </summary>
+ public IPropertySet Properties {
+ get {
+ return properties ?? MainPropertyGroup;
+ }
+ internal set {
+ properties = value;
+ }
+ }
+
+ internal MSBuildPropertyGroup MainPropertyGroup {
+ get {
+ if (mainPropertyGroup == null) {
+ if (ParentItem == null)
+ mainPropertyGroup = new MSBuildPropertyGroup ();
+ else
+ mainPropertyGroup = ParentItem.MSBuildProject.CreatePropertyGroup ();
+ mainPropertyGroup.IgnoreDefaultValues = true;
+ }
+ return mainPropertyGroup;
+ }
+ set {
+ mainPropertyGroup = value;
+ mainPropertyGroup.IgnoreDefaultValues = true;
+ }
+ }
+
+ internal MSBuildProjectInstance ProjectInstance { get; set; }
+
+ public bool StoreInUserFile { get; set; } = true;
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfiguration.cs
new file mode 100644
index 0000000000..5235be4985
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfiguration.cs
@@ -0,0 +1,59 @@
+//
+// RunConfiguration.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+
+namespace MonoDevelop.Projects
+{
+ public abstract class RunConfiguration
+ {
+ /// <summary>
+ /// Display name of the configuration
+ /// </summary>
+ public abstract string Name { get; }
+
+ /// <summary>
+ /// Unique id of the configuration
+ /// </summary>
+ public abstract string Id { get; }
+
+ /// <summary>
+ /// Icon
+ /// </summary>
+ public virtual string IconId {
+ get { return null; }
+ }
+
+ /// <summary>
+ /// One line description of the configuration
+ /// </summary>
+ /// <value>The summary.</value>
+ public virtual string Summary {
+ get { return string.Empty; }
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfigurationCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfigurationCollection.cs
new file mode 100644
index 0000000000..91bf3e9704
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/RunConfigurationCollection.cs
@@ -0,0 +1,65 @@
+//
+// RunConfigurationCollection.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+
+namespace MonoDevelop.Projects
+{
+ public class RunConfigurationCollection: ItemCollection<ProjectRunConfiguration>
+ {
+ SolutionItem parentItem;
+
+ public RunConfigurationCollection ()
+ {
+ }
+
+ internal RunConfigurationCollection (SolutionItem parentItem)
+ {
+ this.parentItem = parentItem;
+ }
+
+ protected override void OnItemsAdded (IEnumerable<ProjectRunConfiguration> items)
+ {
+ if (parentItem != null) {
+ foreach (var conf in items)
+ ((SolutionItemRunConfiguration)conf).ParentItem = parentItem;
+ }
+ base.OnItemsAdded (items);
+ (parentItem as Project)?.OnRunConfigurationsAdded (items);
+ }
+
+ protected override void OnItemsRemoved (IEnumerable<ProjectRunConfiguration> items)
+ {
+ if (parentItem != null) {
+ foreach (var conf in items)
+ ((SolutionItemRunConfiguration)conf).ParentItem = null;
+ }
+ base.OnItemsRemoved (items);
+ (parentItem as Project)?.OnRunConfigurationRemoved (items);
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SingleItemSolutionRunConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SingleItemSolutionRunConfiguration.cs
new file mode 100644
index 0000000000..3a26f1c680
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SingleItemSolutionRunConfiguration.cs
@@ -0,0 +1,45 @@
+//
+// SingleItemSolutionRunConfiguration.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+namespace MonoDevelop.Projects
+{
+ public sealed class SingleItemSolutionRunConfiguration: SolutionRunConfiguration
+ {
+ public SingleItemSolutionRunConfiguration (SolutionItem item, SolutionItemRunConfiguration config): base (item.ItemId + "|" + config?.Name)
+ {
+ Item = item;
+ RunConfiguration = config;
+ if (config != null && !config.IsDefaultConfiguration)
+ SetName (item.Name + " – " + config.Name);
+ else
+ SetName (item.Name);
+ }
+
+ public SolutionItem Item { get; private set; }
+ public SolutionItemRunConfiguration RunConfiguration { get; private set; }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs
index 05a406c308..8c49995ef0 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs
@@ -43,24 +43,22 @@ using MonoDevelop.Projects.MSBuild;
namespace MonoDevelop.Projects
{
[ProjectModelDataItem]
- public class Solution: WorkspaceItem, IConfigurationTarget, IPolicyProvider, IBuildTarget, IMSBuildFileObject
+ public class Solution: WorkspaceItem, IConfigurationTarget, IPolicyProvider, IBuildTarget, IMSBuildFileObject, IRunTarget
{
internal object MemoryProbe = Counters.SolutionsInMemory.CreateMemoryProbe ();
+
SolutionFolder rootFolder;
string defaultConfiguration;
MSBuildFileFormat format;
bool loadingFromConstructor;
- SolutionItem startupItem;
- List<SolutionItem> startupItems;
- bool singleStartup = true;
+ SolutionRunConfiguration startupSolutionConfiguration;
- // Used for serialization only
- List<string> multiStartupItems;
- string startItemFileName;
-
ReadOnlyCollection<SolutionItem> solutionItems;
SolutionConfigurationCollection configurations;
+ SolutionRunConfigurationCollection runConfigurations;
+ MultiItemSolutionRunConfiguration multiStartupConfig = new MultiItemSolutionRunConfiguration (MultiStartupConfigId, "Multi-Startup");
+ const string MultiStartupConfigId = "MonoDevelop.Projects.MultiStartup";
MSBuildEngineManager msbuildEngineManager = new MSBuildEngineManager ();
@@ -82,6 +80,7 @@ namespace MonoDevelop.Projects
loadingFromConstructor = loading;
Counters.SolutionsLoaded++;
configurations = new SolutionConfigurationCollection (this);
+ runConfigurations = new SolutionRunConfigurationCollection (this);
format = MSBuildFileFormat.DefaultFormat;
Initialize (this);
}
@@ -162,99 +161,56 @@ namespace MonoDevelop.Projects
return solutionItems;
}
}
-
- public SolutionItem StartupItem {
+
+ public SolutionRunConfiguration StartupConfiguration {
get {
- if (startItemFileName != null) {
- startupItem = FindSolutionItem (startItemFileName);
- startItemFileName = null;
- singleStartup = true;
- }
- if (startupItem == null && singleStartup) {
- var its = GetAllItems<SolutionItem> ();
- if (its.Any ())
- startupItem = its.FirstOrDefault (it => it.SupportsExecute ());
+ return startupSolutionConfiguration;
+ }
+ set {
+ if (startupSolutionConfiguration != value) {
+ var oldIt = StartupItem;
+ startupSolutionConfiguration = value;
+ NotifyModified ();
+ OnStartupConfigurationChanged (null);
+ if (oldIt != StartupItem)
+ OnStartupItemChanged (null);
}
- return startupItem;
+ }
+ }
+
+ public SolutionItem StartupItem {
+ get {
+ return (StartupConfiguration as SingleItemSolutionRunConfiguration)?.Item;
}
set {
- startupItem = value;
- startItemFileName = null;
- NotifyModified ();
- OnStartupItemChanged(null);
+ if (value != StartupItem)
+ StartupConfiguration = GetRunConfigurations ().OfType<SingleItemSolutionRunConfiguration> ().FirstOrDefault (co => co.Item == value);
}
}
-
+
public bool SingleStartup {
get {
- if (startItemFileName != null)
- return true;
- if (multiStartupItems != null)
- return false;
- return singleStartup;
+ return StartupConfiguration is SingleItemSolutionRunConfiguration;
}
set {
- if (SingleStartup == value)
+ if (value == SingleStartup)
return;
- singleStartup = value;
if (value) {
- if (MultiStartupItems.Count > 0)
- startupItem = startupItems [0];
+ StartupItem = multiStartupConfig.Items.FirstOrDefault () ?? GetRunConfigurations ().OfType<SingleItemSolutionRunConfiguration> ().Select (i => i.Item).FirstOrDefault ();
} else {
- MultiStartupItems.Clear ();
- if (StartupItem != null)
- MultiStartupItems.Add (StartupItem);
+ if (!runConfigurations.Contains (multiStartupConfig))
+ runConfigurations.Add (multiStartupConfig);
+ StartupConfiguration = multiStartupConfig;
}
- NotifyModified ();
- OnStartupItemChanged(null);
}
}
public List<SolutionItem> MultiStartupItems {
get {
- if (multiStartupItems != null) {
- startupItems = new List<SolutionItem> ();
- foreach (string file in multiStartupItems) {
- SolutionItem it = FindSolutionItem (file);
- if (it != null)
- startupItems.Add (it);
- }
- multiStartupItems = null;
- singleStartup = false;
- }
- else if (startupItems == null)
- startupItems = new List<SolutionItem> ();
- return startupItems;
+ return multiStartupConfig.Items;
}
}
- // Used by serialization only
- internal string StartupItemFileName {
- get {
- if (SingleStartup && StartupItem != null)
- return StartupItem.FileName;
- else
- return null ;
- }
- set { startItemFileName = value; }
- }
-
- internal List<string> MultiStartupItemFileNames {
- get {
- if (SingleStartup)
- return null;
- if (multiStartupItems != null)
- return multiStartupItems;
- List<string> files = new List<string> ();
- foreach (SolutionItem item in MultiStartupItems)
- files.Add (item.FileName);
- return files;
- }
- set {
- multiStartupItems = value;
- }
- }
-
/// <summary>
/// Gets the author information for this solution. If no specific information is set for this solution, it
/// will return the author defined in the global settings.
@@ -285,6 +241,44 @@ namespace MonoDevelop.Projects
{
await base.OnEndLoad ();
LoadItemProperties (UserProperties, RootFolder, "MonoDevelop.Ide.ItemProperties");
+
+ bool startupConfigSet = false;
+
+ var sitem = UserProperties.GetValue<string> ("StartupItem");
+ if (!string.IsNullOrEmpty (sitem)) {
+ // Old StartupItem property. Find the corresponding SingleItemSolutionRunConfiguration instance and get rid of the property.
+ var startItemFileName = GetAbsoluteChildPath (sitem);
+ var item = FindSolutionItem (startItemFileName);
+ if (item != null) {
+ StartupConfiguration = GetRunConfigurations ().OfType<SingleItemSolutionRunConfiguration> ().FirstOrDefault (c => c.Item == item);
+ startupConfigSet = true;
+ }
+ UserProperties.RemoveValue ("StartupItem");
+ }
+
+ var sitems = UserProperties.GetValue<string []> ("StartupItems");
+ if (sitems != null && sitems.Length > 0) {
+ // Old StartupItems property. Create a corresponding MultiItemSolutionRunConfiguration.
+ var multiStartupItems = sitems.Select (p => (string)GetAbsoluteChildPath (p)).Select (file => FindSolutionItem (file)).Where (i => i != null);
+ multiStartupConfig.Items.Clear ();
+ multiStartupConfig.Items.AddRange (multiStartupItems.ToArray ());
+ runConfigurations.Add (multiStartupConfig);
+ if (!startupConfigSet) {
+ // If the config has not been set by StartupItem it means that this is an old solution that had been configured with multiple startup.
+ // Select the multi-startup config in this case.
+ StartupConfiguration = multiStartupConfig;
+ startupConfigSet = true;
+ }
+ }
+
+ if (!startupConfigSet) {
+ // Startup configuration has not been set by legacy properties. Do it now.
+ var sconfig = UserProperties.GetValue<string> ("StartupConfiguration");
+ if (!string.IsNullOrEmpty (sconfig))
+ StartupConfiguration = GetRunConfigurations ().FirstOrDefault (c => c.Id == sconfig);
+ else
+ StartupConfiguration = GetRunConfigurations ().FirstOrDefault ();
+ }
}
internal protected override Task OnSave (ProgressMonitor monitor)
@@ -292,24 +286,15 @@ namespace MonoDevelop.Projects
return FileFormat.WriteFile (FileName, this, monitor);
}
- protected override async Task OnLoadUserProperties ()
- {
- await base.OnLoadUserProperties ();
- var sitem = UserProperties.GetValue<string> ("StartupItem");
- if (!string.IsNullOrEmpty (sitem))
- startItemFileName = GetAbsoluteChildPath (sitem);
-
- var sitems = UserProperties.GetValue<string[]> ("StartupItems");
- if (sitems != null && sitems.Length > 0)
- multiStartupItems = sitems.Select (p => (string) GetAbsoluteChildPath (p)).ToList ();
- }
-
protected override async Task OnSaveUserProperties ()
{
- UserProperties.SetValue ("StartupItem", (string) GetRelativeChildPath (StartupItemFileName));
- if (MultiStartupItemFileNames != null) {
- UserProperties.SetValue ("StartupItems", MultiStartupItemFileNames.Select (p => (string)GetRelativeChildPath (p)).ToArray ());
- } else
+ UserProperties.SetValue ("StartupConfiguration", (string)StartupConfiguration?.Id);
+
+ // Save the multi-startup configuration only if it is the one that's selected
+ var msc = StartupConfiguration as MultiItemSolutionRunConfiguration;
+ if (msc != null)
+ UserProperties.SetValue ("StartupItems", msc.Items.Select (p => (string)GetRelativeChildPath (p.FileName)).ToArray ());
+ else
UserProperties.RemoveValue ("StartupItems");
CollectItemProperties (UserProperties, RootFolder, "MonoDevelop.Ide.ItemProperties");
@@ -402,7 +387,7 @@ namespace MonoDevelop.Projects
{
return (SolutionConfiguration) configuration.GetConfiguration (this) ?? DefaultConfiguration;
}
-
+
public SolutionFolderItem GetSolutionItem (string itemId)
{
foreach (SolutionFolderItem item in Items)
@@ -638,6 +623,21 @@ namespace MonoDevelop.Projects
return true;
}
+ internal void OnRunConfigurationsAdded (IEnumerable<SolutionRunConfiguration> items)
+ {
+ NotifyRunConfigurationsChanged ();
+ }
+
+ internal void OnRunConfigurationRemoved (IEnumerable<SolutionRunConfiguration> items)
+ {
+ NotifyRunConfigurationsChanged ();
+ }
+
+ internal void NotifyRunConfigurationsChanged ()
+ {
+ RunConfigurationsChanged?.Invoke (this, EventArgs.Empty);
+ }
+
public Task<BuildResult> Clean (ProgressMonitor monitor, string configuration)
{
return Clean (monitor, (SolutionConfigurationSelector) configuration);
@@ -670,40 +670,134 @@ namespace MonoDevelop.Projects
public Task Execute (ProgressMonitor monitor, ExecutionContext context, string configuration)
{
- return Execute (monitor, context, (SolutionConfigurationSelector) configuration);
+ return Execute (monitor, context, (SolutionConfigurationSelector) configuration, StartupConfiguration);
}
public Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- return SolutionExtension.Execute (monitor, context, configuration);
+ return Execute (monitor, context, configuration, StartupConfiguration);
+ }
+
+ public Task Execute (ProgressMonitor monitor, ExecutionContext context, string configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return Execute (monitor, context, (SolutionConfigurationSelector)configuration, runConfiguration);
+ }
+
+ public Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return SolutionExtension.Execute (monitor, context, configuration, runConfiguration ?? StartupConfiguration);
+ }
+
+ Task IRunTarget.Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return Execute (monitor, context, configuration, (SolutionRunConfiguration)runConfiguration);
}
public Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- return SolutionExtension.PrepareExecution (monitor, context, configuration);
+ return PrepareExecution (monitor, context, configuration, StartupConfiguration);
+ }
+
+ public Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return SolutionExtension.PrepareExecution (monitor, context, configuration, runConfiguration);
+ }
+
+ Task IRunTarget.PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return PrepareExecution (monitor, context, configuration, (SolutionRunConfiguration)runConfiguration);
}
public bool CanExecute (ExecutionContext context, string configuration)
{
- return CanExecute (context, (SolutionConfigurationSelector) configuration);
+ return CanExecute (context, (SolutionConfigurationSelector) configuration, StartupConfiguration);
}
public bool CanExecute (ExecutionContext context, ConfigurationSelector configuration)
{
- return SolutionExtension.CanExecute (context, configuration);
+ return CanExecute (context, configuration, StartupConfiguration);
+ }
+
+ public bool CanExecute (ExecutionContext context, string configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return CanExecute (context, (SolutionConfigurationSelector)configuration, runConfiguration);
+ }
+
+ public bool CanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return SolutionExtension.CanExecute (context, configuration, runConfiguration);
+ }
+
+ bool IRunTarget.CanExecute (ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return CanExecute (context, configuration, (SolutionRunConfiguration)runConfiguration);
+ }
+
+ public IEnumerable<SolutionRunConfiguration> GetRunConfigurations ()
+ {
+ return SolutionExtension.OnGetRunConfigurations ();
+ }
+
+ IEnumerable<RunConfiguration> IRunTarget.GetRunConfigurations ()
+ {
+ return GetRunConfigurations ();
+ }
+
+ protected virtual IEnumerable<SolutionRunConfiguration> OnGetRunConfigurations ()
+ {
+ IEnumerable<SolutionRunConfiguration> res = runConfigurations;
+ foreach (var it in GetAllSolutionItems ().Where (i => i.SupportsExecute ())) {
+ var configs = it.GetRunConfigurations ().ToArray ();
+ if (!configs.Any ())
+ res = res.Concat (new SingleItemSolutionRunConfiguration (it, null));
+ else if (configs.Length == 1)
+ res = res.Concat (new SingleItemSolutionRunConfiguration (it, configs[0]));
+ else
+ res = res.Concat (it.GetRunConfigurations ().Select (c => new SingleItemSolutionRunConfiguration (it, c)));
+ }
+ return res;
}
public IEnumerable<ExecutionTarget> GetExecutionTargets (string configuration)
{
- return GetExecutionTargets ((SolutionConfigurationSelector) configuration);
+ return GetExecutionTargets ((SolutionConfigurationSelector) configuration, StartupConfiguration);
}
public IEnumerable<ExecutionTarget> GetExecutionTargets (ConfigurationSelector configuration)
{
+ return GetExecutionTargets (configuration, StartupConfiguration);
+ }
+
+ public IEnumerable<ExecutionTarget> GetExecutionTargets (string configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return GetExecutionTargets ((SolutionConfigurationSelector)configuration, runConfiguration);
+ }
+
+ public IEnumerable<ExecutionTarget> GetExecutionTargets (ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return SolutionExtension.GetExecutionTargets (this, configuration, runConfiguration);
+ }
+
+ IEnumerable<ExecutionTarget> IRunTarget.GetExecutionTargets (ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return SolutionExtension.GetExecutionTargets (this, configuration, (SolutionRunConfiguration)runConfiguration);
+ }
+
+ IEnumerable<ExecutionTarget> OnGetExecutionTargets (ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
return SolutionExtension.GetExecutionTargets (this, configuration);
}
- /*protected virtual*/ Task<BuildResult> OnBuild (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
+ /*protected virtual*/
+ Task<BuildResult> OnBuild (ProgressMonitor monitor, ConfigurationSelector configuration, OperationContext operationContext)
{
return RootFolder.Build (monitor, configuration, operationContext:operationContext);
}
@@ -718,41 +812,46 @@ namespace MonoDevelop.Projects
return RootFolder.Clean (monitor, configuration, operationContext);
}
- /*protected virtual*/ bool OnGetCanExecute(ExecutionContext context, ConfigurationSelector configuration)
+ /*protected virtual*/ bool OnGetCanExecute(ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
{
- if (SingleStartup) {
- if (StartupItem == null)
- return false;
- return StartupItem.CanExecute (context, configuration);
- } else {
- foreach (SolutionItem it in MultiStartupItems) {
+ var ssc = runConfiguration as SingleItemSolutionRunConfiguration;
+ if (ssc != null)
+ return ssc.Item.CanExecute (context, configuration, ssc.RunConfiguration);
+
+ var msc = runConfiguration as MultiItemSolutionRunConfiguration;
+ if (msc != null) {
+ foreach (SolutionItem it in msc.Items) {
if (it.CanExecute (context, configuration))
return true;
}
return false;
}
+ return false;
}
- /*protected virtual*/ async Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ /*protected virtual*/ async Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
{
- if (SingleStartup) {
- if (StartupItem == null) {
- monitor.ReportError (GettextCatalog.GetString ("Startup item not set"), null);
- return;
- }
- await StartupItem.Execute (monitor, context, configuration);
- } else {
+ var ssc = runConfiguration as SingleItemSolutionRunConfiguration;
+ if (ssc != null) {
+ await ssc.Item.Execute (monitor, context, configuration, ssc.RunConfiguration);
+ return;
+ }
+ var msc = runConfiguration as MultiItemSolutionRunConfiguration;
+ if (msc != null) {
var tasks = new List<Task> ();
var monitors = new List<AggregatedProgressMonitor> ();
monitor.BeginTask ("Executing projects", 1);
+
+ var secondaryContext = new ExecutionContext (Runtime.ProcessService.DefaultExecutionMode, context.ConsoleFactory, null);
- foreach (SolutionItem it in MultiStartupItems) {
+ foreach (SolutionItem it in msc.Items) {
if (!it.CanExecute (context, configuration))
continue;
AggregatedProgressMonitor mon = new AggregatedProgressMonitor ();
mon.AddFollowerMonitor (monitor, MonitorAction.ReportError | MonitorAction.ReportWarning | MonitorAction.FollowerCancel);
monitors.Add (mon);
tasks.Add (it.Execute (mon, context, configuration));
+ context = secondaryContext;
}
try {
await Task.WhenAll (tasks);
@@ -767,7 +866,7 @@ namespace MonoDevelop.Projects
}
}
- /*protected virtual*/ Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ /*protected virtual*/ Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
{
return Task.FromResult (0);
}
@@ -778,6 +877,13 @@ namespace MonoDevelop.Projects
StartupItemChanged (this, e);
}
+ void OnStartupConfigurationChanged (EventArgs e)
+ {
+ if (StartupConfigurationChanged != null)
+ StartupConfigurationChanged (this, e);
+ }
+
+
[ThreadSafe]
public MSBuildFileFormat FileFormat {
get {
@@ -1078,7 +1184,9 @@ namespace MonoDevelop.Projects
#endregion
public event EventHandler StartupItemChanged;
-
+ public event EventHandler StartupConfigurationChanged;
+ public event EventHandler RunConfigurationsChanged;
+
public event SolutionItemChangeEventHandler SolutionItemAdded;
public event SolutionItemChangeEventHandler SolutionItemRemoved;
@@ -1120,19 +1228,19 @@ namespace MonoDevelop.Projects
return Solution.OnClean (monitor, configuration, operationContext);
}
- internal protected override Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ internal protected override Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
{
- return Solution.OnExecute (monitor, context, configuration);
+ return Solution.OnExecute (monitor, context, configuration, runConfiguration);
}
- internal protected override Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ internal protected override Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
{
- return Solution.OnPrepareExecution (monitor, context, configuration);
+ return Solution.OnPrepareExecution (monitor, context, configuration, runConfiguration);
}
- internal protected override bool CanExecute (ExecutionContext context, ConfigurationSelector configuration)
+ internal protected override bool CanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
{
- return Solution.OnGetCanExecute (context, configuration);
+ return Solution.OnGetCanExecute (context, configuration, runConfiguration);
}
internal protected override void OnReadSolution (ProgressMonitor monitor, SlnFile file)
@@ -1165,6 +1273,11 @@ namespace MonoDevelop.Projects
Solution.OnReadSolutionFolderItemData (monitor, properties, item);
}
+ internal protected override IEnumerable<ExecutionTarget> GetExecutionTargets (Solution solution, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return Solution.OnGetExecutionTargets (configuration, runConfiguration);
+ }
+
internal protected override IEnumerable<ExecutionTarget> GetExecutionTargets (Solution solution, ConfigurationSelector configuration)
{
yield break;
@@ -1179,6 +1292,11 @@ namespace MonoDevelop.Projects
{
Solution.OnSetFormat (value);
}
+
+ internal protected override IEnumerable<SolutionRunConfiguration> OnGetRunConfigurations ()
+ {
+ return Solution.OnGetRunConfigurations ();
+ }
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionExtension.cs
index 1907ade73c..a6dfcb7615 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionExtension.cs
@@ -61,19 +61,46 @@ namespace MonoDevelop.Projects
return next.Clean (monitor, configuration, operationContext);
}
+ [Obsolete("Use the overload that takes a SolutionRunConfiguration argument")]
internal protected virtual Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- return next.Execute (monitor, context, configuration);
+ return next.Execute (monitor, context, configuration, (SolutionRunConfiguration)context.RunConfiguration);
}
+ [Obsolete ("Use the overload that takes a SolutionRunConfiguration argument")]
internal protected virtual Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- return next.PrepareExecution (monitor, context, configuration);
+ return next.PrepareExecution (monitor, context, configuration, (SolutionRunConfiguration)context.RunConfiguration);
}
+ [Obsolete ("Use the overload that takes a SolutionRunConfiguration argument")]
internal protected virtual bool CanExecute (ExecutionContext context, ConfigurationSelector configuration)
{
- return next.CanExecute (context, configuration);
+ return next.CanExecute (context, configuration, (SolutionRunConfiguration)context.RunConfiguration);
+ }
+
+ internal protected virtual Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ context.RunConfiguration = runConfiguration;
+#pragma warning disable 618 // Type or member is obsolete
+ return Execute (monitor, context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ internal protected virtual Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ context.RunConfiguration = runConfiguration;
+#pragma warning disable 618 // Type or member is obsolete
+ return PrepareExecution (monitor, context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ internal protected virtual bool CanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ context.RunConfiguration = runConfiguration;
+#pragma warning disable 618 // Type or member is obsolete
+ return CanExecute (context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
}
internal protected virtual IEnumerable<ExecutionTarget> GetExecutionTargets (Solution solution, ConfigurationSelector configuration)
@@ -81,6 +108,16 @@ namespace MonoDevelop.Projects
return next.GetExecutionTargets (solution, configuration);
}
+ internal protected virtual IEnumerable<ExecutionTarget> GetExecutionTargets (Solution solution, ConfigurationSelector configuration, SolutionRunConfiguration runConfiguration)
+ {
+ return next.GetExecutionTargets (solution, configuration, runConfiguration);
+ }
+
+ internal protected virtual IEnumerable<SolutionRunConfiguration> OnGetRunConfigurations ()
+ {
+ return next.OnGetRunConfigurations ();
+ }
+
internal protected virtual bool NeedsBuilding (ConfigurationSelector configuration)
{
return next.NeedsBuilding (configuration);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
index 76b8ae90a7..d34bc6f1a7 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
@@ -52,7 +52,7 @@ using System.Collections.Immutable;
namespace MonoDevelop.Projects
{
- public abstract class SolutionItem : SolutionFolderItem, IWorkspaceFileObject, IConfigurationTarget, IBuildTarget, IMSBuildFileObject
+ public abstract class SolutionItem : SolutionFolderItem, IWorkspaceFileObject, IConfigurationTarget, IBuildTarget, IMSBuildFileObject, IRunTarget
{
internal object MemoryProbe = Counters.ItemsInMemory.CreateMemoryProbe ();
@@ -72,6 +72,7 @@ namespace MonoDevelop.Projects
public event ConfigurationEventHandler DefaultConfigurationChanged;
public event ConfigurationEventHandler ConfigurationAdded;
public event ConfigurationEventHandler ConfigurationRemoved;
+ public EventHandler RunConfigurationsChanged;
// When set, it means this item is saved as part of a global solution save operation
internal bool SavingSolution { get; set; }
@@ -394,6 +395,8 @@ namespace MonoDevelop.Projects
protected virtual void OnInitializeFromTemplate (ProjectCreateInformation projectCreateInfo, XmlElement template)
{
+ if (projectCreateInfo.TemplateInitializationCallback != null)
+ projectCreateInfo.TemplateInitializationCallback (this);
}
protected sealed override FilePath GetDefaultBaseDirectory ( )
@@ -486,12 +489,17 @@ namespace MonoDevelop.Projects
return ItemExtension.OnGetSupportedFeatures ().HasFlag (ProjectFeatures.Configurations);
}
+ public bool SupportsRunConfigurations ()
+ {
+ return ItemExtension.OnGetSupportedFeatures ().HasFlag (ProjectFeatures.RunConfigurations);
+ }
+
protected virtual ProjectFeatures OnGetSupportedFeatures ()
{
if (IsUnsupportedProject)
return ProjectFeatures.Configurations;
else
- return ProjectFeatures.Execute | ProjectFeatures.Build | ProjectFeatures.Configurations;
+ return ProjectFeatures.Execute | ProjectFeatures.Build | ProjectFeatures.Configurations | ProjectFeatures.RunConfigurations;
}
/// <summary>
@@ -822,7 +830,6 @@ namespace MonoDevelop.Projects
protected virtual void OnGetProjectEventMetadata (IDictionary<string, string> metadata)
{
}
-
/// <summary>
/// Executes this solution item
/// </summary>
@@ -835,7 +842,27 @@ namespace MonoDevelop.Projects
/// <param name='configuration'>
/// Configuration to use to execute the item
/// </param>
- public async Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ public Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ {
+ return Execute (monitor, context, configuration, GetDefaultRunConfiguration ());
+ }
+
+ /// <summary>
+ /// Executes this solution item
+ /// </summary>
+ /// <param name='monitor'>
+ /// A progress monitor
+ /// </param>
+ /// <param name='context'>
+ /// An execution context
+ /// </param>
+ /// <param name='configuration'>
+ /// Configuration to use to execute the item
+ /// </param>
+ /// <param name='runConfiguration'>
+ /// Run configuration to use to execute the item
+ /// </param>
+ public async Task Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
SolutionItemConfiguration conf = GetConfiguration (configuration) as SolutionItemConfiguration;
if (conf != null) {
@@ -850,7 +877,7 @@ namespace MonoDevelop.Projects
if (monitor.CancellationToken.IsCancellationRequested)
return;
- await ItemExtension.OnExecute (monitor, context, configuration);
+ await ItemExtension.OnExecute (monitor, context, configuration, runConfiguration ?? GetDefaultRunConfiguration ());
if (conf != null && !monitor.CancellationToken.IsCancellationRequested) {
ExecutionContext localContext = new ExecutionContext (Runtime.ProcessService.DefaultExecutionHandler, context.ConsoleFactory, context.ExecutionTarget);
@@ -860,6 +887,13 @@ namespace MonoDevelop.Projects
}
}
+ Task IRunTarget.Execute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionItemRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return Execute (monitor, context, configuration, (SolutionItemRunConfiguration)runConfiguration);
+ }
+
/// <summary>
/// Prepares the target for execution
/// </summary>
@@ -873,9 +907,35 @@ namespace MonoDevelop.Projects
/// there is no guarantee that Execute() will actually be called.</remarks>
public Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- return BindTask (ct => ItemExtension.OnPrepareExecution (monitor.WithCancellationToken (ct), context, configuration));
+ return PrepareExecution (monitor, context, configuration, GetDefaultRunConfiguration ());
+ }
+
+ /// <summary>
+ /// Prepares the target for execution
+ /// </summary>
+ /// <returns>The execution.</returns>
+ /// <param name="monitor">Monitor for tracking progress</param>
+ /// <param name="context">Execution context</param>
+ /// <param name="configuration">Configuration to execute</param>
+ /// <param name='runConfiguration'>
+ /// Run configuration to use to execute the item
+ /// </param>
+ /// <remarks>This method can be called (it is not mandatory) before Execute() to give the target a chance
+ /// to asynchronously prepare the execution that is going to be done later on. It can be used for example
+ /// to start the simulator that is going to be used for execution. Calling this method is optional, and
+ /// there is no guarantee that Execute() will actually be called.</remarks>
+ public Task PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+ return BindTask (ct => ItemExtension.OnPrepareExecution (monitor.WithCancellationToken (ct), context, configuration, runConfiguration ?? GetDefaultRunConfiguration ()));
}
+ Task IRunTarget.PrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionItemRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return PrepareExecution (monitor, context, configuration, (SolutionItemRunConfiguration)runConfiguration);
+ }
+
/// <summary>
/// Determines whether this solution item can be executed using the specified context and configuration.
/// </summary>
@@ -890,17 +950,44 @@ namespace MonoDevelop.Projects
/// </param>
public bool CanExecute (ExecutionContext context, ConfigurationSelector configuration)
{
- return !IsUnsupportedProject && ItemExtension.OnGetCanExecute (context, configuration);
+ return CanExecute (context, configuration, GetDefaultRunConfiguration ());
+ }
+
+ /// <summary>
+ /// Determines whether this solution item can be executed using the specified context and configuration.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if this instance can be executed; otherwise, <c>false</c>.
+ /// </returns>
+ /// <param name='context'>
+ /// An execution context
+ /// </param>
+ /// <param name='configuration'>
+ /// Configuration to use to execute the item
+ /// </param>
+ /// <param name='runConfiguration'>
+ /// Run configuration to use to execute the item
+ /// </param>
+ public bool CanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+ return !IsUnsupportedProject && ItemExtension.OnGetCanExecute (context, configuration, runConfiguration ?? GetDefaultRunConfiguration ());
}
- async Task DoExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ bool IRunTarget.CanExecute (ExecutionContext context, ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionItemRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return CanExecute (context, configuration, (SolutionItemRunConfiguration)runConfiguration);
+ }
+
+ async Task DoExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
SolutionItemConfiguration conf = GetConfiguration (configuration) as SolutionItemConfiguration;
if (conf != null && conf.CustomCommands.HasCommands (CustomCommandType.Execute)) {
await conf.CustomCommands.ExecuteCommand (monitor, this, CustomCommandType.Execute, context, configuration);
return;
}
- await OnExecute (monitor, context, configuration);
+ await OnExecute (monitor, context, configuration, runConfiguration);
}
/// <summary>
@@ -915,6 +1002,14 @@ namespace MonoDevelop.Projects
/// <param name='configuration'>
/// Configuration to use to execute the item
/// </param>
+ protected virtual Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+#pragma warning disable 618 // Type or member is obsolete
+ return OnExecute (monitor, context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ [Obsolete ("Use overload that takes a RunConfiguration")]
protected virtual Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
return Task.FromResult (0);
@@ -927,21 +1022,30 @@ namespace MonoDevelop.Projects
/// <param name="monitor">Monitor for tracking progress</param>
/// <param name="context">Execution context</param>
/// <param name="configuration">Configuration to execute</param>
+ /// <param name="runConfiguration">Run configuration to execute</param>
/// <remarks>This method can be called (it is not mandatory) before Execute() to give the target a chance
/// to asynchronously prepare the execution that is going to be done later on. It can be used for example
/// to start the simulator that is going to be used for execution. Calling this method is optional, and
/// there is no guarantee that Execute() will actually be called.</remarks>
+ protected virtual Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+#pragma warning disable 618 // Type or member is obsolete
+ return OnPrepareExecution (monitor, context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ [Obsolete ("Use overload that takes a RunConfiguration")]
protected virtual Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
return Task.FromResult (true);
}
- protected virtual bool DoGetCanExecute (ExecutionContext context, ConfigurationSelector configuration)
+ bool DoGetCanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
SolutionItemConfiguration conf = GetConfiguration (configuration) as SolutionItemConfiguration;
if (conf != null && conf.CustomCommands.HasCommands (CustomCommandType.Execute))
return conf.CustomCommands.CanExecute (this, CustomCommandType.Execute, context, configuration);
- return OnGetCanExecute (context, configuration);
+ return OnGetCanExecute (context, configuration, runConfiguration);
}
/// <summary>
@@ -956,6 +1060,17 @@ namespace MonoDevelop.Projects
/// <param name='configuration'>
/// Configuration to use to execute the item
/// </param>
+ /// <param name='runConfiguration'>
+ /// Run configuration to use to execute the item
+ /// </param>
+ protected virtual bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+#pragma warning disable 618 // Type or member is obsolete
+ return OnGetCanExecute (context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ [Obsolete ("Use overload that takes a RunConfiguration")]
protected virtual bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration)
{
SolutionItemConfiguration conf = GetConfiguration (configuration) as SolutionItemConfiguration;
@@ -971,10 +1086,32 @@ namespace MonoDevelop.Projects
/// <param name="configuration">The configuration.</param>
public IEnumerable<ExecutionTarget> GetExecutionTargets (ConfigurationSelector configuration)
{
+ return ItemExtension.OnGetExecutionTargets (new OperationContext (), configuration, GetDefaultRunConfiguration ());
+ }
+
+ /// <summary>
+ /// Gets the execution targets.
+ /// </summary>
+ /// <returns>The execution targets.</returns>
+ /// <param name="configuration">The configuration.</param>
+ public IEnumerable<ExecutionTarget> GetExecutionTargets (ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+ return ItemExtension.OnGetExecutionTargets (new OperationContext (), configuration, runConfiguration ?? GetDefaultRunConfiguration ());
+ }
+
+ IEnumerable<ExecutionTarget> IRunTarget.GetExecutionTargets (ConfigurationSelector configuration, RunConfiguration runConfiguration)
+ {
+ if (runConfiguration != null && !(runConfiguration is SolutionItemRunConfiguration))
+ throw new ArgumentException ("Invalid configuration type");
+ return GetExecutionTargets (configuration, (SolutionItemRunConfiguration)runConfiguration);
+ }
+
+ protected virtual IEnumerable<ExecutionTarget> OnGetExecutionTargets (ConfigurationSelector configuration, SolutionItemRunConfiguration runConfig)
+ {
return ItemExtension.OnGetExecutionTargets (configuration);
}
- protected void NotifyExecutionTargetsChanged ()
+ public void NotifyExecutionTargetsChanged ()
{
ItemExtension.OnExecutionTargetsChanged ();
}
@@ -987,6 +1124,49 @@ namespace MonoDevelop.Projects
ExecutionTargetsChanged (this, EventArgs.Empty);
}
+ /// <summary>
+ /// Gets the run configurations.
+ /// </summary>
+ /// <returns>The execution targets.</returns>
+ public IEnumerable<SolutionItemRunConfiguration> GetRunConfigurations ()
+ {
+ return ItemExtension.OnGetRunConfigurations (new OperationContext ());
+ }
+
+ IEnumerable<RunConfiguration> IRunTarget.GetRunConfigurations ()
+ {
+ return GetRunConfigurations ();
+ }
+
+ /// <summary>
+ /// Gets the default run configuration for this item.
+ /// </summary>
+ /// <returns>The configuration.</returns>
+ public SolutionItemRunConfiguration GetDefaultRunConfiguration ()
+ {
+ var configs = GetRunConfigurations ();
+ return configs.FirstOrDefault (s => s.IsDefaultConfiguration) ?? configs.FirstOrDefault ();
+ }
+
+ public void NotifyRunConfigurationsChanged ()
+ {
+ ItemExtension.OnRunConfigurationsChanged (new OperationContext ());
+ if (ParentSolution != null)
+ ParentSolution.NotifyRunConfigurationsChanged ();
+ }
+
+ protected virtual void OnRunConfigurationsChanged ()
+ {
+ if (RunConfigurationsChanged != null)
+ RunConfigurationsChanged (this, EventArgs.Empty);
+ }
+
+ protected virtual IEnumerable<SolutionItemRunConfiguration> OnGetRunConfigurations ()
+ {
+ yield break;
+ }
+
+
protected virtual Task OnLoad (ProgressMonitor monitor)
{
return Task.FromResult (0);
@@ -1358,19 +1538,19 @@ namespace MonoDevelop.Projects
return Item.OnGetSupportedFeatures ();
}
- internal protected override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ internal protected override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
- return Item.DoExecute (monitor, context, configuration);
+ return Item.DoExecute (monitor, context, configuration, runConfiguration);
}
- internal protected override Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ internal protected override Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
- return Item.OnPrepareExecution (monitor, context, configuration);
+ return Item.OnPrepareExecution (monitor, context, configuration, runConfiguration);
}
- internal protected override bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration)
+ internal protected override bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
- return Item.DoGetCanExecute (context, configuration);
+ return Item.DoGetCanExecute (context, configuration, runConfiguration);
}
internal protected override IEnumerable<ExecutionTarget> OnGetExecutionTargets (ConfigurationSelector configuration)
@@ -1378,11 +1558,26 @@ namespace MonoDevelop.Projects
yield break;
}
+ internal protected override IEnumerable<ExecutionTarget> OnGetExecutionTargets (OperationContext ctx, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfig)
+ {
+ return Item.OnGetExecutionTargets (configuration, runConfig);
+ }
+
internal protected override void OnExecutionTargetsChanged ()
{
Item.OnExecutionTargetsChanged ();
}
+ internal protected override IEnumerable<SolutionItemRunConfiguration> OnGetRunConfigurations (OperationContext ctx)
+ {
+ return Item.OnGetRunConfigurations ();
+ }
+
+ internal protected override void OnRunConfigurationsChanged (OperationContext ctx)
+ {
+ Item.OnRunConfigurationsChanged ();
+ }
+
internal protected override void OnReloadRequired (SolutionItemEventArgs args)
{
Item.DoOnReloadRequired (args);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs
index ee20bd4c5a..4f9e087975 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemExtension.cs
@@ -210,19 +210,46 @@ namespace MonoDevelop.Projects
#region Execution
+ [Obsolete ("Use overload that takes a RunConfiguration")]
internal protected virtual Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- return next.OnPrepareExecution (monitor, context, configuration);
+ return next.OnPrepareExecution (monitor, context, configuration, (SolutionItemRunConfiguration)context.RunConfiguration);
}
+ [Obsolete ("Use overload that takes a RunConfiguration")]
internal protected virtual Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
{
- return next.OnExecute (monitor, context, configuration);
+ return next.OnExecute (monitor, context, configuration, (SolutionItemRunConfiguration)context.RunConfiguration);
}
+ [Obsolete ("Use overload that takes a RunConfiguration")]
internal protected virtual bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration)
{
- return next.OnGetCanExecute (context, configuration);
+ return next.OnGetCanExecute (context, configuration, (SolutionItemRunConfiguration)context.RunConfiguration);
+ }
+
+ internal protected virtual Task OnPrepareExecution (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+ context.RunConfiguration = runConfiguration;
+#pragma warning disable 618 // Type or member is obsolete
+ return OnPrepareExecution (monitor, context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ internal protected virtual Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+ context.RunConfiguration = runConfiguration;
+#pragma warning disable 618 // Type or member is obsolete
+ return OnExecute (monitor, context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
+ }
+
+ internal protected virtual bool OnGetCanExecute (ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
+ {
+ context.RunConfiguration = runConfiguration;
+#pragma warning disable 618 // Type or member is obsolete
+ return OnGetCanExecute (context, configuration);
+#pragma warning restore 618 // Type or member is obsolete
}
internal protected virtual IEnumerable<ExecutionTarget> OnGetExecutionTargets (ConfigurationSelector configuration)
@@ -230,11 +257,26 @@ namespace MonoDevelop.Projects
return next.OnGetExecutionTargets (configuration);
}
+ internal protected virtual IEnumerable<ExecutionTarget> OnGetExecutionTargets (OperationContext ctx, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfig)
+ {
+ return next.OnGetExecutionTargets (ctx, configuration, runConfig);
+ }
+
internal protected virtual void OnExecutionTargetsChanged ()
{
next.OnExecutionTargetsChanged ();
}
+ internal protected virtual IEnumerable<SolutionItemRunConfiguration> OnGetRunConfigurations (OperationContext ctx)
+ {
+ return next.OnGetRunConfigurations (ctx);
+ }
+
+ internal protected virtual void OnRunConfigurationsChanged (OperationContext ctx)
+ {
+ next.OnRunConfigurationsChanged (ctx);
+ }
+
#endregion
#region Events
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemRunConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemRunConfiguration.cs
new file mode 100644
index 0000000000..4118baf8d4
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItemRunConfiguration.cs
@@ -0,0 +1,72 @@
+//
+// RunConfiguration.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using MonoDevelop.Core.Execution;
+
+namespace MonoDevelop.Projects
+{
+ public class SolutionItemRunConfiguration: RunConfiguration
+ {
+ string id;
+ string name;
+
+ public SolutionItemRunConfiguration (string id)
+ {
+ this.name = this.id = id;
+ }
+
+ public SolutionItemRunConfiguration (string id, string name)
+ {
+ this.id = id;
+ this.name = name;
+ }
+
+ public SolutionItem ParentItem {
+ get;
+ internal set;
+ }
+
+ public sealed override string Name {
+ get { return name; }
+ }
+
+ public sealed override string Id {
+ get { return id; }
+ }
+
+ public override string ToString ()
+ {
+ return Name;
+ }
+
+ public bool IsDefaultConfiguration {
+ get { return Id == "Default"; }
+ }
+
+ public ExecutionTarget ExecutionTarget { get; set; }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfiguration.cs
new file mode 100644
index 0000000000..1e0d693b37
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfiguration.cs
@@ -0,0 +1,66 @@
+//
+// SolutionRunConfiguration.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+namespace MonoDevelop.Projects
+{
+ public class SolutionRunConfiguration: RunConfiguration
+ {
+ string id;
+ string name;
+
+ public SolutionRunConfiguration (string id)
+ {
+ this.name = this.id = id;
+ }
+
+ public SolutionRunConfiguration (string id, string name)
+ {
+ this.id = id;
+ this.name = name;
+ }
+
+ internal Solution ParentSolution { get; set; }
+
+ public sealed override string Name {
+ get { return name; }
+ }
+
+ public sealed override string Id {
+ get { return id; }
+ }
+
+ protected void SetName (string name)
+ {
+ this.name = name;
+ }
+
+ public override string ToString ()
+ {
+ return Name;
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfigurationCollection.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfigurationCollection.cs
new file mode 100644
index 0000000000..3e7e6a3da2
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionRunConfigurationCollection.cs
@@ -0,0 +1,65 @@
+//
+// RunConfigurationCollection.cs
+//
+// Author:
+// Lluis Sanchez Gual <lluis@xamarin.com>
+//
+// Copyright (c) 2016 Xamarin, Inc (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Collections.Generic;
+
+namespace MonoDevelop.Projects
+{
+ public class SolutionRunConfigurationCollection: ItemCollection<SolutionRunConfiguration>
+ {
+ Solution parentSolution;
+
+ public SolutionRunConfigurationCollection ()
+ {
+ }
+
+ internal SolutionRunConfigurationCollection (Solution parentSolution)
+ {
+ this.parentSolution = parentSolution;
+ }
+
+ protected override void OnItemsAdded (IEnumerable<SolutionRunConfiguration> items)
+ {
+ if (parentSolution != null) {
+ foreach (var conf in items)
+ conf.ParentSolution = parentSolution;
+ }
+ base.OnItemsAdded (items);
+ parentSolution.OnRunConfigurationsAdded (items);
+ }
+
+ protected override void OnItemsRemoved (IEnumerable<SolutionRunConfiguration> items)
+ {
+ if (parentSolution != null) {
+ foreach (var conf in items)
+ conf.ParentSolution = null;
+ }
+ base.OnItemsRemoved (items);
+ parentSolution.OnRunConfigurationRemoved (items);
+ }
+ }
+}
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/UnknownProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/UnknownProject.cs
index e37bd6b611..77f9ae4bbc 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/UnknownProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/UnknownProject.cs
@@ -93,7 +93,7 @@ namespace MonoDevelop.Projects
return Task.FromResult (r);
}
- protected override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration)
+ protected override Task OnExecute (ProgressMonitor monitor, ExecutionContext context, ConfigurationSelector configuration, SolutionItemRunConfiguration runConfiguration)
{
return new Task (delegate {
});