Browse Source

New async-based API for the build engine.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
f42d52cfed
  1. 18
      src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestBuildProjectFactory.cs
  2. 6
      src/AddIns/Analysis/UnitTesting/Model/ITestProject.cs
  3. 5
      src/AddIns/Analysis/UnitTesting/Model/TestProjectBase.cs
  4. 2
      src/AddIns/Analysis/UnitTesting/Test/NUnit/CreateNUnitTestRunnerTestFixture.cs
  5. 17
      src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs
  6. 2
      src/AddIns/Analysis/UnitTesting/UnitTesting.csproj
  7. 16
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs
  8. 1
      src/AddIns/Misc/UsageDataCollector/UsageDataCollector/UsageDataSessionWriter.cs
  9. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  10. 22
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  11. 21
      src/Main/Base/Project/Project/Build/BuildDetection.cs
  12. 16
      src/Main/Base/Project/Project/Build/BuildError.cs
  13. 43
      src/Main/Base/Project/Project/Build/BuildEventArgs.cs
  14. 76
      src/Main/Base/Project/Project/Build/BuildOptions.cs
  15. 11
      src/Main/Base/Project/Project/Build/BuildOutputVerbosity.cs
  16. 41
      src/Main/Base/Project/Project/Build/BuildResults.cs
  17. 0
      src/Main/Base/Project/Project/Build/BuildTarget.cs
  18. 22
      src/Main/Base/Project/Project/Build/IBuildFeedbackSink.cs
  19. 77
      src/Main/Base/Project/Project/Build/IBuildService.cs
  20. 46
      src/Main/Base/Project/Project/Build/IBuildable.cs
  21. 13
      src/Main/Base/Project/Project/Build/MultipleProjectBuildable.cs
  22. 47
      src/Main/Base/Project/Project/Build/ProjectBuildOptions.cs
  23. 5
      src/Main/Base/Project/Services/SD.cs
  24. 76
      src/Main/Base/Project/Src/Commands/BuildCommands.cs
  25. 8
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptions.xaml.cs
  26. 2
      src/Main/Base/Project/Src/Gui/IProgressMonitor.cs
  27. 1
      src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs
  28. 16
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  29. 18
      src/Main/Base/Project/Src/Project/BeforeBuildCustomToolProjectItems.cs
  30. 2
      src/Main/Base/Project/Src/Project/BeforeBuildCustomToolRunner.cs
  31. 1
      src/Main/Base/Project/Src/Project/ConfigurationGuiHelper.cs
  32. 36
      src/Main/Base/Project/Src/Project/IProject.cs
  33. 14
      src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs
  34. 2
      src/Main/Base/Project/Src/Project/MSBuildEngine/BuildWorkerManager.cs
  35. 22
      src/Main/Base/Project/Src/Project/MSBuildEngine/MSBuildEngine.cs
  36. 6
      src/Main/Base/Project/Src/Project/MSBuildFileProject.cs
  37. 4
      src/Main/Base/Project/Src/Project/ProjectLoadInformation.cs
  38. 13
      src/Main/Base/Project/Src/Project/Solution/Solution.cs
  39. 84
      src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
  40. 48
      src/Main/Base/Test/Project/BeforeBuildCustomToolProjectItemsTests.cs
  41. 1
      src/Main/Core/Project/Src/Services/PropertyService/PropertyServiceImpl.cs
  42. 57
      src/Main/SharpDevelop/Project/Build/BuildEngine.cs
  43. 155
      src/Main/SharpDevelop/Project/Build/BuildModifiedProjectsOnlyService.cs
  44. 117
      src/Main/SharpDevelop/Project/Build/BuildService.cs
  45. 46
      src/Main/SharpDevelop/Project/Build/UIBuildFeedbackSink.cs
  46. 6
      src/Main/SharpDevelop/SharpDevelop.csproj

18
src/AddIns/Analysis/UnitTesting/Interfaces/UnitTestBuildProjectFactory.cs

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Commands;
namespace ICSharpCode.UnitTesting
{
public class UnitTestBuildProjectFactory : IBuildProjectFactory
{
public BuildProject CreateBuildProjectBeforeTestRun(IEnumerable<IBuildable> projects)
{
return new BuildProjectBeforeExecute(new MultipleProjectBuildable(projects));
}
}
}

6
src/AddIns/Analysis/UnitTesting/Model/ITestProject.cs

@ -28,11 +28,9 @@ namespace ICSharpCode.UnitTesting @@ -28,11 +28,9 @@ namespace ICSharpCode.UnitTesting
IEnumerable<ITest> GetTestsForEntity(IEntity entity);
/// <summary>
/// Returns a SharpDevelop <see cref="IBuildable"/> that builds the project
/// for test execution.
/// May return null if the project does not require compilation.
/// Gets whether the project needs to be compiled before the tests can be run.
/// </summary>
IBuildable GetBuildableForTesting();
bool IsBuildNeededBeforeTestRun { get; }
/// <summary>
/// Notifies the project that the parse information was changed.

5
src/AddIns/Analysis/UnitTesting/Model/TestProjectBase.cs

@ -57,9 +57,8 @@ namespace ICSharpCode.UnitTesting @@ -57,9 +57,8 @@ namespace ICSharpCode.UnitTesting
get { return project.Name; }
}
public virtual IBuildable GetBuildableForTesting()
{
return project;
public virtual bool IsBuildNeededBeforeTestRun {
get { return true; }
}
public override ImmutableStack<ITest> FindPathToDescendant(ITest test)

2
src/AddIns/Analysis/UnitTesting/Test/NUnit/CreateNUnitTestRunnerTestFixture.cs

@ -39,7 +39,7 @@ namespace UnitTesting.Tests.NUnit @@ -39,7 +39,7 @@ namespace UnitTesting.Tests.NUnit
[Test]
public void NUnitTestProjectBuildsTheProject()
{
Assert.AreSame(project, testProject.GetBuildableForTesting());
Assert.IsTrue(testProject.IsBuildNeededBeforeTestRun);
}
}
}

17
src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs

@ -23,7 +23,7 @@ namespace ICSharpCode.UnitTesting.Frameworks @@ -23,7 +23,7 @@ namespace ICSharpCode.UnitTesting.Frameworks
/// </summary>
public class TestExecutionManager
{
readonly IBuildProjectFactory buildProjectFactory;
readonly IBuildService buildService;
readonly IUnitTestTaskService taskService;
readonly IUnitTestSaveAllFilesCommand saveAllFilesCommand;
readonly ITestService testService;
@ -34,7 +34,7 @@ namespace ICSharpCode.UnitTesting.Frameworks @@ -34,7 +34,7 @@ namespace ICSharpCode.UnitTesting.Frameworks
public TestExecutionManager()
{
this.buildProjectFactory = new UnitTestBuildProjectFactory();
this.buildService = SD.BuildService;
this.taskService = new UnitTestTaskService();
this.saveAllFilesCommand = new UnitTestSaveAllFilesCommand();
this.testService = SD.GetRequiredService<ITestService>();
@ -62,12 +62,15 @@ namespace ICSharpCode.UnitTesting.Frameworks @@ -62,12 +62,15 @@ namespace ICSharpCode.UnitTesting.Frameworks
saveAllFilesCommand.SaveAllFiles();
// Run the build, if necessary:
var projectsToBuild = testsByProject.Keys.Select(p => p.GetBuildableForTesting()).Where(b => b != null).ToList();
var projectsToBuild = testsByProject.Keys.Where(p => p.IsBuildNeededBeforeTestRun).Select(p => p.Project).ToList();
if (projectsToBuild.Count > 0) {
var buildCommand = buildProjectFactory.CreateBuildProjectBeforeTestRun(projectsToBuild);
var buildResults = await buildCommand.BuildAsync(cancellationToken);
if (buildResults.Result != BuildResultCode.Success)
return;
using (cancellationToken.Register(buildService.CancelBuild)) {
var buildOptions = new BuildOptions(BuildTarget.Build);
buildOptions.BuildDetection = BuildOptions.BuildOnExecute;
var buildResults = await buildService.BuildAsync(projectsToBuild, buildOptions);
if (buildResults.Result != BuildResultCode.Success)
return;
}
}
cancellationToken.ThrowIfCancellationRequested();

2
src/AddIns/Analysis/UnitTesting/UnitTesting.csproj

@ -80,7 +80,6 @@ @@ -80,7 +80,6 @@
<Compile Include="Model\ITestSolution.cs" />
<Compile Include="Model\TestBase.cs" />
<Compile Include="Interfaces\IBuildOptions.cs" />
<Compile Include="Interfaces\IBuildProjectFactory.cs" />
<Compile Include="Interfaces\IFileSystem.cs" />
<Compile Include="Interfaces\IUnitTestDebuggerService.cs" />
<Compile Include="Interfaces\IUnitTestSaveAllFilesCommand.cs" />
@ -100,7 +99,6 @@ @@ -100,7 +99,6 @@
<Compile Include="Pad\TestTreeView.cs" />
<Compile Include="Pad\UnitTestNode.cs" />
<Compile Include="Pad\UnitTestsPad.cs" />
<Compile Include="Interfaces\UnitTestBuildProjectFactory.cs" />
<Compile Include="Interfaces\UnitTestDebuggerService.cs" />
<Compile Include="Interfaces\UnitTestFileService.cs" />
<Compile Include="Interfaces\UnitTestSaveAllFilesCommand.cs" />

16
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs

@ -7,9 +7,12 @@ using System.ComponentModel; @@ -7,9 +7,12 @@ using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Internal.Templates;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Converter;
@ -80,16 +83,15 @@ namespace CSharpBinding @@ -80,16 +83,15 @@ namespace CSharpBinding
InitializeProjectContent(new CSharpProjectContent());
}
public override void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink)
public override Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
if (this.MinimumSolutionVersion == Solution.SolutionVersionVS2005) {
MSBuildEngine.StartBuild(this,
options,
feedbackSink,
MSBuildEngine.AdditionalTargetFiles.Concat(
new [] { Path.Combine(MSBuildEngine.SharpDevelopBinPath, "SharpDevelop.CheckMSBuild35Features.targets") }));
return MSBuildEngine.BuildAsync(
this, options, feedbackSink, progressMonitor.CancellationToken,
MSBuildEngine.AdditionalTargetFiles.Concat(
new [] { Path.Combine(MSBuildEngine.SharpDevelopBinPath, "SharpDevelop.CheckMSBuild35Features.targets") }));
} else {
base.StartBuild(options, feedbackSink);
return base.BuildAsync(options, feedbackSink, progressMonitor);
}
}

1
src/AddIns/Misc/UsageDataCollector/UsageDataCollector/UsageDataSessionWriter.cs

