Browse Source

Context actions optimization - removed one unnecessary call to EditorContext ctor.

pull/14/head
mkonicek 15 years ago
parent
commit
62a6e2cd99
  1. 34
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs
  2. 11
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs
  3. 2
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs

34
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs

@ -22,15 +22,22 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -22,15 +22,22 @@ namespace ICSharpCode.AvalonEdit.AddIn
public class CaretReferencesRenderer
{
/// <summary>
/// Delays the highlighting after the caret position changes, so that Find references does not get called too often.
/// Delays the Resolve check so that it does not get called too often when user holds an arrow.
/// </summary>
DispatcherTimer delayMoveTimer;
const int delayMoveMs = 100;
/// <summary>
/// Delays the Find references (and highlight) after the caret stays at one point for a while.
/// </summary>
DispatcherTimer delayTimer;
const int delayMilliseconds = 800;
const int delayMs = 800;
/// <summary>
/// Delays the Resolve check so that it does not get called too often when user holds an arrow.
/// Maximum time for Find references. After this time it gets cancelled and no highlight is displayed.
/// Useful for very large files.
/// </summary>
DispatcherTimer delayMoveTimer;
const int delayMoveMilliseconds = 100;
const int findReferencesTimeoutMs = 200;
CodeEditorView editorView;
ITextEditor Editor { get { return editorView.Adapter; } }
@ -53,10 +60,10 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -53,10 +60,10 @@ namespace ICSharpCode.AvalonEdit.AddIn
{
this.editorView = editorView;
this.highlightRenderer = new ExpressionHighlightRenderer(this.editorView.TextArea.TextView);
this.delayTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(delayMilliseconds) };
this.delayTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(delayMs) };
this.delayTimer.Stop();
this.delayTimer.Tick += TimerTick;
this.delayMoveTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(delayMoveMilliseconds) };
this.delayMoveTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(delayMoveMs) };
this.delayMoveTimer.Stop();
this.delayMoveTimer.Tick += TimerMoveTick;
this.editorView.TextArea.Caret.PositionChanged += CaretPositionChanged;
@ -73,7 +80,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -73,7 +80,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (!IsEnabled)
return;
var referencesToBeHighlighted = GetReferencesInCurrentFile(this.lastResolveResult);
var referencesToBeHighlighted = FindReferencesInCurrentFile(this.lastResolveResult);
this.highlightRenderer.SetHighlight(referencesToBeHighlighted);
}
@ -85,7 +92,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -85,7 +92,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (!IsEnabled)
return;
var resolveResult = GetExpressionUnderCaret();
var resolveResult = GetExpressionAtCaret();
if (resolveResult == null) {
this.lastResolveResult = resolveResult;
this.highlightRenderer.ClearHighlight();
@ -115,7 +122,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -115,7 +122,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
/// Resolves the current expression under caret.
/// This gets called on every caret position change, so quite often.
/// </summary>
ResolveResult GetExpressionUnderCaret()
ResolveResult GetExpressionAtCaret()
{
if (string.IsNullOrEmpty(Editor.FileName) || ParserService.LoadSolutionProjectsThreadRunning)
return null;
@ -127,14 +134,14 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -127,14 +134,14 @@ namespace ICSharpCode.AvalonEdit.AddIn
/// <summary>
/// Finds references to resolved expression in the current file.
/// </summary>
List<Reference> GetReferencesInCurrentFile(ResolveResult resolveResult)
List<Reference> FindReferencesInCurrentFile(ResolveResult resolveResult)
{
var cancellationTokenSource = new CancellationTokenSource();
using (new Timer(
delegate {
LoggingService.Debug("Aborting GetReferencesInCurrentFile due to timeout");
LoggingService.Debug("Aborting FindReferencesInCurrentFile due to timeout");
cancellationTokenSource.Cancel();
}, null, 200, Timeout.Infinite))
}, null, findReferencesTimeoutMs, Timeout.Infinite))
{
var progressMonitor = new DummyProgressMonitor();
progressMonitor.CancellationToken = cancellationTokenSource.Token;
@ -147,6 +154,7 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -147,6 +154,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
/// <summary>
/// Returns true if the 2 ResolveResults refer to the same symbol.
/// So that when caret moves but stays inside the same symbol, symbol stays highlighted.
/// </summary>
bool SameResolveResult(ResolveResult resolveResult, ResolveResult resolveResult2)
{

11
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs

@ -59,7 +59,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -59,7 +59,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{
ITextEditor editor { get; set; }
IList<IContextActionsProvider> providers { get; set; }
EditorContext context { get; set; }
public EditorActionsProvider(ITextEditor editor, IList<IContextActionsProvider> providers)
{
@ -70,7 +69,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -70,7 +69,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring
this.editor = editor;
this.providers = providers;
ParserService.ParseCurrentViewContent();
this.context = new EditorContext(editor);
}
public IEnumerable<IContextAction> GetVisibleActions()
@ -104,11 +102,16 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -104,11 +102,16 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{
if (ParserService.LoadSolutionProjectsThreadRunning)
yield break;
// Not necessary to reparse here because the ContextActionsRenderer timeout
// is large enough for the standard parser to finish first - not completely reliable, but saves one full reparse.
// In case the standard parser does not finish in time, the DOM is a little outdated but nothing bad happens
// (context action can just display an old class/method).
// DO NOT USE Wait on the main thread!
// causes deadlocks!
//parseTask.Wait();
// parseTask.Wait();
var sw = new Stopwatch(); sw.Start();
// var sw = new Stopwatch(); sw.Start();
var editorContext = new EditorContext(this.editor);
long elapsedEditorContextMs = sw.ElapsedMilliseconds;

2
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs

@ -200,7 +200,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -200,7 +200,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
ExpressionResult GetExpressionAtCaret(ITextEditor editor)
{
ExpressionResult expr = ParserService.FindFullExpression(CaretLine, CaretColumn, editor.Document, editor.FileName);
// if no expression, look one character back (works better with method calls - Foo()(*caret*))
// if no expression, look one character back (works better with method calls, e.g. Foo()(*caret*))
if (string.IsNullOrWhiteSpace(expr.Expression) && CaretColumn > 1)
expr = ParserService.FindFullExpression(CaretLine, CaretColumn - 1, editor.Document, editor.FileName);
return expr;

Loading…
Cancel
Save