Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CustomTools/CustomToolService.cs')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CustomTools/CustomToolService.cs126
1 files changed, 68 insertions, 58 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CustomTools/CustomToolService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CustomTools/CustomToolService.cs
index 78f2292634..00aa394ed9 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CustomTools/CustomToolService.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CustomTools/CustomToolService.cs
@@ -31,20 +31,28 @@ using MonoDevelop.Core;
using Mono.Addins;
using MonoDevelop.Projects;
using System.IO;
-using MonoDevelop.Ide.Tasks;
using System.CodeDom.Compiler;
using MonoDevelop.Ide.Gui;
using MonoDevelop.Core.ProgressMonitoring;
using System.Linq;
using System.Threading;
+using Task = System.Threading.Tasks.Task;
+using IdeTask = MonoDevelop.Ide.Tasks.UserTask;
+using MonoDevelop.Ide.Tasks;
namespace MonoDevelop.Ide.CustomTools
{
public static class CustomToolService
{
static readonly Dictionary<string,CustomToolExtensionNode> nodes = new Dictionary<string,CustomToolExtensionNode> ();
-
- static readonly Dictionary<string,IAsyncOperation> runningTasks = new Dictionary<string, IAsyncOperation> ();
+
+ class TaskInfo {
+ public Task Task;
+ public CancellationTokenSource CancellationTokenSource;
+ public SingleFileCustomToolResult Result;
+ }
+
+ static readonly Dictionary<string,TaskInfo> runningTasks = new Dictionary<string, TaskInfo> ();
static CustomToolService ()
{
@@ -103,7 +111,7 @@ namespace MonoDevelop.Ide.CustomTools
return null;
}
- public static void Update (ProjectFile file, bool force)
+ public async static void Update (ProjectFile file, bool force)
{
var tool = GetGenerator (file.Generator);
if (tool == null)
@@ -122,49 +130,50 @@ namespace MonoDevelop.Ide.CustomTools
//if this file is already being run, cancel it
lock (runningTasks) {
- IAsyncOperation runningTask;
+ TaskInfo runningTask;
if (runningTasks.TryGetValue (file.FilePath, out runningTask)) {
- runningTask.Cancel ();
+ runningTask.CancellationTokenSource.Cancel ();
runningTasks.Remove (file.FilePath);
}
}
-
- var monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor (false);
+
+ CancellationTokenSource cs = new CancellationTokenSource ();
+ var monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor (false).WithCancellationSource (cs);
var result = new SingleFileCustomToolResult ();
- var aggOp = new AggregatedOperationMonitor (monitor);
+ Task op;
try {
monitor.BeginTask (GettextCatalog.GetString ("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);
- IAsyncOperation op = tool.Generate (monitor, file, result);
- runningTasks.Add (file.FilePath, op);
- aggOp.AddOperation (op);
- op.Completed += delegate {
- lock (runningTasks) {
- IAsyncOperation runningTask;
- if (runningTasks.TryGetValue (file.FilePath, out runningTask) && runningTask == op) {
- runningTasks.Remove (file.FilePath);
- UpdateCompleted (monitor, aggOp, file, genFile, result);
- } else {
- //it was cancelled because another was run for the same file, so just clean up
- aggOp.Dispose ();
- monitor.EndTask ();
- monitor.ReportWarning (GettextCatalog.GetString ("Cancelled because generator ran again for the same file"));
- monitor.Dispose ();
- }
- }
- };
+ op = tool.Generate (monitor, file, result);
+ runningTasks.Add (file.FilePath, new TaskInfo {
+ Task = op,
+ CancellationTokenSource = cs,
+ Result = result
+ });
} catch (Exception ex) {
result.UnhandledException = ex;
- UpdateCompleted (monitor, aggOp, file, genFile, result);
+ UpdateCompleted (monitor, file, genFile, result);
+ return;
+ }
+ await op;
+ lock (runningTasks) {
+ TaskInfo runningTask;
+ if (runningTasks.TryGetValue (file.FilePath, out runningTask) && runningTask.Task == op) {
+ runningTasks.Remove (file.FilePath);
+ UpdateCompleted (monitor, file, genFile, result);
+ } else {
+ //it was cancelled because another was run for the same file, so just clean up
+ monitor.EndTask ();
+ monitor.ReportWarning (GettextCatalog.GetString ("Cancelled because generator ran again for the same file"));
+ monitor.Dispose ();
+ }
}
}
- static void UpdateCompleted (IProgressMonitor monitor, AggregatedOperationMonitor aggOp,
- ProjectFile file, ProjectFile genFile, SingleFileCustomToolResult result)
+ static void UpdateCompleted (ProgressMonitor monitor, ProjectFile file, ProjectFile genFile, SingleFileCustomToolResult result)
{
monitor.EndTask ();
- aggOp.Dispose ();
-
- if (monitor.IsCancelRequested) {
+
+ if (monitor.CancellationToken.IsCancellationRequested) {
monitor.ReportError (GettextCatalog.GetString ("Cancelled"), null);
monitor.Dispose ();
return;
@@ -200,19 +209,23 @@ namespace MonoDevelop.Ide.CustomTools
}
if (result.Errors.Count > 0) {
- foreach (CompilerError err in result.Errors)
- TaskService.Errors.Add (new Task (file.FilePath, err.ErrorText, err.Column, err.Line,
- err.IsWarning? TaskSeverity.Warning : TaskSeverity.Error,
- TaskPriority.Normal, file.Project.ParentSolution, file));
+ DispatchService.GuiDispatch (delegate {
+ foreach (CompilerError err in result.Errors)
+ TaskService.Errors.Add (new UserTask (file.FilePath, err.ErrorText, err.Column, err.Line,
+ err.IsWarning? TaskSeverity.Warning : TaskSeverity.Error,
+ TaskPriority.Normal, file.Project.ParentSolution, file));
+ });
}
if (broken)
return;
-
+
if (result.Success)
monitor.ReportSuccess ("Generated file successfully.");
+ else if (result.SuccessWithWarnings)
+ monitor.ReportSuccess ("Warnings in file generation.");
else
- monitor.ReportError ("Failed to generate file. See error pad for details.", null);
+ monitor.ReportError ("Errors in file generation.", null);
} finally {
monitor.Dispose ();
@@ -246,7 +259,7 @@ namespace MonoDevelop.Ide.CustomTools
}
if (projectChanged)
- IdeApp.ProjectOperations.Save (file.Project);
+ IdeApp.ProjectOperations.SaveAsync (file.Project);
});
}
@@ -271,9 +284,9 @@ namespace MonoDevelop.Ide.CustomTools
return ns;
}
- public static bool WaitForRunningTools (IProgressMonitor monitor)
+ public static bool WaitForRunningTools (ProgressMonitor monitor)
{
- IAsyncOperation[] operations;
+ TaskInfo[] operations;
lock (runningTasks) {
operations = runningTasks.Values.ToArray ();
}
@@ -285,27 +298,24 @@ namespace MonoDevelop.Ide.CustomTools
var evt = new AutoResetEvent (false);
- monitor.CancelRequested += delegate {
- evt.Set ();
- };
-
- OperationHandler checkOp = delegate {
- monitor.Step (1);
- if (operations.All (op => op.IsCompleted))
- evt.Set ();
- };
+ foreach (var t in operations) {
+ t.Task.ContinueWith (ta => {
+ monitor.Step (1);
+ if (operations.All (op => op.Task.IsCompleted))
+ evt.Set ();
+ });
+ }
- foreach (var o in operations)
- o.Completed += checkOp;
+ monitor.CancellationToken.Register (delegate {
+ evt.Set ();
+ });
evt.WaitOne ();
- bool success = operations.All (op => op.Success);
-
- if (!success)
- monitor.ReportError ("Error in custom tool", null);
monitor.EndTask ();
- return success;
+
+ //the tool operations display warnings themselves
+ return operations.Any (op => !op.Result.SuccessWithWarnings);
}
}
}