@ -44,6 +44,7 @@ namespace ICSharpCode.UsageDataCollector @@ -44,6 +44,7 @@ namespace ICSharpCode.UsageDataCollector
SQLiteConnectionStringBuilder conn = new SQLiteConnectionStringBuilder();
conn.DataSource = databaseFileName;
Directory.CreateDirectory(Path.GetDirectoryName(databaseFileName));
connection = new SQLiteConnection(conn.ConnectionString);
connection.Open();
try {

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -70,6 +70,8 @@ @@ -70,6 +70,8 @@
class="ICSharpCode.SharpDevelop.Dom.ModelFactory"/>
<Service id="ICSharpCode.SharpDevelop.IClipboard"
class="ICSharpCode.SharpDevelop.ClipboardWrapper"/>
<Service id="ICSharpCode.SharpDevelop.Project.IBuildService"
class="ICSharpCode.SharpDevelop.Project.BuildService"/>
<Service id="ICSharpCode.SharpDevelop.WinForms.IWinFormsService"
class="ICSharpCode.SharpDevelop.WinForms.WinFormsService"/>

22
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -123,6 +123,18 @@ @@ -123,6 +123,18 @@
<Compile Include="Parser\ParseInformation.cs" />
<Compile Include="Parser\ParseInformationEventArgs.cs" />
<Compile Include="Parser\ProjectContentContainer.cs" />
<Compile Include="Project\Build\BuildDetection.cs" />
<Compile Include="Project\Build\BuildError.cs" />
<Compile Include="Project\Build\BuildEventArgs.cs" />
<Compile Include="Project\Build\BuildOptions.cs" />
<Compile Include="Project\Build\BuildOutputVerbosity.cs" />
<Compile Include="Project\Build\BuildResults.cs" />
<Compile Include="Project\Build\BuildTarget.cs" />
<Compile Include="Project\Build\IBuildable.cs" />
<Compile Include="Project\Build\IBuildFeedbackSink.cs" />
<Compile Include="Project\Build\IBuildService.cs" />
<Compile Include="Project\Build\MultipleProjectBuildable.cs" />
<Compile Include="Project\Build\ProjectBuildOptions.cs" />
<Compile Include="Services\IClipboard.cs" />
<Compile Include="Services\IMessageLoop.cs" />
<Compile Include="Services\SD.cs" />
@ -389,7 +401,6 @@ @@ -389,7 +401,6 @@
<Compile Include="Src\Project\Behaviors\ProjectBehaviorService.cs" />
<Compile Include="Src\Project\Behaviors\ProjectBehaviorSupportedConditionEvaluator.cs" />
<Compile Include="Src\Project\Behaviors\ResXConverter.cs" />
<Compile Include="Src\Project\BuildEngine.cs" />
<Compile Include="Src\Project\ContextSpecificProperties.cs" />
<Compile Include="Src\Project\Converter\IUpgradableProject.cs" />
<Compile Include="Src\Project\Converter\UpgradeView.xaml.cs">
@ -397,7 +408,6 @@ @@ -397,7 +408,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\Project\Converter\UpgradeViewContent.cs" />
<Compile Include="Src\Project\IBuildFeedbackSink.cs" />
<Compile Include="Src\Project\IProjectChangeWatcher.cs" />
<Compile Include="Src\Project\IProjectItemBackendStore.cs" />
<Compile Include="Src\Project\Items\ServiceReferenceProjectItem.cs" />
@ -411,7 +421,6 @@ @@ -411,7 +421,6 @@
<Compile Include="Src\Project\MSBuildEngine\WorkerProcess.cs" />
<Compile Include="Src\Project\MSBuildFileProject.cs" />
<Compile Include="Src\Project\MSBuildItemWrapper.cs" />
<Compile Include="Src\Project\MultipleProjectBuildable.cs" />
<Compile Include="Src\Project\PortableLibrary\CheckPortableLibraryInstalled.cs" />
<Compile Include="Src\Project\PortableLibrary\ConvertToPortableLibraryProjectBehavior.cs" />
<Compile Include="Src\Project\PortableLibrary\PickPortableTargetFramework.cs" />
@ -460,7 +469,6 @@ @@ -460,7 +469,6 @@
<Compile Include="Src\Internal\Doozers\IOptionPanelDescriptor.cs" />
<Compile Include="Workbench\File\FileEventArgs.cs" />
<Compile Include="Src\Services\MimeTypeDetection.cs" />
<Compile Include="Src\Services\ProjectService\CompileModifiedProjectsOnly.cs" />
<Compile Include="Src\Services\ProjectService\SolutionConfigurationEventHandler.cs" />
<Compile Include="Src\Services\RefactoringService\ExtractInterfaceOptions.cs" />
<Compile Include="Src\Services\RefactoringService\FindReferenceService.cs" />
@ -777,8 +785,6 @@ @@ -777,8 +785,6 @@
<Compile Include="Src\Services\NavigationService\NavigationService.cs" />
<Compile Include="Src\Commands\NavigationCommands.cs" />
<Compile Include="Src\Internal\ConditionEvaluators\NavigationConditionEvaluators.cs" />
<Compile Include="Src\Project\BuildResults.cs" />
<Compile Include="Src\Project\BuildError.cs" />
<Compile Include="Src\Services\HelpProvider.cs" />
<Compile Include="Src\Services\ParserService\CodeCompletionOptions.cs" />
<Compile Include="Src\Internal\ConditionEvaluators\CompareProjectPropertyConditionEvaluator.cs" />
@ -797,13 +803,11 @@ @@ -797,13 +803,11 @@
<Compile Include="Src\Project\MSBuildBasedProject.cs" />
<Compile Include="Src\Project\MSBuildItemDefinitionGroup.cs" />
<Compile Include="Src\Project\AbstractProject.cs" />
<Compile Include="Src\Project\BuildOptions.cs" />
<Compile Include="Src\Project\CompilableProject.cs" />
<Compile Include="Src\Project\MSBuildInternals.cs" />
<Compile Include="Src\Util\ScrollUtils.cs" />
<Compile Include="Src\Util\ReadOnlyCollectionWrapper.cs" />
<Compile Include="Src\Project\Items\ItemType.cs" />
<Compile Include="Src\Project\BuildTarget.cs" />
<Compile Include="Src\Util\GenericConverter.cs" />
<Compile Include="Src\Internal\Templates\TemplateLoadException.cs" />
<Compile Include="Src\Util\UnclosableStream.cs" />
@ -867,7 +871,9 @@ @@ -867,7 +871,9 @@
</ProjectReference>
<Folder Include="Dom" />
<Folder Include="Editor" />
<Folder Include="Project" />
<Folder Include="Parser" />
<Folder Include="Project\Build" />
<Folder Include="Services" />
<Folder Include="WinForms" />
<Folder Include="Workbench" />

21
src/Main/Base/Project/Project/Build/BuildDetection.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.ComponentModel;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Project
{
public enum BuildDetection
{
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.DoNotBuild}")]
DoNotBuild,
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.BuildOnlyModified}")]
BuildOnlyModified,
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.BuildModifiedAndDependent}")]
BuildModifiedAndDependent,
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.RegularBuild}")]
RegularBuild
}
}

16
src/Main/Base/Project/Src/Project/BuildError.cs → src/Main/Base/Project/Project/Build/BuildError.cs

@ -42,7 +42,8 @@ namespace ICSharpCode.SharpDevelop.Project @@ -42,7 +42,8 @@ namespace ICSharpCode.SharpDevelop.Project
string errorText;
string fileName;
int line;
bool warning;
bool isWarning;
bool isMessage;
[NonSerialized]
object tag;
string contextMenuAddInTreeEntry;
@ -105,12 +106,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -105,12 +106,13 @@ namespace ICSharpCode.SharpDevelop.Project
}
public bool IsWarning {
get {
return warning;
}
set {
warning = value;
}
get { return isWarning; }
set { isWarning = value; }
}
public bool IsMessage {
get { return isMessage; }
set { isMessage = value; }
}
/// <summary>

43
src/Main/Base/Project/Project/Build/BuildEventArgs.cs

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Project
{
public class BuildEventArgs : EventArgs
{
/// <summary>
/// The projects to be built.
/// </summary>
public readonly IReadOnlyList<IProject> Projects;
/// <summary>
/// The build options.
/// </summary>
public readonly BuildOptions Options;
/// <summary>
/// Gets the build results.
/// This property is null for build started events.
/// </summary>
public readonly BuildResults Results;
public BuildEventArgs(IReadOnlyList<IProject> projects, BuildOptions options)
: this(projects, options, null)
{
}
public BuildEventArgs(IReadOnlyList<IProject> projects, BuildOptions options, BuildResults results)
{
if (projects == null)
throw new ArgumentNullException("projects");
if (options == null)
throw new ArgumentNullException("options");
this.Projects = projects;
this.Options = options;
this.Results = results;
}
}
}

76
src/Main/Base/Project/Src/Project/BuildOptions.cs → src/Main/Base/Project/Project/Build/BuildOptions.cs

