From 56a582932961ae0142f43e1a15fc33808b2f82d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kon=C3=AD=C4=8Dek?= Date: Tue, 27 Apr 2010 18:18:14 +0000 Subject: [PATCH] Implemented CaretReferencesRenderer - highlighting of all references to symbol under caret in the editor (VS2010 like). Please provide feedback (usefulness, performance, highlight color, ...) It should have no effect on editor performance - when moving caret by holding an arrow in the editor, nothing gets executed. After the caret stops for 100ms at one place, expression under caret is resolved to e.g. hide current highlight if no expression is under caret. Then, if the caret stays in place for 1000ms, "Find references in current document" is executed (on the main thread, but it's quite fast, maybe could be moved to background thread). The timeouts are done using two DispatcherTimers. Added "Find references in given document" (RefactoringService.FindReferencesLocal) to RefactoringService. Refactored RefactoringService a bit, but public API and its behavior stays unchanged. Fixed comment of DebuggerService.HandleToolTipRequest. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5725 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Debugger.AddIn/Debugger.AddIn.addin | 13 -- .../AvalonEdit.AddIn/AvalonEdit.AddIn.csproj | 2 + .../Src/CaretReferencesRenderer.cs | 123 ++++++++++++++++++ .../AvalonEdit.AddIn/Src/CodeEditorView.cs | 30 +++-- .../Src/ExpressionHighlightRenderer.cs | 80 ++++++++++++ .../Src/ToolTips/ResourceToolTipProvider.cs | 2 +- .../Project/Src/SwitchBodySnippetElement.cs | 8 +- .../Src/Editor/ToolTipRequestEventArgs.cs | 4 +- .../Src/Services/Debugger/DebuggerService.cs | 10 +- .../Services/ParserService/ParserService.cs | 26 +++- .../RefactoringService/RefactoringService.cs | 55 +++++--- 11 files changed, 302 insertions(+), 51 deletions(-) create mode 100644 src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs create mode 100644 src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ExpressionHighlightRenderer.cs diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin index a0219c4c68..d9056d6151 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin +++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin @@ -162,19 +162,6 @@ - - - - - - - - - + ChooseEncodingDialog.xaml Code @@ -87,6 +88,7 @@ + diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs new file mode 100644 index 0000000000..4607b5708b --- /dev/null +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs @@ -0,0 +1,123 @@ +// +// +// +// +// $Revision: $ +// +using System; +using System.Collections.Generic; +using System.Windows.Threading; + +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Refactoring; + +namespace ICSharpCode.AvalonEdit.AddIn +{ + /// + /// Description of CaretReferencesRenderer. + /// + public class CaretReferencesRenderer + { + /// + /// Delays the highlighting after the caret position changes, so that Find references does not get called too often. + /// + DispatcherTimer delayTimer; + const int delayMilliseconds = 1000; + DispatcherTimer delayMoveTimer; + const int delayMoveMilliseconds = 100; + + CodeEditorView editorView; + ITextEditor Editor { get { return editorView.Adapter; } } + + ExpressionHighlightRenderer highlightRenderer; + ResolveResult lastResolveResult; + + public CaretReferencesRenderer(CodeEditorView editorView) + { + this.editorView = editorView; + this.highlightRenderer = new ExpressionHighlightRenderer(this.editorView.TextArea.TextView); + this.delayTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(delayMilliseconds) }; + this.delayTimer.Stop(); + this.delayTimer.Tick += TimerTick; + this.delayMoveTimer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(delayMoveMilliseconds) }; + this.delayMoveTimer.Stop(); + this.delayMoveTimer.Tick += TimerMoveTick; + this.editorView.TextArea.Caret.PositionChanged += CaretPositionChanged; + } + + void TimerTick(object sender, EventArgs e) + { + this.delayTimer.Stop(); + LoggingService.Info("tick"); + // almost the same as DebuggerService.HandleToolTipRequest + var referencesToBeHighlighted = GetReferencesInCurrentFile(this.lastResolveResult); + this.highlightRenderer.SetHighlight(referencesToBeHighlighted); + } + + void TimerMoveTick(object sender, EventArgs e) + { + LoggingService.Debug("move"); + this.delayMoveTimer.Stop(); + this.delayTimer.Stop(); + var resolveResult = GetExpressionUnderCaret(); + if (resolveResult == null) { + this.lastResolveResult = resolveResult; + this.highlightRenderer.ClearHighlight(); + return; + } + // caret is over symbol and that symbol is different from the last time + if (!SameResolveResult(resolveResult, lastResolveResult)) + { + this.lastResolveResult = resolveResult; + this.highlightRenderer.ClearHighlight(); + this.delayTimer.Start(); + } + } + + /// + /// In the current document, highlights all references to the expression + /// which is currently under the caret (local variable, class, property). + /// This gets called on every caret position change, so quite often. + /// + void CaretPositionChanged(object sender, EventArgs e) + { + this.delayMoveTimer.Stop(); + this.delayMoveTimer.Start(); + } + + /// + /// Resolves the current expression under caret. + /// This gets called on every caret position change, so quite often. + /// + ResolveResult GetExpressionUnderCaret() + { + if (string.IsNullOrEmpty(Editor.FileName) || ParserService.LoadSolutionProjectsThreadRunning) + return null; + int line = Editor.Caret.Position.Line; + int column = Editor.Caret.Position.Column; + return ParserService.Resolve(line, column, Editor.Document, Editor.FileName); + } + + /// + /// Finds references to resolved expression in the current file. + /// + List GetReferencesInCurrentFile(ResolveResult resolveResult) + { + var references = RefactoringService.FindReferencesLocal(resolveResult, Editor.FileName, null); + if (references == null || references.Count == 0) + return null; + return references; + } + + /// + /// Returns true if the 2 ResolveResults refer to the same symbol. + /// + bool SameResolveResult(ResolveResult resolveResult, ResolveResult resolveResult2) + { + return false; + } + } +} diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs index d4cf259340..0b706ed66d 100755 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs @@ -41,6 +41,7 @@ namespace ICSharpCode.AvalonEdit.AddIn public ITextEditor Adapter { get; set; } BracketHighlightRenderer bracketRenderer; + CaretReferencesRenderer caretReferencesRenderer; public CodeEditorView() { @@ -48,19 +49,16 @@ namespace ICSharpCode.AvalonEdit.AddIn UpdateCustomizedHighlighting(); - bracketRenderer = new BracketHighlightRenderer(this.TextArea.TextView); + this.bracketRenderer = new BracketHighlightRenderer(this.TextArea.TextView); + this.caretReferencesRenderer = new CaretReferencesRenderer(this); this.MouseHover += TextEditorMouseHover; this.MouseHoverStopped += TextEditorMouseHoverStopped; this.MouseLeave += TextEditorMouseLeave; this.TextArea.TextView.MouseDown += TextViewMouseDown; - this.TextArea.Caret.PositionChanged += CaretPositionChanged; + this.TextArea.Caret.PositionChanged += HighlightBrackets; - var editingKeyBindings = this.TextArea.DefaultInputHandler.Editing.InputBindings.OfType(); - var tabBinding = editingKeyBindings.Single(b => b.Key == Key.Tab && b.Modifiers == ModifierKeys.None); - this.TextArea.DefaultInputHandler.Editing.InputBindings.Remove(tabBinding); - var newTabBinding = new KeyBinding(new CustomTabCommand(this, tabBinding.Command), tabBinding.Key, tabBinding.Modifiers); - this.TextArea.DefaultInputHandler.Editing.InputBindings.Add(newTabBinding); + SetUpTabSnippetHandler(); } protected override string FileName { @@ -71,13 +69,16 @@ namespace ICSharpCode.AvalonEdit.AddIn { base.OnOptionChanged(e); if (e.PropertyName == "HighlightBrackets") - CaretPositionChanged(null, e); + HighlightBrackets(null, e); else if (e.PropertyName == "EnableFolding") UpdateParseInformation(); } #region CaretPositionChanged - Bracket Highlighting - void CaretPositionChanged(object sender, EventArgs e) + /// + /// Highlights matching brackets. + /// + void HighlightBrackets(object sender, EventArgs e) { if (CodeEditorOptions.Instance.HighlightBrackets) { /* @@ -97,6 +98,15 @@ namespace ICSharpCode.AvalonEdit.AddIn #endregion #region Custom Tab command (code snippet expansion) + void SetUpTabSnippetHandler() + { + var editingKeyBindings = this.TextArea.DefaultInputHandler.Editing.InputBindings.OfType(); + var tabBinding = editingKeyBindings.Single(b => b.Key == Key.Tab && b.Modifiers == ModifierKeys.None); + this.TextArea.DefaultInputHandler.Editing.InputBindings.Remove(tabBinding); + var newTabBinding = new KeyBinding(new CustomTabCommand(this, tabBinding.Command), tabBinding.Key, tabBinding.Modifiers); + this.TextArea.DefaultInputHandler.Editing.InputBindings.Add(newTabBinding); + } + sealed class CustomTabCommand : ICommand { CodeEditorView editor; @@ -202,7 +212,7 @@ namespace ICSharpCode.AvalonEdit.AddIn ITextMarker markerWithToolTip = markersAtOffset.FirstOrDefault(marker => marker.ToolTip != null); if (markerWithToolTip != null) { - args.ShowToolTip(markerWithToolTip.ToolTip); + args.SetToolTip(markerWithToolTip.ToolTip); } } diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ExpressionHighlightRenderer.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ExpressionHighlightRenderer.cs new file mode 100644 index 0000000000..648cc68650 --- /dev/null +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ExpressionHighlightRenderer.cs @@ -0,0 +1,80 @@ +// +// +// +// +// $Revision: $ +// +using System; +using System.Diagnostics; +using System.Windows.Media; +using System.Collections.Generic; + +using ICSharpCode.AvalonEdit.Document; +using ICSharpCode.AvalonEdit.Rendering; +using ICSharpCode.SharpDevelop.Editor; +using ICSharpCode.SharpDevelop.Refactoring; + +namespace ICSharpCode.AvalonEdit.AddIn +{ + /// + /// Highlights expressions (references to expression under current caret). + /// + public class ExpressionHighlightRenderer : IBackgroundRenderer + { + List renderedReferences; + Pen borderPen; + Brush backgroundBrush; + TextView textView; + + public void SetHighlight(List renderedReferences) + { + if (this.renderedReferences != renderedReferences) { + this.renderedReferences = renderedReferences; + textView.InvalidateLayer(this.Layer); + } + } + + public void ClearHighlight() + { + this.SetHighlight(null); + } + + public ExpressionHighlightRenderer(TextView textView) + { + if (textView == null) + throw new ArgumentNullException("textView"); + //this.borderPen = new Pen(new SolidColorBrush(Color.FromRgb(70, 230, 70)), 1); + this.borderPen = new Pen(Brushes.Transparent, 1); + this.borderPen.Freeze(); + this.backgroundBrush = new SolidColorBrush(Color.FromArgb(120, 60, 255, 60)); + this.backgroundBrush.Freeze(); + this.textView = textView; + this.textView.BackgroundRenderers.Add(this); + } + + public KnownLayer Layer { + get { + return KnownLayer.Selection; + } + } + + public void Draw(TextView textView, DrawingContext drawingContext) + { + if (this.renderedReferences == null) + return; + BackgroundGeometryBuilder builder = new BackgroundGeometryBuilder(); + builder.CornerRadius = 1; + builder.AlignToMiddleOfPixels = true; + foreach (var reference in this.renderedReferences) { + builder.AddSegment(textView, new TextSegment() { + StartOffset = reference.Offset, + Length = reference.Length }); + builder.CloseFigure(); + } + Geometry geometry = builder.CreateGeometry(); + if (geometry != null) { + drawingContext.DrawGeometry(backgroundBrush, borderPen, geometry); + } + } + } +} diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/ToolTips/ResourceToolTipProvider.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/ToolTips/ResourceToolTipProvider.cs index 156486f716..a1960add72 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/ToolTips/ResourceToolTipProvider.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/ToolTips/ResourceToolTipProvider.cs @@ -31,7 +31,7 @@ namespace Hornung.ResourceToolkit.ToolTips ResourceResolveResult result = ResourceResolverService.Resolve(e.Editor.FileName, doc, logicPos.Y - 1, logicPos.X - 1, null); if (result != null && result.ResourceFileContent != null) { - e.ShowToolTip(ResourceResolverService.FormatResourceDescription(result.ResourceFileContent, result.Key)); + e.SetToolTip(ResourceResolverService.FormatResourceDescription(result.ResourceFileContent, result.Key)); } } diff --git a/src/AddIns/Misc/SharpRefactoring/Project/Src/SwitchBodySnippetElement.cs b/src/AddIns/Misc/SharpRefactoring/Project/Src/SwitchBodySnippetElement.cs index 533393d091..35e714e2ef 100644 --- a/src/AddIns/Misc/SharpRefactoring/Project/Src/SwitchBodySnippetElement.cs +++ b/src/AddIns/Misc/SharpRefactoring/Project/Src/SwitchBodySnippetElement.cs @@ -184,7 +184,7 @@ namespace SharpRefactoring /// Assuming that interactive mode of 'switch' snippet has currently finished in context, /// returns the switch condition that user entered. /// - string GetSwitchConditionText(InsertionContext context, out int startOffset) + string GetSwitchConditionText(InsertionContext context, out int conditionEndOffset) { var snippetActiveElements = context.ActiveElements.ToList(); if (snippetActiveElements.Count == 0) @@ -194,17 +194,17 @@ namespace SharpRefactoring throw new InvalidOperationException("Switch snippet condition should be " + typeof(IReplaceableActiveElement).Name); if (switchConditionElement.Segment == null) throw new InvalidOperationException("Swith condition should have a start offset"); - startOffset = switchConditionElement.Segment.EndOffset - 1; + conditionEndOffset = switchConditionElement.Segment.EndOffset - 1; return switchConditionElement.Text; } /// /// Resolves the Dom.IReturnType of expression ending at offset, ie. the switch condition expression. /// - IReturnType ResolveConditionType(string conditionExpression, int offset) + IReturnType ResolveConditionType(string conditionExpression, int conditionEndOffset) { ExpressionResult expressionResult = new ExpressionResult(conditionExpression); - Location location = this.Editor.Document.OffsetToPosition(offset); + Location location = this.Editor.Document.OffsetToPosition(conditionEndOffset); var result = ParserService.Resolve(expressionResult, location.Line, location.Column, this.Editor.FileName, this.Editor.Document.Text); return result.ResolvedType; } diff --git a/src/Main/Base/Project/Src/Editor/ToolTipRequestEventArgs.cs b/src/Main/Base/Project/Src/Editor/ToolTipRequestEventArgs.cs index e192ec7dfc..495ec920cb 100644 --- a/src/Main/Base/Project/Src/Editor/ToolTipRequestEventArgs.cs +++ b/src/Main/Base/Project/Src/Editor/ToolTipRequestEventArgs.cs @@ -38,9 +38,9 @@ namespace ICSharpCode.SharpDevelop.Editor public object ContentToShow { get; set; } /// - /// Shows the tool tip. + /// Sets the tooltip to be shown. /// - public void ShowToolTip(object content) + public void SetToolTip(object content) { if (content == null) throw new ArgumentNullException("content"); diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index 71973927fb..614bcd6146 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -246,9 +246,9 @@ namespace ICSharpCode.SharpDevelop.Debugging #region Tool tips /// /// Gets debugger tooltip information for the specified position. - /// A descriptive text for the element or a DebuggerGridControl + /// A descriptive string for the element or a DebuggerTooltipControl /// showing its current value (when in debugging mode) can be returned - /// through the ToolTipInfo object. + /// through the ToolTipRequestEventArgs.SetTooltip() method. /// internal static void HandleToolTipRequest(ToolTipRequestEventArgs e) { @@ -276,15 +276,15 @@ namespace ICSharpCode.SharpDevelop.Debugging } if (toolTipText != null) { if (debuggerCanShowValue && currentDebugger != null) { - e.ShowToolTip(currentDebugger.GetTooltipControl(expressionResult.Expression)); + e.SetToolTip(currentDebugger.GetTooltipControl(expressionResult.Expression)); } else { - e.ShowToolTip(toolTipText); + e.SetToolTip(toolTipText); } } } else { #if DEBUG if (Control.ModifierKeys == Keys.Control) { - e.ShowToolTip("no expr: " + expressionResult.ToString()); + e.SetToolTip("no expr: " + expressionResult.ToString()); } #endif } diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs index b66524bd00..591b574928 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs @@ -182,7 +182,7 @@ namespace ICSharpCode.SharpDevelop } #endregion - #region GetParser / ExpressionFinder /etc. + #region GetParser / ExpressionFinder / Resolve / etc. static readonly string[] DefaultTaskListTokens = {"HACK", "TODO", "UNDONE", "FIXME"}; /// @@ -238,6 +238,9 @@ namespace ICSharpCode.SharpDevelop return null; } + /// + /// Resolves given ExpressionResult. + /// public static ResolveResult Resolve(ExpressionResult expressionResult, int caretLineNumber, int caretColumn, string fileName, string fileContent) @@ -252,6 +255,27 @@ namespace ICSharpCode.SharpDevelop } return null; } + + /// + /// Resolves expression at given position. + /// That is, finds ExpressionResult at that position and + /// calls the overload Resolve(ExpressionResult,...). + /// + public static ResolveResult Resolve(int caretLine, int caretColumn, IDocument document, string fileName) + { + IExpressionFinder expressionFinder = GetExpressionFinder(fileName); + if (expressionFinder == null) + return null; + if (caretColumn > document.GetLine(caretLine).Length) + return null; + string documentText = document.Text; + var expressionResult = expressionFinder.FindFullExpression(documentText, document.PositionToOffset(caretLine, caretColumn)); + string expression = (expressionResult.Expression ?? "").Trim(); + if (expression.Length > 0) { + return Resolve(expressionResult, caretLine, caretColumn, fileName, documentText); + } else + return null; + } #endregion #region GetParseableFileContent diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs index 9eedc19290..75cdbb8267 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs @@ -88,54 +88,78 @@ namespace ICSharpCode.SharpDevelop.Refactoring /// Find all references to the specified member. /// public static List FindReferences(IMember member, IProgressMonitor progressMonitor) + { + return FindReferences(member, null, progressMonitor); + } + + static List FindReferences(IMember member, string fileName, IProgressMonitor progressMonitor) { if (member == null) throw new ArgumentNullException("member"); - return RunFindReferences(member.DeclaringType, member, false, progressMonitor); + return RunFindReferences(member.DeclaringType, member, fileName, progressMonitor); } /// /// Find all references to the specified class. /// public static List FindReferences(IClass @class, IProgressMonitor progressMonitor) + { + return FindReferences(@class, null, progressMonitor); + } + + static List FindReferences(IClass @class, string fileName, IProgressMonitor progressMonitor) { if (@class == null) throw new ArgumentNullException("class"); - return RunFindReferences(@class, null, false, progressMonitor); + return RunFindReferences(@class, null, fileName, progressMonitor); } /// /// Find all references to the resolved entity. /// public static List FindReferences(ResolveResult entity, IProgressMonitor progressMonitor) + { + return FindReferences(entity, null, progressMonitor); + } + + /// + /// Finds all references to the resolved entity, only in the file where the entity was resolved. + /// + public static List FindReferencesLocal(ResolveResult entity, string fileName, IProgressMonitor progressMonitor) + { + return FindReferences(entity, fileName, progressMonitor); + } + + static List FindReferences(ResolveResult entity, string fileName, IProgressMonitor progressMonitor) { if (entity == null) throw new ArgumentNullException("entity"); if (entity is LocalResolveResult) { - return RunFindReferences(entity.CallingClass, (entity as LocalResolveResult).Field, true, progressMonitor); + return RunFindReferences(entity.CallingClass, (entity as LocalResolveResult).Field, + entity.CallingClass.CompilationUnit.FileName, progressMonitor); } else if (entity is TypeResolveResult) { - return FindReferences((entity as TypeResolveResult).ResolvedClass, progressMonitor); + return FindReferences((entity as TypeResolveResult).ResolvedClass, fileName, progressMonitor); } else if (entity is MemberResolveResult) { - return FindReferences((entity as MemberResolveResult).ResolvedMember, progressMonitor); + return FindReferences((entity as MemberResolveResult).ResolvedMember, fileName, progressMonitor); } else if (entity is MethodGroupResolveResult) { IMethod method = (entity as MethodGroupResolveResult).GetMethodIfSingleOverload(); if (method != null) { - return FindReferences(method, progressMonitor); + return FindReferences(method, fileName, progressMonitor); } } else if (entity is MixedResolveResult) { - return FindReferences((entity as MixedResolveResult).PrimaryResult, progressMonitor); + return FindReferences((entity as MixedResolveResult).PrimaryResult, fileName, progressMonitor); } return null; } /// /// This method can be used in three modes: - /// 1. Find references to classes (parentClass = targetClass, member = null, isLocal = false) - /// 2. Find references to members (parentClass = parent, member = member, isLocal = false) - /// 3. Find references to local variables (parentClass = parent, member = local var as field, isLocal = true) + /// 1. Find references to classes (parentClass = targetClass, member = null, fileName = null) + /// 2. Find references to members (parentClass = parent, member = member, fileName = null) + /// 3. Find references to local variables (parentClass = parent, member = local var as field, fileName = parent.CompilationUnit.FileName) /// static List RunFindReferences(IClass ownerClass, IMember member, - bool isLocal, + string fileName, IProgressMonitor progressMonitor) { if (ParserService.LoadSolutionProjectsThreadRunning) { @@ -145,10 +169,12 @@ namespace ICSharpCode.SharpDevelop.Refactoring return null; } List files; - if (isLocal) { + if (!string.IsNullOrEmpty(fileName)) { + // search just in given file files = new List(); - files.Add(FindItem(ownerClass.CompilationUnit.FileName)); + files.Add(FindItem(fileName)); } else { + // search in all possible files ownerClass = ownerClass.GetCompoundClass(); files = GetPossibleFiles(ownerClass, member); } @@ -169,7 +195,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring ITextBuffer content = entry.GetContent(); if (content != null) { - AddReferences(references, ownerClass, member, isLocal, entry.FileName, content.Text); + AddReferences(references, ownerClass, member, entry.FileName, content.Text); } } @@ -181,7 +207,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring /// static void AddReferences(List list, IClass parentClass, IMember member, - bool isLocal, string fileName, string fileContent) { TextFinder textFinder; // the class used to find the position to resolve