diff options
Diffstat (limited to 'main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui')
3 files changed, 132 insertions, 103 deletions
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultMarker.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultMarker.cs index 332f0061cf..43ddf40ef4 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultMarker.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultMarker.cs @@ -24,15 +24,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -using Mono.TextEditor; -using MonoDevelop.SourceEditor; -using MonoDevelop.SourceEditor.QuickTasks; -using ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.Refactoring; using System.Collections.Generic; +using MonoDevelop.Core.Text; +using MonoDevelop.Ide.Editor; namespace MonoDevelop.AnalysisCore.Gui { +/* class ResultMarker : UnderlineTextSegmentMarker { readonly Result result; @@ -42,17 +40,9 @@ namespace MonoDevelop.AnalysisCore.Gui this.result = result; } - static bool IsOneLine (Result result) - { - return result.Region.BeginLine == result.Region.EndLine; - } - public Result Result { get { return result; } } //utility for debugging - public int Line { get { return result.Region.BeginLine; } } - public int ColStart { get { return IsOneLine (result)? (result.Region.BeginColumn) : 0; } } - public int ColEnd { get { return IsOneLine (result)? (result.Region.EndColumn) : 0; } } public string Message { get { return result.Message; } } static Cairo.Color GetColor (TextEditor editor, Result result) @@ -214,4 +204,5 @@ namespace MonoDevelop.AnalysisCore.Gui } #endregion } +*/ } diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultTooltipProvider.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultTooltipProvider.cs index e826f51f45..b5d18d54d1 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultTooltipProvider.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultTooltipProvider.cs @@ -25,11 +25,10 @@ // THE SOFTWARE.
using System;
-using Mono.TextEditor;
-using MonoDevelop.SourceEditor;
using System.Text;
using System.Collections.Generic;
using MonoDevelop.Ide.TypeSystem;
+using MonoDevelop.Ide.Editor;
namespace MonoDevelop.AnalysisCore.Gui
{
@@ -39,57 +38,59 @@ namespace MonoDevelop.AnalysisCore.Gui {
}
- public override TooltipItem GetItem (TextEditor editor, int offset)
+ public override TooltipItem GetItem (TextEditor editor, DocumentContext ctx, int offset)
{
- //get the ResultsEditorExtension from the editor
- var ed = editor as ExtensibleTextEditor;
- if (ed == null)
- return null;
- var ext = ed.Extension;
- while (ext != null && !(ext is ResultsEditorExtension))
- ext = ext.Next;
- if (ext == null)
- return null;
- var resExt = (ResultsEditorExtension) ext;
-
- //get the results from the extension
- var results = resExt.GetResultsAtOffset (offset);
- if (results == null || results.Count == 0)
- return null;
-
- return new TooltipItem (results, editor.Document.GetLineByOffset (offset));
+// //get the ResultsEditorExtension from the editor
+// var ed = editor as ExtensibleTextEditor;
+// if (ed == null)
+// return null;
+// var ext = ed.Extension;
+// while (ext != null && !(ext is ResultsEditorExtension))
+// ext = ext.Next;
+// if (ext == null)
+// return null;
+// var resExt = (ResultsEditorExtension) ext;
+//
+// //get the results from the extension
+// var results = resExt.GetResultsAtOffset (offset);
+// if (results == null || results.Count == 0)
+// return null;
+//
+// return new TooltipItem (results, editor.GetLineByOffset (offset));
+ return null;
}
- protected override Gtk.Window CreateTooltipWindow (TextEditor editor, int offset, Gdk.ModifierType modifierState, TooltipItem item)
+ public override MonoDevelop.Components.Control CreateTooltipWindow (TextEditor editor, DocumentContext ctx, TooltipItem item, int offset, Gdk.ModifierType modifierState)
{
- //create a message string from all the results
- var results = (IList<Result>)item.Item;
- var sb = new StringBuilder ();
- bool first = false;
- foreach (var r in results) {
- if (!first)
- first = true;
- else
- sb.AppendLine ();
- sb.Append (r.Level.ToString ());
- sb.Append (": ");
- sb.Append (AmbienceService.EscapeText (r.Message));
- }
-
- //FIXME: use a nicer, more specialized tooltip window, with results formatting and hints about
- // commands and stuff
- var win = new LanguageItemWindow ((ExtensibleTextEditor) editor, modifierState, null, sb.ToString (), null);
- if (win.IsEmpty)
- return null;
- return win;
+// //create a message string from all the results
+// var results = (IList<Result>)item.Item;
+// var sb = new StringBuilder ();
+// bool first = false;
+// foreach (var r in results) {
+// if (!first)
+// first = true;
+// else
+// sb.AppendLine ();
+// sb.Append (r.Level.ToString ());
+// sb.Append (": ");
+// sb.Append (AmbienceService.EscapeText (r.Message));
+// }
+//
+// //FIXME: use a nicer, more specialized tooltip window, with results formatting and hints about
+// // commands and stuff
+// var win = new LanguageItemWindow ((ExtensibleTextEditor) editor, modifierState, null, sb.ToString (), null);
+// if (win.IsEmpty)
+// return null;
+// return win;
+ return null;
}
- protected override void GetRequiredPosition (TextEditor editor, Gtk.Window tipWindow, out int requiredWidth, out double xalign)
- {
- var win = (LanguageItemWindow) tipWindow;
- requiredWidth = win.SetMaxWidth (win.Screen.Width);
- xalign = 0.5;
- }
+// protected override void GetRequiredPosition (ITextEditor editor, Gtk.Window tipWindow, out int requiredWidth, out double xalign)
+// {
+// var win = (LanguageItemWindow) tipWindow;
+// requiredWidth = win.SetMaxWidth (win.Screen.Width);
+// xalign = 0.5;
+// }
}
}
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs index 4806feac47..0f9e33ae9d 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.AnalysisCore/Gui/ResultsEditorExtension.cs @@ -30,20 +30,35 @@ using MonoDevelop.Ide.Gui.Content; using System.Threading; using System.Threading.Tasks; using System.IO; -using Mono.TextEditor; using System.Linq; -using MonoDevelop.SourceEditor.QuickTasks; -using ICSharpCode.NRefactory.CSharp; -using ICSharpCode.NRefactory.Refactoring; +using MonoDevelop.Ide.Editor; +using MonoDevelop.Core.Text; +using MonoDevelop.Ide.Editor.Highlighting; +using MonoDevelop.Ide.Editor.Extension; +using Microsoft.CodeAnalysis; using MonoDevelop.CodeIssues; namespace MonoDevelop.AnalysisCore.Gui { + class AnalysisDocument + { + public TextEditor Editor { get; private set; } + public DocumentLocation CaretLocation { get; private set; } + public DocumentContext DocumentContext { get; private set; } + + public AnalysisDocument (TextEditor editor, DocumentContext documentContext) + { + this.Editor = editor; + this.CaretLocation = editor.CaretLocation; + this.DocumentContext = documentContext; + } + } + public class ResultsEditorExtension : TextEditorExtension, IQuickTaskProvider { bool disposed; - public override void Initialize () + protected override void Initialize () { base.Initialize (); @@ -61,12 +76,11 @@ namespace MonoDevelop.AnalysisCore.Gui if (disposed) return; enabled = false; - Document.DocumentParsed -= OnDocumentParsed; - CancelUpdateTimout (); + DocumentContext.DocumentParsed -= OnDocumentParsed; CancelTask (); AnalysisOptions.AnalysisEnabled.Changed -= AnalysisOptionsChanged; while (markers.Count > 0) - Document.Editor.Document.RemoveMarker (markers.Dequeue ()); + Editor.RemoveMarker (markers.Dequeue ()); tasks.Clear (); disposed = true; } @@ -90,20 +104,16 @@ namespace MonoDevelop.AnalysisCore.Gui if (enabled) return; enabled = true; - Document.DocumentParsed += OnDocumentParsed; - if (Document.ParsedDocument != null) + DocumentContext.DocumentParsed += OnDocumentParsed; + if (DocumentContext.ParsedDocument != null) OnDocumentParsed (null, null); } void CancelTask () { - if (src != null) { - src.Cancel (); - try { - oldTask.Wait (); - } catch (TaskCanceledException) { - } catch (AggregateException ex) { - ex.Handle (e => e is TaskCanceledException); + lock (updateLock) { + if (src != null) { + src.Cancel (); } } } @@ -113,7 +123,7 @@ namespace MonoDevelop.AnalysisCore.Gui if (!enabled) return; enabled = false; - Document.DocumentParsed -= OnDocumentParsed; + DocumentContext.DocumentParsed -= OnDocumentParsed; CancelTask (); new ResultsUpdater (this, new Result[0], CancellationToken.None).Update (); } @@ -125,21 +135,28 @@ namespace MonoDevelop.AnalysisCore.Gui void OnDocumentParsed (object sender, EventArgs args) { - if (!QuickTaskStrip.EnableFancyFeatures) + if (!AnalysisOptions.EnableFancyFeatures) return; CancelUpdateTimout (); - var doc = Document.ParsedDocument; + var doc = DocumentContext.ParsedDocument; if (doc == null) return; + var ad = new AnalysisDocument (Editor, DocumentContext); updateTimeout = GLib.Timeout.Add (250, delegate { lock (updateLock) { CancelTask (); src = new CancellationTokenSource (); var token = src.Token; oldTask = Task.Run (() => { - var result = CodeAnalysisRunner.Check (Document, doc, token); - var updater = new ResultsUpdater (this, result, token); - updater.Update (); + try { + var result = CodeDiagnosticRunner.Check (ad, token); + if (token.IsCancellationRequested) + return; + var updater = new ResultsUpdater (this, result, token); + updater.Update (); + } catch (OperationCanceledException) { + } catch (AggregateException) { + } }); updateTimeout = 0; return false; @@ -155,6 +172,7 @@ namespace MonoDevelop.AnalysisCore.Gui } } + class ResultsUpdater { readonly ResultsEditorExtension ext; @@ -178,12 +196,28 @@ namespace MonoDevelop.AnalysisCore.Gui public void Update () { - if (!QuickTaskStrip.EnableFancyFeatures || cancellationToken.IsCancellationRequested) + if (!AnalysisOptions.EnableFancyFeatures || cancellationToken.IsCancellationRequested) return; ext.tasks.Clear (); GLib.Idle.Add (IdleHandler); } - + + static Cairo.Color GetColor (TextEditor editor, Result result) + { + switch (result.Level) { + case DiagnosticSeverity.Hidden: + return DefaultSourceEditorOptions.Instance.GetColorStyle ().PlainText.Background; + case DiagnosticSeverity.Error: + return DefaultSourceEditorOptions.Instance.GetColorStyle ().UnderlineError.Color; + case DiagnosticSeverity.Warning: + return DefaultSourceEditorOptions.Instance.GetColorStyle ().UnderlineWarning.Color; + case DiagnosticSeverity.Info: + return DefaultSourceEditorOptions.Instance.GetColorStyle ().UnderlineSuggestion.Color; + default: + throw new System.ArgumentOutOfRangeException (); + } + } + //this runs as a glib idle handler so it can add/remove text editor markers //in order to to block the GUI thread, we batch them in UPDATE_COUNT bool IdleHandler () @@ -191,13 +225,13 @@ namespace MonoDevelop.AnalysisCore.Gui if (cancellationToken.IsCancellationRequested) return false; var editor = ext.Editor; - if (editor == null || editor.Document == null) + if (editor == null) return false; //clear the old results out at the same rate we add in the new ones for (int i = 0; oldMarkers > 0 && i < UPDATE_COUNT; i++) { if (cancellationToken.IsCancellationRequested) return false; - editor.Document.RemoveMarker (ext.markers.Dequeue ()); + editor.RemoveMarker (ext.markers.Dequeue ()); oldMarkers--; } //add in the new markers @@ -209,27 +243,30 @@ namespace MonoDevelop.AnalysisCore.Gui if (cancellationToken.IsCancellationRequested) return false; var currentResult = (Result)enumerator.Current; - if (currentResult.InspectionMark != IssueMarker.None) { - int start = editor.LocationToOffset (currentResult.Region.Begin); - int end = editor.LocationToOffset (currentResult.Region.End); + int start = currentResult.Region.Start; + int end = currentResult.Region.End; if (start >= end) continue; if (currentResult.InspectionMark == IssueMarker.GrayOut) { - var marker = new GrayOutMarker (currentResult, TextSegment.FromBounds (start, end)); + var marker = TextMarkerFactory.CreateGenericTextSegmentMarker (editor, TextSegmentMarkerEffect.GrayOut, TextSegment.FromBounds (start, end)); marker.IsVisible = currentResult.Underline; - editor.Document.AddMarker (marker); + marker.Tag = currentResult; + editor.AddMarker (marker); ext.markers.Enqueue (marker); - editor.Parent.TextViewMargin.RemoveCachedLine (editor.GetLineByOffset (start)); - editor.Parent.QueueDraw (); +// editor.Parent.TextViewMargin.RemoveCachedLine (editor.GetLineByOffset (start)); +// editor.Parent.QueueDraw (); } else { - var marker = new ResultMarker (currentResult, TextSegment.FromBounds (start, end)); + var effect = currentResult.InspectionMark == IssueMarker.DottedLine ? TextSegmentMarkerEffect.DottedLine : TextSegmentMarkerEffect.WavedLine; + var marker = TextMarkerFactory.CreateGenericTextSegmentMarker (editor, effect, TextSegment.FromBounds (start, end)); + marker.Color = GetColor (editor, currentResult); marker.IsVisible = currentResult.Underline; - editor.Document.AddMarker (marker); + marker.Tag = currentResult; + editor.AddMarker (marker); ext.markers.Enqueue (marker); } } - ext.tasks.Add (new QuickTask (currentResult.Message, currentResult.Region.Begin, currentResult.Level)); + ext.tasks.Add (new QuickTask (currentResult.Message, currentResult.Region.Start, currentResult.Level)); } return true; @@ -237,7 +274,7 @@ namespace MonoDevelop.AnalysisCore.Gui } //all markers known to be in the editor - Queue<ResultMarker> markers = new Queue<ResultMarker> (); + Queue<IGenericTextSegmentMarker> markers = new Queue<IGenericTextSegmentMarker> (); const int UPDATE_COUNT = 20; @@ -247,19 +284,19 @@ namespace MonoDevelop.AnalysisCore.Gui // var line = Editor.GetLineByOffset (offset); var list = new List<Result> (); - foreach (var marker in Editor.Document.GetTextSegmentMarkersAt (offset)) { + foreach (var marker in Editor.GetTextSegmentMarkersAt (offset)) { if (token.IsCancellationRequested) break; - var resultMarker = marker as ResultMarker; - if (resultMarker != null) - list.Add (resultMarker.Result); + var resultMarker = marker as IGenericTextSegmentMarker; + if (resultMarker != null && resultMarker.Tag is Result) + list.Add (resultMarker.Tag as Result); } return list; } public IEnumerable<Result> GetResults () { - return markers.Select (m => m.Result); + return markers.Select (m => m.Tag).OfType<Result> (); } #region IQuickTaskProvider implementation |