@ -4,60 +4,15 @@ @@ -4,60 +4,15 @@
using System;
using System.Collections.Generic;
using ICSharpCode.Core;
using Microsoft.Build.Framework;
namespace ICSharpCode.SharpDevelop.Project
{
public delegate void BuildCallback(BuildResults results);
/// <summary>
/// Specifies options for building a single project.
/// </summary>
public class ProjectBuildOptions
{
BuildTarget target;
IDictionary<string, string> properties = new SortedList<string, string>();
public BuildTarget Target {
get { return target; }
}
public IDictionary<string, string> Properties {
get { return properties; }
}
public ProjectBuildOptions(BuildTarget target)
{
this.target = target;
}
/// <summary>
/// Specifies the project configuration used for the build.
/// </summary>
public string Configuration { get; set; }
/// <summary>
/// Specifies the project platform used for the build.
/// </summary>
public string Platform { get; set; }
/// <summary>
/// Gets/Sets the verbosity of build output.
/// </summary>
public BuildOutputVerbosity BuildOutputVerbosity { get; set; }
}
public enum BuildOutputVerbosity
{
Normal,
Diagnostic
}
/// <summary>
/// Specifies options when starting a build.
/// </summary>
public class BuildOptions
{
#region static settings
public static bool ShowErrorListAfterBuild {
get {
return PropertyService.Get("SharpDevelop.ShowErrorListAfterBuild", true);
@ -76,6 +31,15 @@ namespace ICSharpCode.SharpDevelop.Project @@ -76,6 +31,15 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
public static BuildDetection BuildOnExecute {
get {
return PropertyService.Get("SharpDevelop.BuildOnExecute", BuildDetection.RegularBuild);
}
set {
PropertyService.Set("SharpDevelop.BuildOnExecute", value);
}
}
public static BuildOutputVerbosity DefaultBuildOutputVerbosity {
get {
return PropertyService.Get("SharpDevelop.DefaultBuildOutputVerbosity", BuildOutputVerbosity.Normal);
@ -84,6 +48,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -84,6 +48,7 @@ namespace ICSharpCode.SharpDevelop.Project
PropertyService.Set("SharpDevelop.DefaultBuildOutputVerbosity", value);
}
}
#endregion
IDictionary<string, string> globalAdditionalProperties = new SortedList<string, string>();
IDictionary<string, string> projectAdditionalProperties = new SortedList<string, string>();
@ -113,24 +78,21 @@ namespace ICSharpCode.SharpDevelop.Project @@ -113,24 +78,21 @@ namespace ICSharpCode.SharpDevelop.Project
/// </summary>
public BuildOutputVerbosity BuildOutputVerbosity { get; set; }
public BuildOptions(BuildTarget target, BuildCallback callback)
/// <summary>
/// Gets/Sets whether to build all projects or only modified ones.
/// The default is to build all projects.
/// </summary>
public BuildDetection BuildDetection { get; set; }
public BuildOptions(BuildTarget target)
{
this.callback = callback;
this.projectTarget = target;
this.TargetForDependencies = target;
this.BuildDependentProjects = true;
this.ParallelProjectCount = DefaultParallelProjectCount;
this.BuildOutputVerbosity = DefaultBuildOutputVerbosity;
}
readonly BuildCallback callback;
/// <summary>
/// Gets the method to call when the build has finished.
/// </summary>
public BuildCallback Callback {
get { return callback; }
this.BuildDetection = BuildDetection.RegularBuild;
}
readonly BuildTarget projectTarget;

11
src/AddIns/Analysis/UnitTesting/Interfaces/IBuildProjectFactory.cs → src/Main/Base/Project/Project/Build/BuildOutputVerbosity.cs

@ -3,13 +3,14 @@ @@ -3,13 +3,14 @@
using System;
using System.Collections.Generic;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Commands;
namespace ICSharpCode.UnitTesting
namespace ICSharpCode.SharpDevelop.Project
{
public interface IBuildProjectFactory
public enum BuildOutputVerbosity
{
BuildProject CreateBuildProjectBeforeTestRun(IEnumerable<IBuildable> projects);
Normal,
Diagnostic
}
}

41
src/Main/Base/Project/Src/Project/BuildResults.cs → src/Main/Base/Project/Project/Build/BuildResults.cs

@ -30,11 +30,8 @@ namespace ICSharpCode.SharpDevelop.Project @@ -30,11 +30,8 @@ namespace ICSharpCode.SharpDevelop.Project
List<BuildError> errors = new List<BuildError>();
ReadOnlyCollection<BuildError> readOnlyErrors;
List<IBuildable> builtProjects = new List<IBuildable>();
ReadOnlyCollection<IBuildable> readOnlyBuiltProjects;
BuildResultCode result;
int errorCount, warningCount;
int errorCount, warningCount, messageCount;
/// <summary>
/// Adds a build error/warning to the results.
@ -47,27 +44,15 @@ namespace ICSharpCode.SharpDevelop.Project @@ -47,27 +44,15 @@ namespace ICSharpCode.SharpDevelop.Project
lock (errors) {
readOnlyErrors = null;
errors.Add(error);
if (error.IsWarning)
if (error.IsMessage)
messageCount++;
else if (error.IsWarning)
warningCount++;
else
errorCount++;
}
}
/// <summary>
/// Adds a project to the list of built projects.
/// This method is thread-safe.
/// </summary>
public void AddBuiltProject(IBuildable buildable)
{
if (buildable == null)
throw new ArgumentNullException("buildable");
lock (builtProjects) {
readOnlyBuiltProjects = null;
builtProjects.Add(buildable);
}
}
/// <summary>
/// Gets the list of build errors or warnings.
/// This property is thread-safe.
@ -83,20 +68,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -83,20 +68,6 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
/// <summary>
/// Gets the list of projects that were built. This property is thread-safe.
/// </summary>
public ReadOnlyCollection<IBuildable> BuiltProjects {
get {
lock (builtProjects) {
if (readOnlyBuiltProjects == null) {
readOnlyBuiltProjects = Array.AsReadOnly(builtProjects.ToArray());
}
return readOnlyBuiltProjects;
}
}
}
public BuildResultCode Result {
get { return result; }
set { result = value; }
@ -109,5 +80,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -109,5 +80,9 @@ namespace ICSharpCode.SharpDevelop.Project
public int WarningCount {
get { return warningCount; }
}
public int MessageCount {
get { return messageCount; }
}
}
}

0
src/Main/Base/Project/Src/Project/BuildTarget.cs → src/Main/Base/Project/Project/Build/BuildTarget.cs

22
src/Main/Base/Project/Src/Project/IBuildFeedbackSink.cs → src/Main/Base/Project/Project/Build/IBuildFeedbackSink.cs

@ -7,19 +7,16 @@ namespace ICSharpCode.SharpDevelop.Project @@ -7,19 +7,16 @@ namespace ICSharpCode.SharpDevelop.Project
{
/// <summary>
/// Interface for reporting build results in real-time.
/// Project-specific build engines use this interface to report results to the main build engine.
/// </summary>
/// <remarks>
/// Implementations of this interface must be thread-safe.
/// Project-specific build engines use this interface to report results to the main build engine,
/// and the main build engine uses this interface to report the combined results to the IDE.
/// </remarks>
public interface IBuildFeedbackSink
{
/// <summary>
/// Gets the progress monitor associated with this build.
/// Does not return null.
/// This member is thread-safe.
/// </summary>
Gui.IProgressMonitor ProgressMonitor { get; }
/// <summary>
/// Reports an build error by adding it to the error list.
/// Reports an build error/warning/message by adding it to the error list.
/// This member is thread-safe.
/// </summary>
void ReportError(BuildError error);
@ -29,12 +26,5 @@ namespace ICSharpCode.SharpDevelop.Project @@ -29,12 +26,5 @@ namespace ICSharpCode.SharpDevelop.Project
/// This member is thread-safe.
/// </summary>
void ReportMessage(string message);
/// <summary>
/// Notifies the build engine that the build of a project has finished.
/// You should not call any methods after the Done() call.
/// This member is thread-safe.
/// </summary>
void Done(bool success);
}
}

77
src/Main/Base/Project/Project/Build/IBuildService.cs

@ -0,0 +1,77 @@ @@ -0,0 +1,77 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Project
{
/// <summary>
/// The service interface for accessing the build engine.
/// The build engine is responsible for constructing a dependency graph
/// between the <see cref="IBuildable"/>s, performing a topological sort
/// and scheduling the actual build.
/// </summary>
[SDService]
public interface IBuildService
{
/// <summary>
/// Builds the specified projects.
/// If tests are already running, the existing run is cancelled.
/// </summary>
/// <remarks>
/// The build progress will be shown in the SharpDevelop UI;
/// and the build can be cancelled by the user.
/// This method can only be used on the main thread.
/// </remarks>
Task<BuildResults> BuildAsync(IEnumerable<IProject> projects, BuildOptions options);
Task<BuildResults> BuildAsync(IProject project, BuildOptions options);
Task<BuildResults> BuildAsync(Solution solution, BuildOptions options);
/// <summary>
/// Raised when a build is started.
/// </summary>
/// <remarks>This event always occurs on the main thread.</remarks>
event EventHandler<BuildEventArgs> BuildStarted;
/// <summary>
/// Raised when a build is finished.
/// </summary>
/// <remarks>This event always occurs on the main thread.</remarks>
event EventHandler<BuildEventArgs> BuildFinished;
/// <summary>
/// Gets whether a build is currently running.
/// </summary>
bool IsBuilding { get; }
/// <summary>
/// Aborts the current build.
/// This method has no effect if no build is running.
/// </summary>
void CancelBuild();
/// <summary>
/// Performs a build in the background (not visible in the UI).
/// </summary>
/// <param name="buildable">The root buildable</param>
/// <param name="options">The build options that should be used</param>
/// <param name="buildFeedbackSink">The build feedback sink that receives the build output.</param>
/// <param name="progressMonitor">Progress monitor used to report progress about this build.</param>
/// <remarks>
/// This method does not set <see cref="IsBuilding"/> and cannot be cancelled using
/// <see cref="CancelBuild()"/>.
/// Cancellation is possible using the progress monitor's cancellation token, but
/// will not cause an <see cref="TaskCanceledException"/> - instead, the build results
/// will use <c>BuildResultCode.Cancelled</c>.
/// It does not raise the <see cref="BuildStarted"/>/<see cref="BuildFinished"/> events.
/// This method is thread-safe, and multiple background builds can run concurrently.
/// </remarks>
Task<BuildResults> BuildInBackgroundAsync(IBuildable buildable, BuildOptions options, IBuildFeedbackSink buildFeedbackSink, IProgressMonitor progressMonitor);
}
}

46
src/Main/Base/Project/Project/Build/IBuildable.cs

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Project
{
/// <summary>
/// A project or solution.
/// The IBuildable interface members are thread-safe.
/// </summary>
public interface IBuildable
{
/// <summary>
/// Gets the list of projects on which this project depends.
/// This method is thread-safe.
/// </summary>
IEnumerable<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions);
/// <summary>
/// Starts building the project using the specified options.
/// This member must be implemented thread-safe.
/// </summary>
Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor);
/// <summary>
/// Gets the name of the buildable item.
/// This property is thread-safe.
/// </summary>
string Name { get; }
/// <summary>
/// Creates the project-specific build options.
/// This member must be implemented thread-safe.
/// </summary>
/// <param name="options">The global build options.</param>
/// <param name="isRootBuildable">Specifies whether this project is the main buildable item.
/// The root buildable is the buildable for which <see cref="BuildOptions.ProjectTarget"/> and <see cref="BuildOptions.ProjectAdditionalProperties"/> apply.
/// The dependencies of that root buildable are the non-root buildables.</param>
/// <returns>The project-specific build options.</returns>
ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable);
}
}

13
src/Main/Base/Project/Src/Project/MultipleProjectBuildable.cs → src/Main/Base/Project/Project/Build/MultipleProjectBuildable.cs

@ -4,6 +4,9 @@ @@ -4,6 +4,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop.Project
@ -24,19 +27,15 @@ namespace ICSharpCode.SharpDevelop.Project @@ -24,19 +27,15 @@ namespace ICSharpCode.SharpDevelop.Project
get { return string.Empty; }
}
public Solution ParentSolution {
get { return projects.Length > 0 ? projects[0].ParentSolution : null; }
}
public ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
public IEnumerable<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
{
return projects;
}
public void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink)
public Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
// SharpDevelop already has built our dependencies, so we're done immediately.
feedbackSink.Done(true);
return Task.FromResult(true);
}
public ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable)

