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:
authorSimon Lindgren <simon.n.lindgren@gmail.com>2013-08-07 15:50:10 +0400
committerSimon Lindgren <simon.n.lindgren@gmail.com>2013-08-20 17:15:37 +0400
commit9e427418b5792652ea11792ba5fb8f0a750cddea (patch)
treeb6c0ca86efbfb0facfe17cf2d92dae5e2a31436a /main/src/addins
parent2b703b332ce67be2a94b9515a2216229f1f61982 (diff)
[Refactoring] Handle exceptions better and add more specific error handling in CodeAnalysisBatchRunner.
Diffstat (limited to 'main/src/addins')
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalysisState.cs3
-rw-r--r--main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeAnalysisBatchRunner.cs143
2 files changed, 87 insertions, 59 deletions
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalysisState.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalysisState.cs
index 0a6af25dbc..221e11d819 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalysisState.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/AnalysisState.cs
@@ -30,7 +30,8 @@ namespace MonoDevelop.CodeIssues
NeverStarted,
Running,
Completed,
- Cancelled
+ Cancelled,
+ Error
}
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeAnalysisBatchRunner.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeAnalysisBatchRunner.cs
index 39bad501a3..bf0ea189e9 100644
--- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeAnalysisBatchRunner.cs
+++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeAnalysisBatchRunner.cs
@@ -41,6 +41,7 @@ using MonoDevelop.Core;
using System.Collections.Concurrent;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
+using Mono.TextEditor;
namespace MonoDevelop.CodeIssues
{
@@ -49,6 +50,8 @@ namespace MonoDevelop.CodeIssues
object _lock = new object ();
CancellationTokenSource tokenSource;
IIssueSummarySink destinationGroup;
+
+ ConcurrentDictionary<string, object> processedFiles;
public IIssueSummarySink IssueSink {
get {
@@ -115,77 +118,101 @@ namespace MonoDevelop.CodeIssues
{
lock (_lock) {
tokenSource = new CancellationTokenSource ();
+ processedFiles = new ConcurrentDictionary<string, object> ();
ThreadPool.QueueUserWorkItem (delegate {
State = AnalysisState.Running;
using (var monitor = IdeApp.Workbench.ProgressMonitors.GetStatusProgressMonitor ("Analyzing solution", null, false)) {
- int work = 0;
- foreach (var project in solution.GetAllProjects ()) {
- work += project.Files.Count (f => f.BuildAction == BuildAction.Compile);
- }
- monitor.BeginTask ("Analyzing solution", work);
- var processedFiles = new ConcurrentDictionary<string, object> ();
- foreach (var project in solution.GetAllProjects ()) {
- if (tokenSource.IsCancellationRequested)
- break;
- var content = TypeSystemService.GetProjectContext (project);
- Parallel.ForEach (project.Files, file => {
- var me = new object();
- var owner = processedFiles.AddOrUpdate(file.Name, me, (key, old) => old);
- if (me != owner)
- return;
- if (file.BuildAction != BuildAction.Compile || tokenSource.IsCancellationRequested)
- return;
-
- var editor = TextFileProvider.Instance.GetReadOnlyTextEditorData (file.FilePath);
- var document = TypeSystemService.ParseFile (project, editor);
- if (document == null)
- return;
-
- var compilation = content.AddOrUpdateFiles (document.ParsedFile).CreateCompilation ();
- var resolver = new CSharpAstResolver (compilation, document.GetAst<SyntaxTree> (), document.ParsedFile as ICSharpCode.NRefactory.CSharp.TypeSystem.CSharpUnresolvedFile);
- var context = document.CreateRefactoringContextWithEditor (editor, resolver, tokenSource.Token);
-
- CodeIssueProvider[] codeIssueProvider = RefactoringService.GetInspectors (editor.MimeType).ToArray ();
- Parallel.ForEach (codeIssueProvider, (provider) => {
- var severity = provider.GetSeverity ();
- if (severity == Severity.None || tokenSource.IsCancellationRequested)
- return;
- try {
- foreach (var issue in provider.GetIssues (context, tokenSource.Token)) {
- AddIssue (file, provider, issue);
- }
- } catch (OperationCanceledException) {
- // The operation was cancelled, no-op as the user-visible parts are
- // handled elsewhere
- } catch (Exception ex) {
- LoggingService.LogError ("Error while running code issue on:" + editor.FileName, ex);
- }
- });
- //lastMime = editor.MimeType;
- monitor.Step (1);
- });
- }
- // Cleanup
AnalysisState oldState;
AnalysisState newState;
- lock (_lock) {
- oldState = state;
- if (tokenSource.IsCancellationRequested) {
- newState = AnalysisState.Cancelled;
- } else {
- newState = AnalysisState.Completed;
+ try {
+ int work = 0;
+ foreach (var project in solution.GetAllProjects ()) {
+ work += project.Files.Count (f => f.BuildAction == BuildAction.Compile);
+ }
+ monitor.BeginTask ("Analyzing solution", work);
+ foreach (var project in solution.GetAllProjects ()) {
+ if (tokenSource.IsCancellationRequested)
+ break;
+ var content = TypeSystemService.GetProjectContext (project);
+ Parallel.ForEach (project.Files, file => {
+ AnalyzeFile (file, content);
+ monitor.Step (1);
+ });
}
- state = newState;
- tokenSource = null;
+ // Cleanup
+ lock (_lock) {
+ oldState = state;
+ if (tokenSource.IsCancellationRequested) {
+ newState = AnalysisState.Cancelled;
+ } else {
+ newState = AnalysisState.Completed;
+ }
+ state = newState;
+ tokenSource = null;
+ }
+ OnAnalysisStateChanged (new AnalysisStateChangeEventArgs (oldState, newState));
+ } catch (Exception e) {
+ lock (_lock) {
+ oldState = state;
+ state = AnalysisState.Error;
+ newState = state;
+ tokenSource = null;
+ }
+ OnAnalysisStateChanged (new AnalysisStateChangeEventArgs (oldState, newState));
+ // Do not rethrow in a thread pool
+ MessageService.ShowException (e);
}
- OnAnalysisStateChanged(new AnalysisStateChangeEventArgs(oldState, newState));
- monitor.EndTask ();
}
});
}
}
+ void AnalyzeFile (ProjectFile file, IProjectContent content)
+ {
+ var me = new object ();
+ var owner = processedFiles.AddOrUpdate (file.Name, me, (key, old) => old);
+ if (me != owner)
+ return;
+
+ if (file.BuildAction != BuildAction.Compile || tokenSource.IsCancellationRequested)
+ return;
+
+ TextEditorData editor;
+ try {
+ editor = TextFileProvider.Instance.GetReadOnlyTextEditorData (file.FilePath);
+ } catch (FileNotFoundException) {
+ // Swallow exception and ignore this file
+ return;
+ }
+ var document = TypeSystemService.ParseFile (file.Project, editor);
+ if (document == null)
+ return;
+
+ var compilation = content.AddOrUpdateFiles (document.ParsedFile).CreateCompilation ();
+ var resolver = new CSharpAstResolver (compilation, document.GetAst<SyntaxTree> (), document.ParsedFile as ICSharpCode.NRefactory.CSharp.TypeSystem.CSharpUnresolvedFile);
+ var context = document.CreateRefactoringContextWithEditor (editor, resolver, tokenSource.Token);
+
+ CodeIssueProvider[] codeIssueProvider = RefactoringService.GetInspectors (editor.MimeType).ToArray ();
+ Parallel.ForEach (codeIssueProvider, provider => {
+ var severity = provider.GetSeverity ();
+ if (severity == Severity.None || tokenSource.IsCancellationRequested)
+ return;
+ try {
+ foreach (var issue in provider.GetIssues (context, tokenSource.Token)) {
+ AddIssue (file, provider, issue);
+ }
+ }
+ catch (OperationCanceledException) {
+ // The operation was cancelled, no-op as the user-visible parts are
+ // handled elsewhere
+ }
+ catch (Exception ex) {
+ LoggingService.LogError ("Error while running code issue on:" + editor.FileName, ex);
+ }
+ });
+ }
+
void AddIssue (ProjectFile file, CodeIssueProvider provider, CodeIssue r)
{
var issue = new IssueSummary {