From a2c688cdabf3e19598178ddca5dc88f875f45302 Mon Sep 17 00:00:00 2001 From: Lluis Sanchez Gual Date: Mon, 5 May 2014 20:43:47 +0200 Subject: Fix default startup project issue When a project is added to a solution, if that project supports execution and there no valid startup project for the solution, set the new project as startup. Added new SupportsExecute method for checking if a project supports execution or not. CanExcute can't be used to check that since this method depends on the configuration, target and other properties. Fixes 19502 - iOS project added to Shared Asset only solution cannot be compiled --- .../SharedAssetsProject.cs | 5 ++++ .../MonoDevelop.Projects/ProjectService.cs | 10 ++++++++ .../ProjectServiceExtension.cs | 28 ++++++++++++++++++++++ .../MonoDevelop.Projects/Solution.cs | 5 +++- .../MonoDevelop.Projects/SolutionItem.cs | 12 ++++++++++ .../MonoDevelop.Projects/WorkspaceItem.cs | 10 ++++++++ .../ConfigurationMerger.cs | 1 + .../SharedAssetsProjectTests.cs | 20 ++++++++++++++++ 8 files changed, 90 insertions(+), 1 deletion(-) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs index 281d3ef7cf..c56f52a198 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.SharedAssetsProjects/SharedAssetsProject.cs @@ -99,6 +99,11 @@ namespace MonoDevelop.Projects.SharedAssetsProjects return false; } + internal protected override bool OnGetSupportsExecute () + { + return false; + } + protected override void OnBoundToSolution () { if (currentSolution != null) { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs index 3b4b21a2e9..2679c9d0f4 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs @@ -709,6 +709,16 @@ namespace MonoDevelop.Projects throw new InvalidOperationException ("Unknown item type: " + item); } + public override bool SupportsExecute (IBuildTarget item) + { + if (item is WorkspaceItem) + return ((WorkspaceItem)item).OnGetSupportsExecute (); + else if (item is SolutionItem) + return ((SolutionItem)item).OnGetSupportsExecute (); + else + throw new InvalidOperationException ("Unknown item type: " + item); + } + public override void Execute (IProgressMonitor monitor, IBuildTarget item, ExecutionContext context, ConfigurationSelector configuration) { if (item is SolutionEntityItem) { diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectServiceExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectServiceExtension.cs index 245eb658c3..476081baf6 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectServiceExtension.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectServiceExtension.cs @@ -156,6 +156,34 @@ namespace MonoDevelop.Projects return GetNext (item).SupportsTarget ((IBuildTarget) item, target); } + public virtual bool SupportsExecute (IBuildTarget item) + { + if (item is SolutionEntityItem) + return SupportsExecute ((SolutionEntityItem)item); + else if (item is WorkspaceItem) + return SupportsExecute ((WorkspaceItem) item); + else + return GetNext (item).SupportsExecute (item); + } + + protected virtual bool SupportsExecute (SolutionEntityItem item) + { + return GetNext (item).SupportsExecute ((IBuildTarget) item); + } + + protected virtual bool SupportsExecute (Solution solution) + { + return GetNext (solution).SupportsExecute ((IBuildTarget) solution); + } + + protected virtual bool SupportsExecute (WorkspaceItem item) + { + if (item is Solution) + return SupportsExecute ((Solution) item); + else + return GetNext (item).SupportsExecute ((IBuildTarget) item); + } + protected virtual void Clean (IProgressMonitor monitor, IBuildTarget item, ConfigurationSelector configuration) { if (item is SolutionEntityItem) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs index 09f023d53c..af3754530c 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Solution.cs @@ -124,7 +124,7 @@ namespace MonoDevelop.Projects if (startupItem == null && singleStartup) { ReadOnlyCollection its = GetAllSolutionItems (); if (its.Count > 0) - startupItem = its [0]; + startupItem = its.FirstOrDefault (it => it.SupportsExecute ()); } return startupItem; } @@ -666,6 +666,9 @@ namespace MonoDevelop.Projects // Register the new entry in every solution configuration foreach (SolutionConfiguration conf in Configurations) conf.AddItem (eitem); + // If there is no startup project or it is an invalid one, use the new project as startup if possible + if ((StartupItem == null || !StartupItem.SupportsExecute ()) && eitem.SupportsExecute ()) + StartupItem = eitem; } else { // Reuse the configuration information of the replaced item foreach (SolutionConfiguration conf in Configurations) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs index 2bbab1c45e..dd9f434cdf 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs @@ -483,6 +483,11 @@ namespace MonoDevelop.Projects return SupportsTarget (ProjectService.BuildTarget); } + public bool SupportsExecute () + { + return Services.ProjectService.GetExtensionChain (this).SupportsExecute (this); + } + /// /// Cleans the files produced by this solution item /// @@ -664,6 +669,8 @@ namespace MonoDevelop.Projects /// public bool CanExecute (ExecutionContext context, ConfigurationSelector configuration) { + if (!SupportsExecute ()) + return false; return Services.ProjectService.GetExtensionChain (this).CanExecute (this, context, configuration); } @@ -1060,6 +1067,11 @@ namespace MonoDevelop.Projects return true; } + internal protected virtual bool OnGetSupportsExecute () + { + return true; + } + /// /// Determines whether this solution item can be executed using the specified context and configuration. /// diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs index c9f0169080..27fa88ae0c 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs @@ -267,6 +267,11 @@ namespace MonoDevelop.Projects return Services.ProjectService.GetExtensionChain (this).SupportsTarget (this, target); } + public bool SupportsExecute () + { + return Services.ProjectService.GetExtensionChain (this).SupportsExecute (this); + } + public BuildResult Build (IProgressMonitor monitor, string configuration) { return InternalBuild (monitor, (SolutionConfigurationSelector) configuration); @@ -421,6 +426,11 @@ namespace MonoDevelop.Projects return true; } + internal protected virtual bool OnGetSupportsExecute () + { + return true; + } + protected virtual void OnClean (IProgressMonitor monitor, ConfigurationSelector configuration) { } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ConfigurationMerger.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ConfigurationMerger.cs index d32eb80443..b111883203 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ConfigurationMerger.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.MainToolbar/ConfigurationMerger.cs @@ -126,6 +126,7 @@ namespace MonoDevelop.Components.MainToolbar // There is no startup project, just use all solution configurations in this case var p = new TargetPartition (); p.SolutionConfigurations.AddRange (sol.GetConfigurations ()); + partitions.Add (p); } // There can be several configurations with the same prefix and different platform but which build the same projects. diff --git a/main/tests/UnitTests/MonoDevelop.Projects/SharedAssetsProjectTests.cs b/main/tests/UnitTests/MonoDevelop.Projects/SharedAssetsProjectTests.cs index 871679f075..c4784267cc 100644 --- a/main/tests/UnitTests/MonoDevelop.Projects/SharedAssetsProjectTests.cs +++ b/main/tests/UnitTests/MonoDevelop.Projects/SharedAssetsProjectTests.cs @@ -263,6 +263,26 @@ namespace MonoDevelop.Projects Assert.AreEqual (refSharedProjectXml, sharedProjectXml); Assert.AreEqual (refSharedProjectItemsXml, sharedProjectItemsXml); } + + [Test] + public void SharedProjectCantBeStartup () + { + var sol = new Solution (); + var shared = new SharedAssetsProject (); + + // Shared projects are not executable + Assert.IsFalse (shared.SupportsExecute ()); + + sol.RootFolder.AddItem (shared); + + // The shared project is not executable, so it shouldn't be set as startup by default + Assert.IsNull (sol.StartupItem); + + // An executable project is set as startup by default when there is no startup project + DotNetAssemblyProject project = new DotNetAssemblyProject ("C#"); + sol.RootFolder.AddItem (project); + Assert.IsTrue (sol.StartupItem == project); + } } } -- cgit v1.2.3