47
src/Main/Base/Project/Project/Build/ProjectBuildOptions.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Project
{
/// <summary>
/// Specifies options for building a single project.
/// </summary>
public class ProjectBuildOptions
{
BuildTarget target;
IDictionary<string, string> properties = new SortedList<string, string>();
public BuildTarget Target {
get { return target; }
}
public IDictionary<string, string> Properties {
get { return properties; }
}
public ProjectBuildOptions(BuildTarget target)
{
this.target = target;
}
/// <summary>
/// Specifies the project configuration used for the build.
/// </summary>
public string Configuration { get; set; }
/// <summary>
/// Specifies the project platform used for the build.
/// </summary>
public string Platform { get; set; }
/// <summary>
/// Gets/Sets the verbosity of build output.
/// </summary>
public BuildOutputVerbosity BuildOutputVerbosity { get; set; }
}
}

5
src/Main/Base/Project/Services/SD.cs

@ -11,6 +11,7 @@ using ICSharpCode.SharpDevelop.Dom; @@ -11,6 +11,7 @@ using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.WinForms;
using ICSharpCode.SharpDevelop.Workbench;
@ -174,5 +175,9 @@ namespace ICSharpCode.SharpDevelop @@ -174,5 +175,9 @@ namespace ICSharpCode.SharpDevelop
public static IWinFormsService WinForms {
get { return GetRequiredService<IWinFormsService>(); }
}
public static IBuildService BuildService {
get { return GetRequiredService<IBuildService>(); }
}
}
}

76
src/Main/Base/Project/Src/Commands/BuildCommands.cs

@ -25,9 +25,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -25,9 +25,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
public virtual void BeforeBuild()
{
TaskService.BuildMessageViewCategory.ClearText();
TaskService.InUpdate = true;
TaskService.ClearExceptCommentTasks();
TaskService.InUpdate = false;
ICSharpCode.SharpDevelop.Commands.SaveAllFiles.SaveAll();
}
@ -77,26 +75,6 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -77,26 +75,6 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
}
}
public Task<BuildResults> BuildAsync(CancellationToken cancellationToken)
{
var registration = cancellationToken.Register(BuildEngine.CancelGuiBuild, true);
var tcs = new TaskCompletionSource<BuildResults>();
this.BuildComplete += delegate {
registration.Dispose();
if (cancellationToken.IsCancellationRequested)
tcs.TrySetCanceled();
else
tcs.TrySetResult(this.LastBuildResults);
};
try {
StartBuild();
} catch (Exception ex) {
registration.Dispose();
tcs.TrySetException(ex);
}
return tcs.Task;
}
/// <summary>
/// Notifies the user that #develp's internal MSBuildEngine
/// implementation only supports compiling solutions and projects;
@ -113,9 +91,9 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -113,9 +91,9 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
public class Build : AbstractBuildMenuCommand
{
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Build, CallbackMethod));
CallbackMethod(await SD.BuildService.BuildAsync(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Build)));
}
}
@ -123,7 +101,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -123,7 +101,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
{
public override void Run()
{
if (BuildModifiedProjectsOnlyService.Setting == BuildOnExecuteSetting.DoNotBuild) {
if (BuildOptions.BuildOnExecute == BuildDetection.DoNotBuild) {
LastBuildResults = new BuildResults { Result = BuildResultCode.Success };
OnBuildComplete(EventArgs.Empty);
} else {
@ -131,22 +109,22 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -131,22 +109,22 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
}
}
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(BuildModifiedProjectsOnlyService.WrapBuildable(ProjectService.OpenSolution),
new BuildOptions(BuildTarget.Build, CallbackMethod));
var options = new BuildOptions(BuildTarget.Build) { BuildDetection = BuildOptions.BuildOnExecute };
CallbackMethod(await SD.BuildService.BuildAsync(ProjectService.OpenSolution, options));
}
}
public class BuildProjectBeforeExecute : BuildProject
{
public BuildProjectBeforeExecute(IBuildable project) : base(project)
public BuildProjectBeforeExecute(IProject project) : base(project)
{
}
public override void Run()
{
if (BuildModifiedProjectsOnlyService.Setting == BuildOnExecuteSetting.DoNotBuild) {
if (BuildOptions.BuildOnExecute == BuildDetection.DoNotBuild) {
LastBuildResults = new BuildResults { Result = BuildResultCode.Success };
OnBuildComplete(EventArgs.Empty);
} else {
@ -154,33 +132,33 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -154,33 +132,33 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
}
}
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(BuildModifiedProjectsOnlyService.WrapBuildable(this.ProjectToBuild),
new BuildOptions(BuildTarget.Build, CallbackMethod));
var options = new BuildOptions(BuildTarget.Build) { BuildDetection = BuildOptions.BuildOnExecute };
CallbackMethod(await SD.BuildService.BuildAsync(this.ProjectToBuild, options));
}
}
public class Rebuild : Build
{
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Rebuild, CallbackMethod));
CallbackMethod(await SD.BuildService.BuildAsync(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Rebuild)));
}
}
public class Clean : AbstractBuildMenuCommand
{
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Clean, CallbackMethod));
CallbackMethod(await SD.BuildService.BuildAsync(ProjectService.OpenSolution, new BuildOptions(BuildTarget.Clean)));
}
}
public abstract class AbstractProjectBuildMenuCommand : AbstractBuildMenuCommand
{
protected IBuildable targetProject;
protected IBuildable ProjectToBuild {
protected IProject targetProject;
protected IProject ProjectToBuild {
get {
return targetProject ?? ProjectService.CurrentProject;
}
@ -197,33 +175,33 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -197,33 +175,33 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
public BuildProject()
{
}
public BuildProject(IBuildable targetProject)
public BuildProject(IProject targetProject)
{
this.targetProject = targetProject;
}
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(this.ProjectToBuild, new BuildOptions(BuildTarget.Build, CallbackMethod));
CallbackMethod(await SD.BuildService.BuildAsync(this.ProjectToBuild, new BuildOptions(BuildTarget.Build)));
}
}
public class RebuildProject : BuildProject
{
public RebuildProject() {}
public RebuildProject(IBuildable targetProject) : base(targetProject) {}
public RebuildProject(IProject targetProject) : base(targetProject) {}
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(this.ProjectToBuild, new BuildOptions(BuildTarget.Rebuild, CallbackMethod));
CallbackMethod(await SD.BuildService.BuildAsync(this.ProjectToBuild, new BuildOptions(BuildTarget.Rebuild)));
}
}
public class CleanProject : AbstractProjectBuildMenuCommand
{
public override void StartBuild()
public override async void StartBuild()
{
BuildEngine.BuildInGui(this.ProjectToBuild, new BuildOptions(BuildTarget.Clean, CallbackMethod));
CallbackMethod(await SD.BuildService.BuildAsync(this.ProjectToBuild, new BuildOptions(BuildTarget.Clean)));
}
}
@ -231,11 +209,11 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -231,11 +209,11 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
{
public override void Run()
{
BuildEngine.CancelGuiBuild();
SD.BuildService.CancelBuild();
}
public override bool IsEnabled {
get { return BuildEngine.IsGuiBuildRunning; }
get { return SD.BuildService.IsBuilding; }
set { }
}
}

8
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/ProjectAndSolutionOptions.xaml.cs

@ -17,13 +17,13 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -17,13 +17,13 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
InitializeComponent();
FillComboBoxWithEnumValues(typeof(Project.BuildOnExecuteSetting), onExecuteComboBox);
FillComboBoxWithEnumValues(typeof(Project.BuildDetection), onExecuteComboBox);
FillComboBoxWithEnumValues(typeof(Project.BuildOutputVerbosity), verbosityComboBox);
}
void FillComboBoxWithEnumValues(Type type, ComboBox comboBox)
{
foreach (Project.BuildOnExecuteSetting element in Enum.GetValues(type)) {
foreach (Project.BuildDetection element in Enum.GetValues(type)) {
object[] attr = type.GetField(Enum.GetName(type, element)).GetCustomAttributes(typeof(DescriptionAttribute), false);
string description;
if (attr.Length > 0) {
@ -48,7 +48,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -48,7 +48,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
base.LoadOptions();
parallelBuildCount.Value = Project.BuildOptions.DefaultParallelProjectCount;
onExecuteComboBox.SelectedIndex = (int)Project.BuildModifiedProjectsOnlyService.Setting;
onExecuteComboBox.SelectedIndex = (int)Project.BuildOptions.BuildOnExecute;
verbosityComboBox.SelectedIndex = (int)Project.BuildOptions.DefaultBuildOutputVerbosity;
}
@ -63,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels @@ -63,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
}
}
Project.BuildOptions.DefaultParallelProjectCount = (int)parallelBuildCount.Value;
Project.BuildModifiedProjectsOnlyService.Setting = (Project.BuildOnExecuteSetting)onExecuteComboBox.SelectedIndex;
Project.BuildOptions.BuildOnExecute = (Project.BuildDetection)onExecuteComboBox.SelectedIndex;
Project.BuildOptions.DefaultBuildOutputVerbosity = (Project.BuildOutputVerbosity)verbosityComboBox.SelectedIndex;
return base.SaveOptions();
}

2
src/Main/Base/Project/Src/Gui/IProgressMonitor.cs

@ -7,7 +7,7 @@ using System.ComponentModel; @@ -7,7 +7,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
namespace ICSharpCode.SharpDevelop.Gui
namespace ICSharpCode.SharpDevelop
{
/// <summary>
/// Represents a target where an active task reports progress to.

1
src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs

@ -74,7 +74,6 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -74,7 +74,6 @@ namespace ICSharpCode.SharpDevelop.Gui
TaskService.Initialize();
Bookmarks.BookmarkManager.Initialize();
Project.CustomToolsService.Initialize();
Project.BuildModifiedProjectsOnlyService.Initialize();
workbench.Initialize();
workbench.SetMemento(PropertyService.NestedProperties(workbenchMemento));

16
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -10,6 +10,7 @@ using System.IO; @@ -10,6 +10,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
@ -495,14 +496,14 @@ namespace ICSharpCode.SharpDevelop.Project @@ -495,14 +496,14 @@ namespace ICSharpCode.SharpDevelop.Project
return referenceItems;
}
public virtual void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink)
public virtual Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
feedbackSink.ReportError(new BuildError { ErrorText = "Building project " + Name + " is not supported.", IsWarning = true });
// we don't know how to build anything, report that we're done.
feedbackSink.Done(true);
return Task.FromResult(true);
}
public virtual ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
public virtual IEnumerable<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
{
lock (SyncRoot) {
List<IBuildable> result = new List<IBuildable>();
@ -525,8 +526,11 @@ namespace ICSharpCode.SharpDevelop.Project @@ -525,8 +526,11 @@ namespace ICSharpCode.SharpDevelop.Project
{
if (options == null)
throw new ArgumentNullException("options");
string solutionConfiguration = options.SolutionConfiguration ?? ParentSolution.Preferences.ActiveConfiguration;
string solutionPlatform = options.SolutionPlatform ?? ParentSolution.Preferences.ActivePlatform;
// start of default implementation
var configMatchings = this.ParentSolution.GetActiveConfigurationsAndPlatformsForProjects(options.SolutionConfiguration, options.SolutionPlatform);
var configMatchings = this.ParentSolution.GetActiveConfigurationsAndPlatformsForProjects(solutionConfiguration, solutionPlatform);
ProjectBuildOptions projectOptions = new ProjectBuildOptions(isRootBuildable ? options.ProjectTarget : options.TargetForDependencies);
projectOptions.BuildOutputVerbosity = options.BuildOutputVerbosity;
// find the project configuration
@ -538,9 +542,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -538,9 +542,9 @@ namespace ICSharpCode.SharpDevelop.Project
}
// fall back to solution config if we don't find any entries for the project
if (string.IsNullOrEmpty(projectOptions.Configuration))
projectOptions.Configuration = options.SolutionConfiguration;
projectOptions.Configuration = solutionConfiguration;
if (string.IsNullOrEmpty(projectOptions.Platform))
projectOptions.Platform = options.SolutionPlatform;
projectOptions.Platform = solutionPlatform;
// copy global properties to project options
foreach (var pair in options.GlobalAdditionalProperties)

18
src/Main/Base/Project/Src/Project/BeforeBuildCustomToolProjectItems.cs

@ -10,11 +10,11 @@ namespace ICSharpCode.SharpDevelop.Project @@ -10,11 +10,11 @@ namespace ICSharpCode.SharpDevelop.Project
{
public class BeforeBuildCustomToolProjectItems
{
IBuildable buildable;
IReadOnlyList<IProject> projects;
public BeforeBuildCustomToolProjectItems(IBuildable buildable)
public BeforeBuildCustomToolProjectItems(IReadOnlyList<IProject> projects)
{
this.buildable = buildable;
this.projects = projects;
}
public IEnumerable<FileProjectItem> GetProjectItems()
@ -26,17 +26,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -26,17 +26,7 @@ namespace ICSharpCode.SharpDevelop.Project
IEnumerable<IProject> GetProjects()
{
IProject project = buildable as IProject;
if (project != null) {
return new IProject[] { project };
}
var solution = buildable as Solution;
if (solution != null) {
return solution.Projects;
}
return new IProject[0];
return projects;
}
IEnumerable<FileProjectItem> GetConfiguredCustomToolProjectItems(IProject project)

2
src/Main/Base/Project/Src/Project/BeforeBuildCustomToolRunner.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Project
void ProjectBuildStarted(object sender, BuildEventArgs e)
{
var projectItems = new BeforeBuildCustomToolProjectItems(e.Buildable);
var projectItems = new BeforeBuildCustomToolProjectItems(e.Projects);
RunCustomTool(projectItems.GetProjectItems());
}

1
src/Main/Base/Project/Src/Project/ConfigurationGuiHelper.cs

@ -37,6 +37,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -37,6 +37,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// <summary>
/// Class that helps connecting configuration GUI controls to MsBuild properties.
/// </summary>
[Obsolete]
public class ConfigurationGuiHelper : ICanBeDirty
{
MSBuildBasedProject project;

36
src/Main/Base/Project/Src/Project/IProject.cs

@ -330,48 +330,12 @@ namespace ICSharpCode.SharpDevelop.Project @@ -330,48 +330,12 @@ namespace ICSharpCode.SharpDevelop.Project
/// Never returns null, but may return a permanently empty collection if this project does not support such models.
/// </summary>
ITypeDefinitionModelCollection TypeDefinitionModels { get; }
}
/// <summary>
/// A project or solution.
/// The IBuildable interface members are thread-safe.
/// </summary>
public interface IBuildable
{
/// <summary>
/// Gets the list of projects on which this project depends.
/// This method is thread-safe.
/// </summary>
ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions);
/// <summary>
/// Starts building the project using the specified options.
/// This member must be implemented thread-safe.
/// </summary>
void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink);
/// <summary>
/// Gets the name of the buildable item.
/// This property is thread-safe.
/// </summary>
string Name { get; }
/// <summary>
/// Gets the parent solution.
/// This property is thread-safe.
/// </summary>
Solution ParentSolution { get; }
/// <summary>
/// Creates the project-specific build options.
/// This member must be implemented thread-safe.
/// </summary>
/// <param name="options">The global build options.</param>
/// <param name="isRootBuildable">Specifies whether this project is the main buildable item.
/// The root buildable is the buildable for which <see cref="BuildOptions.ProjectTarget"/> and <see cref="BuildOptions.ProjectAdditionalProperties"/> apply.
/// The dependencies of that root buildable are the non-root buildables.</param>
/// <returns>The project-specific build options.</returns>
ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable);
}
/// <summary>

14
src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs

@ -10,6 +10,7 @@ using System.IO; @@ -10,6 +10,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
@ -1101,9 +1102,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -1101,9 +1102,9 @@ namespace ICSharpCode.SharpDevelop.Project
#endregion
#region Building
public override ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
public override IEnumerable<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
{
ICollection<IBuildable> result = base.GetBuildDependencies(buildOptions);
var result = base.GetBuildDependencies(buildOptions).ToList();
foreach (ProjectItem item in GetItemsOfType(ItemType.ProjectReference)) {
ProjectReferenceProjectItem prpi = item as ProjectReferenceProjectItem;
if (prpi != null && prpi.ReferencedProject != null)
@ -1112,16 +1113,19 @@ namespace ICSharpCode.SharpDevelop.Project @@ -1112,16 +1113,19 @@ namespace ICSharpCode.SharpDevelop.Project
return result;
}
public override void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink)
public override Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
MSBuildEngine.StartBuild(this, options, feedbackSink, MSBuildEngine.AdditionalTargetFiles);
return MSBuildEngine.BuildAsync(this, options, feedbackSink, progressMonitor.CancellationToken, MSBuildEngine.AdditionalTargetFiles);
}
public override ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable)
{
ProjectBuildOptions projectOptions = base.CreateProjectBuildOptions(options, isRootBuildable);
Solution solution = this.ParentSolution;
var configMatchings = solution.GetActiveConfigurationsAndPlatformsForProjects(options.SolutionConfiguration, options.SolutionPlatform);
string solutionConfiguration = options.SolutionConfiguration ?? solution.Preferences.ActiveConfiguration;
string solutionPlatform = options.SolutionPlatform ?? solution.Preferences.ActivePlatform;
var configMatchings = solution.GetActiveConfigurationsAndPlatformsForProjects(solutionConfiguration, solutionPlatform);
// Find the project configuration, and build an XML string containing all configurations from the solution
StringWriter solutionConfigurationXml = new StringWriter();
using (XmlTextWriter solutionConfigurationWriter = new XmlTextWriter(solutionConfigurationXml)) {

2
src/Main/Base/Project/Src/Project/MSBuildEngine/BuildWorkerManager.cs

@ -6,7 +6,7 @@ using System.Collections.Generic; @@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.BuildWorker;
using ICSharpCode.SharpDevelop.Project;

22
src/Main/Base/Project/Src/Project/MSBuildEngine/MSBuildEngine.cs

@ -6,10 +6,12 @@ using System.Collections.Generic; @@ -6,10 +6,12 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.BuildWorker;
using ICSharpCode.SharpDevelop.Gui;
using Microsoft.Build.Framework;
namespace ICSharpCode.SharpDevelop.Project
@ -89,7 +91,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -89,7 +91,7 @@ namespace ICSharpCode.SharpDevelop.Project
MSBuildLoggerFilters = AddInTree.BuildItems<IMSBuildLoggerFilter>(LoggerFiltersPath, null, false);
}
public static void StartBuild(IProject project, ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IEnumerable<string> additionalTargetFiles)
public static Task<bool> BuildAsync(IProject project, ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, CancellationToken cancellationToken, IEnumerable<string> additionalTargetFiles)
{
if (project == null)
throw new ArgumentNullException("project");
@ -105,7 +107,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -105,7 +107,7 @@ namespace ICSharpCode.SharpDevelop.Project
if (project.MinimumSolutionVersion >= Solution.SolutionVersionVS2010) {
engine.additionalTargetFiles.Add(Path.Combine(Path.GetDirectoryName(typeof(MSBuildEngine).Assembly.Location), "SharpDevelop.TargetingPack.targets"));
}
engine.StartBuild();
return engine.RunBuildAsync(cancellationToken);
}
readonly string projectFileName;
@ -192,7 +194,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -192,7 +194,7 @@ namespace ICSharpCode.SharpDevelop.Project
List<ILogger> loggers = new List<ILogger>();
IMSBuildChainedLoggerFilter loggerChain;
void StartBuild()
Task<bool> RunBuildAsync(CancellationToken cancellationToken)
{
Dictionary<string, string> globalProperties = new Dictionary<string, string>();
MSBuildBasedProject.InitializeMSBuildProjectProperties(globalProperties);
@ -264,24 +266,28 @@ namespace ICSharpCode.SharpDevelop.Project @@ -264,24 +266,28 @@ namespace ICSharpCode.SharpDevelop.Project
logger.Initialize(eventSource);
}
tcs = new TaskCompletionSource<bool>();
if (projectMinimumSolutionVersion <= Solution.SolutionVersionVS2008) {
if (DotnetDetection.IsDotnet35SP1Installed()) {
BuildWorkerManager.MSBuild35.RunBuildJob(job, loggerChain, OnDone, feedbackSink.ProgressMonitor.CancellationToken);
BuildWorkerManager.MSBuild35.RunBuildJob(job, loggerChain, OnDone, cancellationToken);
} else {
loggerChain.HandleError(new BuildError(job.ProjectFileName, ".NET 3.5 SP1 is required to build this project."));
OnDone(false);
tcs.SetResult(false);
}
} else {
BuildWorkerManager.MSBuild40.RunBuildJob(job, loggerChain, OnDone, feedbackSink.ProgressMonitor.CancellationToken);
BuildWorkerManager.MSBuild40.RunBuildJob(job, loggerChain, OnDone, cancellationToken);
}
return tcs.Task;
}
TaskCompletionSource<bool> tcs;
void OnDone(bool success)
{
foreach (ILogger logger in loggers) {
logger.Shutdown();
}
feedbackSink.Done(success);
tcs.SetResult(success);
}
void WriteAdditionalTargetsToTempFile(Dictionary<string, string> globalProperties)

6
src/Main/Base/Project/Src/Project/MSBuildFileProject.cs

@ -2,7 +2,9 @@ @@ -2,7 +2,9 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Project
{
@ -18,9 +20,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -18,9 +20,9 @@ namespace ICSharpCode.SharpDevelop.Project
TypeGuid = "{00000000-0000-0000-0000-000000000000}";
}
public override void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink)
public override Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
MSBuildEngine.StartBuild(this, options, feedbackSink, MSBuildEngine.AdditionalTargetFiles);
return MSBuildEngine.BuildAsync(this, options, feedbackSink, progressMonitor.CancellationToken, MSBuildEngine.AdditionalTargetFiles);
}
}
}

4
src/Main/Base/Project/Src/Project/ProjectLoadInformation.cs

@ -29,13 +29,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -29,13 +29,13 @@ namespace ICSharpCode.SharpDevelop.Project
internal bool? upgradeToolsVersion;
Gui.IProgressMonitor progressMonitor = new Gui.DummyProgressMonitor();
IProgressMonitor progressMonitor = new DummyProgressMonitor();
/// <summary>
/// Gets/Sets the progress monitor used during the load.
/// This property never returns null.
/// </summary>
public Gui.IProgressMonitor ProgressMonitor {
public IProgressMonitor ProgressMonitor {
get { return progressMonitor; }
set {
if (value == null)

13
src/Main/Base/Project/Src/Project/Solution/Solution.cs

@ -8,7 +8,7 @@ using System.IO; @@ -8,7 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
@ -1253,18 +1253,15 @@ namespace ICSharpCode.SharpDevelop.Project @@ -1253,18 +1253,15 @@ namespace ICSharpCode.SharpDevelop.Project
#endregion
#region Building
ICollection<IBuildable> IBuildable.GetBuildDependencies(ProjectBuildOptions buildOptions)
IEnumerable<IBuildable> IBuildable.GetBuildDependencies(ProjectBuildOptions buildOptions)
{
List<IBuildable> result = new List<IBuildable>();
foreach (IProject p in this.Projects)
result.Add(p);
return result;
return this.Projects;
}
void IBuildable.StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink)
Task<bool> IBuildable.BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
// building a solution finishes immediately: we only care for the dependencies
feedbackSink.Done(true);
return Task.FromResult(true);
}
ProjectBuildOptions IBuildable.CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable)

84
src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs

@ -540,7 +540,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -540,7 +540,7 @@ namespace ICSharpCode.SharpDevelop.Project
// If a build is running, cancel it.
// If we would let a build run but unload the MSBuild projects, the next project.StartBuild call
// could cause an exception.
BuildEngine.CancelGuiBuild();
SD.BuildService.CancelBuild();
if (openSolution != null) {
CurrentProject = null;
@ -610,44 +610,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -610,44 +610,13 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
static bool building;
[Obsolete]
public static bool IsBuilding {
get {
return building;
return SD.BuildService.IsBuilding;
}
}
/// <summary>
/// Raises the <see cref="BuildStarted"/> event.
///
/// You do not need to call this method if you use BuildEngine.BuildInGui - the build
/// engine will call these events itself.
/// </summary>
public static void RaiseEventBuildStarted(BuildEventArgs e)
{
if (e == null)
throw new ArgumentNullException("e");
WorkbenchSingleton.AssertMainThread();
building = true;
BuildStarted.RaiseEvent(null, e);
}
/// <summary>
/// Raises the <see cref="BuildFinished"/> event.
///
/// You do not need to call this method if you use BuildEngine.BuildInGui - the build
/// engine will call these events itself.
/// </summary>
public static void RaiseEventBuildFinished(BuildEventArgs e)
{
if (e == null)
throw new ArgumentNullException("e");
WorkbenchSingleton.AssertMainThread();
building = false;
BuildFinished.RaiseEvent(null, e);
}
public static void RemoveSolutionFolder(string guid)
{
if (OpenSolution == null) {
@ -740,8 +709,16 @@ namespace ICSharpCode.SharpDevelop.Project @@ -740,8 +709,16 @@ namespace ICSharpCode.SharpDevelop.Project
/// </summary>
public static event SolutionFolderEventHandler SolutionFolderRemoved;
public static event EventHandler<BuildEventArgs> BuildStarted;
public static event EventHandler<BuildEventArgs> BuildFinished;
[Obsolete]
public static event EventHandler<BuildEventArgs> BuildStarted {
add { SD.BuildService.BuildStarted += value; }
remove { SD.BuildService.BuildFinished -= value; }
}
[Obsolete]
public static event EventHandler<BuildEventArgs> BuildFinished {
add { SD.BuildService.BuildFinished += value; }
remove { SD.BuildService.BuildFinished -= value; }
}
public static event SolutionConfigurationEventHandler SolutionConfigurationChanged;
@ -774,39 +751,4 @@ namespace ICSharpCode.SharpDevelop.Project @@ -774,39 +751,4 @@ namespace ICSharpCode.SharpDevelop.Project
public static event EventHandler<ProjectItemEventArgs> ProjectItemAdded;
public static event EventHandler<ProjectItemEventArgs> ProjectItemRemoved;
}
public class BuildEventArgs : EventArgs
{
/// <summary>
/// The project/solution to be built.
/// </summary>
public readonly IBuildable Buildable;
/// <summary>
/// The build options.
/// </summary>
public readonly BuildOptions Options;
/// <summary>
/// Gets the build results.
/// This property is null for build started events.
/// </summary>
public readonly BuildResults Results;
public BuildEventArgs(IBuildable buildable, BuildOptions options)
: this(buildable, options, null)
{
}
public BuildEventArgs(IBuildable buildable, BuildOptions options, BuildResults results)
{
if (buildable == null)
throw new ArgumentNullException("buildable");
if (options == null)
throw new ArgumentNullException("options");
this.Buildable = buildable;
this.Options = options;
this.Results = results;
}
}
}

48
src/Main/Base/Test/Project/BeforeBuildCustomToolProjectItemsTests.cs

@ -5,8 +5,9 @@ using System; @@ -5,8 +5,9 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Tests.Utils;
using NUnit.Framework;
@ -21,27 +22,6 @@ namespace ICSharpCode.SharpDevelop.Tests.Project @@ -21,27 +22,6 @@ namespace ICSharpCode.SharpDevelop.Tests.Project
BeforeBuildCustomToolProjectItems beforeBuildCustomToolProjectItems;
Solution solution;
class UnknownBuildable : IBuildable
{
public string Name { get; set; }
public Solution ParentSolution { get; set; }
public ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
{
return new IBuildable[0];
}
public void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink)
{
}
public ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable)
{
return new ProjectBuildOptions(BuildTarget.Build);
}
}
IProject CreateProject(string fileName = @"d:\MyProject\MyProject.csproj")
{
projectHelper = new ProjectHelper(fileName);
@ -84,17 +64,17 @@ namespace ICSharpCode.SharpDevelop.Tests.Project @@ -84,17 +64,17 @@ namespace ICSharpCode.SharpDevelop.Tests.Project
void CreateBeforeBuildCustomToolProjectItems()
{
CreateBeforeBuildCustomToolProjectItems(projectHelper.Project as IBuildable);
CreateBeforeBuildCustomToolProjectItems(new[] { projectHelper.Project });
}
void CreateBeforeBuildCustomToolProjectItems(IBuildable buildable)
void CreateBeforeBuildCustomToolProjectItems(IReadOnlyList<IProject> projects)
{
beforeBuildCustomToolProjectItems = new BeforeBuildCustomToolProjectItems(buildable);
beforeBuildCustomToolProjectItems = new BeforeBuildCustomToolProjectItems(projects);
}
void CreateBeforeBuildCustomToolProjectItemsUsingSolution()
{
CreateBeforeBuildCustomToolProjectItems(solution as IBuildable);
CreateBeforeBuildCustomToolProjectItems(solution.Projects.ToList());
}
FileProjectItem AddFileToProject(string include)
@ -104,12 +84,6 @@ namespace ICSharpCode.SharpDevelop.Tests.Project @@ -104,12 +84,6 @@ namespace ICSharpCode.SharpDevelop.Tests.Project
return projectItem;
}
void CreateBeforeBuildCustomToolProjectItemsWithUnknownIBuildableDerivedClass()
{
var unknownBuildable = new UnknownBuildable();
CreateBeforeBuildCustomToolProjectItems(unknownBuildable);
}
[Test]
public void GetProjectItems_BuildSingleProjectNotConfiguredToRunCustomToolsOnBuild_ReturnsNoItems()
{
@ -290,15 +264,5 @@ namespace ICSharpCode.SharpDevelop.Tests.Project @@ -290,15 +264,5 @@ namespace ICSharpCode.SharpDevelop.Tests.Project
};
CollectionAssert.AreEqual(expectedProjectItems, projectItems);
}
[Test]
public void GetProjectItems_UnknownIBuildableDerivedClass_NullReferenceExceptionIsNotThrown()
{
CreateBeforeBuildCustomToolProjectItemsWithUnknownIBuildableDerivedClass();
List<FileProjectItem> projectItems = GetProjectItems();
Assert.AreEqual(0, projectItems.Count);
}
}
}

1
src/Main/Core/Project/Src/Services/PropertyService/PropertyServiceImpl.cs

@ -35,6 +35,7 @@ namespace ICSharpCode.Core @@ -35,6 +35,7 @@ namespace ICSharpCode.Core
this.configDirectory = configDirectory;
this.dataDirectory = dataDirectory;
this.propertyFileName = propertiesName + ".xml";
Directory.CreateDirectory(configDirectory);
LoadPropertiesFromStream(Path.Combine(configDirectory, propertyFileName));
}

57
src/Main/Base/Project/Src/Project/BuildEngine.cs → src/Main/SharpDevelop/Project/Build/BuildEngine.cs

@ -8,6 +8,7 @@ using System.IO; @@ -8,6 +8,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
@ -20,10 +21,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -20,10 +21,10 @@ namespace ICSharpCode.SharpDevelop.Project
///
/// This class is not related to MSBuild: it simply "builds" a project by calling IBuildable.StartBuild.
/// </summary>
public sealed class BuildEngine
sealed class BuildEngine
{
#region Building in the SharpDevelop GUI
static CancellationTokenSource guiBuildCancellation;
/*static CancellationTokenSource guiBuildCancellation;
static IAnalyticsMonitorTrackedFeature guiBuildTrackedFeature;
/// <summary>
@ -151,7 +152,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -151,7 +152,7 @@ namespace ICSharpCode.SharpDevelop.Project
ProjectService.RaiseEventBuildFinished(new BuildEventArgs(buildable, options, results));
});
}
}
}*/
#endregion
#region StartBuild
@ -165,26 +166,17 @@ namespace ICSharpCode.SharpDevelop.Project @@ -165,26 +166,17 @@ namespace ICSharpCode.SharpDevelop.Project
/// will ensure that output from two projects building in parallel isn't interleaved.</param>
/// <param name="progressMonitor">The progress monitor that receives build progress. The monitor will be disposed
/// when the build completes.</param>
public static void StartBuild(IBuildable project, BuildOptions options, IBuildFeedbackSink realtimeBuildFeedbackSink)
public static Task<BuildResults> BuildAsync(IBuildable project, BuildOptions options, IBuildFeedbackSink buildFeedbackSink, IProgressMonitor progressMonitor)
{
if (project == null)
throw new ArgumentNullException("solution");
if (options == null)
throw new ArgumentNullException("options");
Solution solution = project.ParentSolution;
if (solution == null)
throw new ArgumentException("project.ParentSolution must not be null", "project");
if (string.IsNullOrEmpty(options.SolutionConfiguration))
options.SolutionConfiguration = solution.Preferences.ActiveConfiguration;
if (string.IsNullOrEmpty(options.SolutionPlatform))
options.SolutionPlatform = solution.Preferences.ActivePlatform;
BuildEngine engine = new BuildEngine(options, project);
engine.buildStart = DateTime.Now;
engine.combinedBuildFeedbackSink = realtimeBuildFeedbackSink;
engine.progressMonitor = realtimeBuildFeedbackSink.ProgressMonitor;
engine.combinedBuildFeedbackSink = buildFeedbackSink;
engine.progressMonitor = progressMonitor;
try {
engine.rootNode = engine.CreateBuildGraph(project);
} catch (CyclicDependencyException ex) {
@ -201,7 +193,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -201,7 +193,7 @@ namespace ICSharpCode.SharpDevelop.Project
engine.results.Result = BuildResultCode.BuildFileError;
engine.ReportDone();
return;
return engine.tcs.Task;
}
engine.workersToStart = options.ParallelProjectCount;
@ -213,6 +205,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -213,6 +205,7 @@ namespace ICSharpCode.SharpDevelop.Project
engine.ReportMessageLine("${res:MainWindow.CompilerMessages.BuildStarted}");
engine.StartBuildProjects();
engine.UpdateProgressTaskName();
return engine.tcs.Task;
}
#endregion
@ -280,12 +273,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -280,12 +273,13 @@ namespace ICSharpCode.SharpDevelop.Project
this.project = project;
}
public void DoStartBuild(object state)
public async void DoStartBuild(object state)
{
string name = string.Empty;
try {
name = project.Name;
project.StartBuild(options, this);
bool success = await project.BuildAsync(options, this, perNodeProgressMonitor).ConfigureAwait(false);
Done(success);
} catch (ObjectDisposedException) {
// Handle ObjectDisposedException that occurs when trying to build a project that was unloaded.
ReportError(new BuildError(null, "The project '" + name + "' was unloaded."));
@ -313,15 +307,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -313,15 +307,6 @@ namespace ICSharpCode.SharpDevelop.Project
{
engine.OnBuildFinished(this, success);
}
IProgressMonitor IBuildFeedbackSink.ProgressMonitor {
get {
// property should be accessed only while build is running and progress monitor available
if (perNodeProgressMonitor == null)
throw new InvalidOperationException();
return perNodeProgressMonitor;
}
}
}
#endregion
@ -330,6 +315,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -330,6 +315,7 @@ namespace ICSharpCode.SharpDevelop.Project
readonly BuildOptions options;
IProgressMonitor progressMonitor;
CancellationTokenRegistration cancellationRegistration;
readonly TaskCompletionSource<BuildResults> tcs = new TaskCompletionSource<BuildResults>();
BuildNode rootNode;
readonly IBuildable rootProject;
readonly BuildResults results = new BuildResults();
@ -500,7 +486,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -500,7 +486,6 @@ namespace ICSharpCode.SharpDevelop.Project
node.hasErrors = !success;
projectsCurrentlyBuilding.Remove(node);
results.AddBuiltProject(node.project);
foreach (BuildNode n in node.dependentOnThis) {
n.outstandingDependencies--;
@ -546,7 +531,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -546,7 +531,6 @@ namespace ICSharpCode.SharpDevelop.Project
ReportMessageLine("${res:MainWindow.CompilerMessages.BuildFinished}" + buildTime);
}
cancellationRegistration.Dispose();
progressMonitor.Dispose();
ReportDone();
}
@ -555,20 +539,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -555,20 +539,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// </summary>
void ReportDone()
{
if (combinedBuildFeedbackSink != null) {
if (combinedBuildFeedbackSink is MessageViewSink) {
// Special case GUI-builds so that they have more information available:
// (non-GUI builds can get the same information from the options.Callback,
// but the GUI cannot use the callback because the build options are set by
// the code triggering the build)
((MessageViewSink)combinedBuildFeedbackSink).Done(rootProject, options, results);
} else {
combinedBuildFeedbackSink.Done(results.Result == BuildResultCode.Success);
}
}
if (options.Callback != null) {
Gui.WorkbenchSingleton.SafeThreadAsyncCall(delegate { options.Callback(results); });
}
tcs.SetResult(results);
}
#endregion

155
src/Main/Base/Project/Src/Services/ProjectService/CompileModifiedProjectsOnly.cs → src/Main/SharpDevelop/Project/Build/BuildModifiedProjectsOnlyService.cs

@ -3,65 +3,43 @@ @@ -3,65 +3,43 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using ICSharpCode.Core;
using System.Diagnostics;
using System.ComponentModel;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Project
{
public enum BuildOnExecuteSetting
{
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.DoNotBuild}")]
DoNotBuild,
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.BuildOnlyModified}")]
BuildOnlyModified,
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.BuildModifiedAndDependent}")]
BuildModifiedAndDependent,
[Description("${res:Dialog.Options.IDEOptions.ProjectAndSolutionOptions.WhenRunning.RegularBuild}")]
RegularBuild
}
/// <summary>
/// Tracks changes to projects and causes only modified projects
/// to be recompiled.
/// </summary>
static class BuildModifiedProjectsOnlyService
class BuildModifiedProjectsOnlyService
{
public static BuildOnExecuteSetting Setting {
get { return PropertyService.Get("BuildOnExecute", BuildOnExecuteSetting.RegularBuild); }
set { PropertyService.Set("BuildOnExecute", value); }
}
static readonly Dictionary<IProject, CompilationPass> unmodifiedProjects = new Dictionary<IProject, CompilationPass>();
static BuildModifiedProjectsOnlyService()
public BuildModifiedProjectsOnlyService(IBuildService buildService)
{
// these actions cause a full recompilation:
ProjectService.SolutionClosed += MarkAllForRecompilation;
ProjectService.SolutionConfigurationChanged += MarkAllForRecompilation;
ProjectService.SolutionSaved += MarkAllForRecompilation;
ProjectService.BuildFinished += ProjectService_BuildFinished;
buildService.BuildFinished += BuildService_BuildFinished;
FileUtility.FileSaved += OnFileSaved;
}
public static void Initialize()
{
// first call to init causes static ctor calls
}
static void ProjectService_BuildFinished(object sender, BuildEventArgs e)
void BuildService_BuildFinished(object sender, BuildEventArgs e)
{
// at the end of an successful build, mark all built projects as unmodified
if (e.Results.Result == BuildResultCode.Success) {
lock (unmodifiedProjects) {
CompilationPass pass = new CompilationPass();
foreach (IBuildable b in e.Results.BuiltProjects) {
IProject p = GetProjectFromBuildable(b);
if (p != null) {
unmodifiedProjects[p] = pass;
}
foreach (IProject p in e.Projects) {
unmodifiedProjects[p] = pass;
}
}
}
@ -73,21 +51,14 @@ namespace ICSharpCode.SharpDevelop.Project @@ -73,21 +51,14 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
static IProject GetProjectFromBuildable(IBuildable b)
{
while (b is Wrapper)
b = ((Wrapper)b).wrapped;
return b as IProject;
}
static void MarkAllForRecompilation(object sender, EventArgs e)
void MarkAllForRecompilation(object sender, EventArgs e)
{
lock (unmodifiedProjects) {
unmodifiedProjects.Clear();
}
}
static void OnFileSaved(object sender, FileNameEventArgs e)
void OnFileSaved(object sender, FileNameEventArgs e)
{
if (ProjectService.OpenSolution != null) {
foreach (IProject p in ProjectService.OpenSolution.Projects) {
@ -100,20 +71,20 @@ namespace ICSharpCode.SharpDevelop.Project @@ -100,20 +71,20 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
public static IBuildable WrapBuildable(IBuildable buildable)
public IBuildable WrapBuildable(IBuildable buildable, BuildDetection setting)
{
switch (Setting) {
case BuildOnExecuteSetting.DoNotBuild:
switch (setting) {
case BuildDetection.DoNotBuild:
return new DummyBuildable(buildable);
case BuildOnExecuteSetting.BuildModifiedAndDependent:
case BuildOnExecuteSetting.BuildOnlyModified:
case BuildDetection.BuildModifiedAndDependent:
case BuildDetection.BuildOnlyModified:
lock (unmodifiedProjects) {
foreach (var pair in unmodifiedProjects) {
LoggingService.Debug(pair.Key.Name + ": " + pair.Value);
}
}
return new WrapperFactory().GetWrapper(buildable);
case BuildOnExecuteSetting.RegularBuild:
return new WrapperFactory(setting).GetWrapper(buildable);
case BuildDetection.RegularBuild:
return buildable;
default:
throw new NotSupportedException();
@ -133,22 +104,19 @@ namespace ICSharpCode.SharpDevelop.Project @@ -133,22 +104,19 @@ namespace ICSharpCode.SharpDevelop.Project
get { return wrappedBuildable.Name; }
}
public Solution ParentSolution {
get { return wrappedBuildable.ParentSolution; }
}
public ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable)
{
return null;
}
public ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
public IEnumerable<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
{
return new IBuildable[0];
return Enumerable.Empty<IBuildable>();
}
public void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink)
public Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
return Task.FromResult(true);
}
}
@ -171,9 +139,15 @@ namespace ICSharpCode.SharpDevelop.Project @@ -171,9 +139,15 @@ namespace ICSharpCode.SharpDevelop.Project
sealed class WrapperFactory
{
public readonly BuildDetection Setting;
public readonly CompilationPass CurrentPass = new CompilationPass();
readonly Dictionary<IBuildable, IBuildable> dict = new Dictionary<IBuildable, IBuildable>();
public WrapperFactory(BuildDetection setting)
{
this.Setting = setting;
}
public IBuildable GetWrapper(IBuildable wrapped)
{
IBuildable b;
@ -200,10 +174,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -200,10 +174,6 @@ namespace ICSharpCode.SharpDevelop.Project
get { return wrapped.Name; }
}
public Solution ParentSolution {
get { return wrapped.ParentSolution; }
}
public ProjectBuildOptions CreateProjectBuildOptions(BuildOptions options, bool isRootBuildable)
{
return wrapped.CreateProjectBuildOptions(options, isRootBuildable);
@ -211,8 +181,8 @@ namespace ICSharpCode.SharpDevelop.Project @@ -211,8 +181,8 @@ namespace ICSharpCode.SharpDevelop.Project
Dictionary<ProjectBuildOptions, ICollection<IBuildable>> cachedBuildDependencies = new Dictionary<ProjectBuildOptions, ICollection<IBuildable>>();
ICollection<IBuildable> cachedBuildDependenciesForNullOptions;
public ICollection<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
public IEnumerable<IBuildable> GetBuildDependencies(ProjectBuildOptions buildOptions)
{
List<IBuildable> result = new List<IBuildable>();
foreach (IBuildable b in wrapped.GetBuildDependencies(buildOptions)) {
@ -241,20 +211,20 @@ namespace ICSharpCode.SharpDevelop.Project @@ -241,20 +211,20 @@ namespace ICSharpCode.SharpDevelop.Project
return lastCompilationPass.Index > comparisonPass.Index;
}
public void StartBuild(ProjectBuildOptions buildOptions, IBuildFeedbackSink feedbackSink)
public async Task<bool> BuildAsync(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink, IProgressMonitor progressMonitor)
{
IProject p = wrapped as IProject;
if (p == null) {
wrapped.StartBuild(buildOptions, feedbackSink);
return await wrapped.BuildAsync(options, feedbackSink, progressMonitor);
} else {
lock (unmodifiedProjects) {
if (!unmodifiedProjects.TryGetValue(p, out lastCompilationPass)) {
lastCompilationPass = null;
}
}
if (lastCompilationPass != null && Setting == BuildOnExecuteSetting.BuildModifiedAndDependent) {
if (lastCompilationPass != null && factory.Setting == BuildDetection.BuildModifiedAndDependent) {
lock (cachedBuildDependencies) {
var dependencies = buildOptions != null ? cachedBuildDependencies[buildOptions] : cachedBuildDependenciesForNullOptions;
var dependencies = options != null ? cachedBuildDependencies[options] : cachedBuildDependenciesForNullOptions;
if (dependencies.OfType<Wrapper>().Any(w=>w.WasRecompiledAfter(lastCompilationPass))) {
lastCompilationPass = null;
}
@ -265,56 +235,17 @@ namespace ICSharpCode.SharpDevelop.Project @@ -265,56 +235,17 @@ namespace ICSharpCode.SharpDevelop.Project
StringParser.Parse("${res:MainWindow.CompilerMessages.SkipProjectNoChanges}",
new StringTagPair("Name", p.Name))
);
feedbackSink.Done(true);
return true;
} else {
lastCompilationPass = factory.CurrentPass;
wrapped.StartBuild(buildOptions, new BuildFeedbackSink(p, feedbackSink, factory.CurrentPass));
}
}
}
/// <summary>
/// Wraps a build feedback sink and marks a project as requiring recompilation when
/// compilation was not successful.
/// </summary>
sealed class BuildFeedbackSink : IBuildFeedbackSink
{
IProject project;
IBuildFeedbackSink sink;
CompilationPass currentPass;
public BuildFeedbackSink(IProject p, IBuildFeedbackSink sink, CompilationPass currentPass)
{
Debug.Assert(p != null);
Debug.Assert(sink != null);
Debug.Assert(currentPass != null);
this.project = p;
this.sink = sink;
this.currentPass = currentPass;
}
public Gui.IProgressMonitor ProgressMonitor {
get { return sink.ProgressMonitor; }
}
public void ReportError(BuildError error)
{
sink.ReportError(error);
}
public void ReportMessage(string message)
{
sink.ReportMessage(message);
}
public void Done(bool success)
{
if (success) {
lock (unmodifiedProjects) {
unmodifiedProjects[project] = currentPass;
var success = await wrapped.BuildAsync(options, feedbackSink, progressMonitor);
if (success) {
lock (unmodifiedProjects) {
unmodifiedProjects[p] = factory.CurrentPass;
}
}
return success;
}
sink.Done(success);
}
}
}

117
src/Main/SharpDevelop/Project/Build/BuildService.cs

@ -0,0 +1,117 @@ @@ -0,0 +1,117 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Project
{
sealed class BuildService : IBuildService
{
readonly BuildModifiedProjectsOnlyService buildModifiedProjectsOnly;
public BuildService()
{
this.buildModifiedProjectsOnly = new BuildModifiedProjectsOnlyService(this);
}
public event EventHandler<BuildEventArgs> BuildStarted;
public event EventHandler<BuildEventArgs> BuildFinished;
CancellationTokenSource guiBuildCancellation;
public bool IsBuilding {
get { return guiBuildCancellation != null; }
}
public void CancelBuild()
{
if (guiBuildCancellation != null)
guiBuildCancellation.Cancel();
}
public async Task<BuildResults> BuildAsync(IEnumerable<IProject> projects, BuildOptions options)
{
if (projects == null)
throw new ArgumentNullException("projects");
if (options == null)
throw new ArgumentNullException("options");
SD.MainThread.VerifyAccess();
if (guiBuildCancellation != null) {
BuildResults results = new BuildResults();
SD.StatusBar.SetMessage(ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning"));
BuildError error = new BuildError(null, ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning"));
results.Add(error);
TaskService.Add(new SDTask(error));
results.Result = BuildResultCode.MSBuildAlreadyRunning;
return results;
}
var projectsList = projects.ToList();
guiBuildCancellation = new CancellationTokenSource();
using (var progressMonitor = SD.StatusBar.CreateProgressMonitor(guiBuildCancellation.Token)) {
if (BuildStarted != null)
BuildStarted(this, new BuildEventArgs(projectsList, options));
var trackedFeature = SD.AnalyticsMonitor.TrackFeature("ICSharpCode.SharpDevelop.Project.BuildEngine.Build");
SD.StatusBar.SetMessage(StringParser.Parse("${res:MainWindow.CompilerMessages.BuildVerb}..."));
IBuildable buildable;
if (projectsList.Count == 1)
buildable = projectsList[0];
else
buildable = new MultipleProjectBuildable(projectsList);
buildable = buildModifiedProjectsOnly.WrapBuildable(buildable, options.BuildDetection);
var sink = new UIBuildFeedbackSink(TaskService.BuildMessageViewCategory, SD.StatusBar);
var results = await BuildInBackgroundAsync(buildable, options, sink, progressMonitor);
string message;
if (results.Result == BuildResultCode.Cancelled) {
message = "${res:MainWindow.CompilerMessages.BuildCancelled}";
} else {
if (results.Result == BuildResultCode.Success)
message = "${res:MainWindow.CompilerMessages.BuildFinished}";
else
message = "${res:MainWindow.CompilerMessages.BuildFailed}";
if (results.ErrorCount > 0)
message += " " + results.ErrorCount + " error(s)";
if (results.WarningCount > 0)
message += " " + results.WarningCount + " warning(s)";
}
SD.StatusBar.SetMessage(message);
trackedFeature.EndTracking();
if (BuildFinished != null)
BuildFinished(this, new BuildEventArgs(projectsList, options, results));
return results;
}
}
public Task<BuildResults> BuildAsync(IProject project, BuildOptions options)
{
if (project != null)
return BuildAsync(new[] { project }, options);
else
return Task.FromResult(new BuildResults { Result = BuildResultCode.Error });
}
public Task<BuildResults> BuildAsync(Solution solution, BuildOptions options)
{
if (solution != null)
return BuildAsync(solution.Projects, options);
else
return Task.FromResult(new BuildResults { Result = BuildResultCode.Error });
}
public Task<BuildResults> BuildInBackgroundAsync(IBuildable buildable, BuildOptions options, IBuildFeedbackSink buildFeedbackSink, IProgressMonitor progressMonitor)
{
return BuildEngine.BuildAsync(buildable, options, buildFeedbackSink, progressMonitor);
}
}
}

46
src/Main/SharpDevelop/Project/Build/UIBuildFeedbackSink.cs

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Project
{
/// <summary>
/// This error message sink is used for GUI builds.
/// </summary>
sealed class UIBuildFeedbackSink : IBuildFeedbackSink
{
MessageViewCategory messageView;
IStatusBarService statusBarService;
public UIBuildFeedbackSink(MessageViewCategory messageView, IStatusBarService statusBarService)
{
Debug.Assert(messageView != null);
Debug.Assert(statusBarService != null);
this.messageView = messageView;
this.statusBarService = statusBarService;
}
public void ReportError(BuildError error)
{
WorkbenchSingleton.SafeThreadAsyncCall(
delegate {
TaskService.Add(new SDTask(error));
});
}
public void ReportMessage(string message)
{
messageView.AppendLine(message);
}
}
}

6
src/Main/SharpDevelop/SharpDevelop.csproj

@ -93,6 +93,10 @@ @@ -93,6 +93,10 @@
<Compile Include="Parser\AssemblyParserService.cs" />
<Compile Include="Parser\LoadSolutionProjects.cs" />
<Compile Include="Parser\SharpDevelopSolutionSnapshot.cs" />
<Compile Include="Project\Build\BuildEngine.cs" />
<Compile Include="Project\Build\BuildModifiedProjectsOnlyService.cs" />
<Compile Include="Project\Build\BuildService.cs" />
<Compile Include="Project\Build\UIBuildFeedbackSink.cs" />
<Compile Include="Services\ClipboardWrapper.cs" />
<Compile Include="Services\DispatcherMessageLoop.cs" />
<Compile Include="Startup\App.xaml.cs" />
@ -216,6 +220,8 @@ @@ -216,6 +220,8 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Dom" />
<Folder Include="Project" />
<Folder Include="Project\Build" />
<Folder Include="Services" />
<Folder Include="WinForms" />
<Folder Include="OptionPanels" />

Loading…
Cancel
Save