From c51c4a525d7b195bc3f58e37494c47451939d968 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 20 Dec 2010 19:32:18 +0100 Subject: [PATCH 1/8] fixed SD-1725 - BadImageFormatException when profiling .NET 4 WinForms application --- .../Profiler/Hook/Profiler.Rewriting.cpp | 42 ++++++++++++++++--- .../Analysis/Profiler/Hook/Profiler.cpp | 2 +- .../Analysis/Profiler/Hook/constants.cpp | 15 ++++--- src/AddIns/Analysis/Profiler/Hook/global.h | 6 ++- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/AddIns/Analysis/Profiler/Hook/Profiler.Rewriting.cpp b/src/AddIns/Analysis/Profiler/Hook/Profiler.Rewriting.cpp index 5fe3745760..0ce96264b5 100644 --- a/src/AddIns/Analysis/Profiler/Hook/Profiler.Rewriting.cpp +++ b/src/AddIns/Analysis/Profiler/Hook/Profiler.Rewriting.cpp @@ -194,10 +194,6 @@ int CProfiler::SetInjectionCode(IMetaDataImport *metaData, byte *buffer, int *si buffer[(*size)++] = 0x14; //ldnull break; case 2: // Windows Forms - buffer[(*size)++] = 0x14; //ldnull - buffer[(*size)++] = 0x14; //ldnull - break; - /* hr = metaData->FindTypeDefByName(L"System.Windows.Forms.Control", nullptr, &controlType); if (!SUCCEEDED(hr) || controlType == 0) { @@ -234,7 +230,7 @@ int CProfiler::SetInjectionCode(IMetaDataImport *metaData, byte *buffer, int *si buffer[(*size)++] = 0x6F; //callvirt *(mdMethodDef*)(&buffer[*size]) = getTextToken; *size += sizeof(getTextToken); - break;*/ + break; case 3: // WPF buffer[(*size)++] = 0x14; //ldnull buffer[(*size)++] = 0x14; //ldnull @@ -318,6 +314,42 @@ STDMETHODIMP CProfiler::ModuleLoadFinished(ModuleID moduleID, HRESULT /*hrStatus IMetaDataEmit *pIMetaDataEmit = nullptr; IMetaDataAssemblyImport *asmMetaData = nullptr; + WCHAR moduleName[NAME_BUFFER_SIZE]; + WCHAR assemblyName[NAME_BUFFER_SIZE]; + + AssemblyID assemblyID; + + ULONG actualLen = 0; + + hr = pICorProfilerInfo->GetModuleInfo(moduleID, nullptr, NAME_BUFFER_SIZE, &actualLen, moduleName, &assemblyID); + + if (!SUCCEEDED(hr)) + goto CLEANUP; + + hr = pICorProfilerInfo->GetAssemblyInfo(assemblyID, NAME_BUFFER_SIZE, &actualLen, assemblyName, nullptr, nullptr); + + if (!SUCCEEDED(hr)) + goto CLEANUP; + + DebugWriteLine(L"\n----------------- Module Load finished -----------------\n"); + DebugWriteLine(L"Module Name: '%s'\n", moduleName); + DebugWriteLine(L"Assembly Name: '%s'\n", assemblyName); + DebugWriteLine(L"--------------------------------------------------------\n"); + + bool found = false; + + for (int i = 0; i < ASSEMBLY_INJECTION_NAME_LIST_LENGTH; i++) { + if (wcscmp(assemblyInjectionNameList[i], assemblyName) == 0) { + found = true; + break; + } + } + + if (!found) { + DebugWriteLine(L"Assembly Name '%s' not found in list!\n", assemblyName); + goto CLEANUP; + } + hr = pICorProfilerInfo->GetModuleMetaData(moduleID, ofRead | ofWrite, IID_IMetaDataEmit, (LPUNKNOWN *) &pIMetaDataEmit); if (!SUCCEEDED(hr) || pIMetaDataEmit == nullptr) diff --git a/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp b/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp index 88cf77d3ce..81fa05e6d8 100644 --- a/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp +++ b/src/AddIns/Analysis/Profiler/Hook/Profiler.cpp @@ -378,7 +378,7 @@ HRESULT CProfiler::SetEventMask() { COR_PRF_MONITOR_FUNCTION_UNLOADS | COR_PRF_MONITOR_CLR_EXCEPTIONS | COR_PRF_MONITOR_EXCEPTIONS; if (sharedMemoryHeader->trackEvents) - eventMask = eventMask | COR_PRF_MONITOR_MODULE_LOADS/* | COR_PRF_MONITOR_JIT_COMPILATION*/; + eventMask = eventMask | COR_PRF_MONITOR_MODULE_LOADS | COR_PRF_MONITOR_JIT_COMPILATION; return pICorProfilerInfo->SetEventMask(eventMask); } diff --git a/src/AddIns/Analysis/Profiler/Hook/constants.cpp b/src/AddIns/Analysis/Profiler/Hook/constants.cpp index 2efe965039..b3d5badb1e 100644 --- a/src/AddIns/Analysis/Profiler/Hook/constants.cpp +++ b/src/AddIns/Analysis/Profiler/Hook/constants.cpp @@ -3,17 +3,22 @@ #include "global.h" +WCHAR *assemblyInjectionNameList[ASSEMBLY_INJECTION_NAME_LIST_LENGTH] = { + L"mscorlib", + L"System.Windows.Forms", + L"PresentationCore" +}; + WCHAR *consoleGroupList[CONSOLE_GROUP_LENGTH] = { L"System.Console.Write", L"System.Console.WriteLine" }; WCHAR *winFormsGroupList[WINFORMS_GROUP_LENGTH] = { - L"-------------------------------------------------", - // L"System.Windows.Forms.Control.OnClick", - // L"System.Windows.Forms.Control.OnDoubleClick", - // L"System.Windows.Forms.Control.OnMouseWheel", - // L"System.Windows.Forms.Control.OnKeyDown" + L"System.Windows.Forms.Control.OnClick", + L"System.Windows.Forms.Control.OnDoubleClick", + L"System.Windows.Forms.Control.OnMouseWheel", + L"System.Windows.Forms.Control.OnKeyDown" }; WCHAR *wpfGroupList[WPF_GROUP_LENGTH] = { diff --git a/src/AddIns/Analysis/Profiler/Hook/global.h b/src/AddIns/Analysis/Profiler/Hook/global.h index 2a63d2f3c6..5a40124037 100644 --- a/src/AddIns/Analysis/Profiler/Hook/global.h +++ b/src/AddIns/Analysis/Profiler/Hook/global.h @@ -10,8 +10,11 @@ #include "LightweightStack.h" #include "LightweightList.h" +#define NAME_BUFFER_SIZE 1024 + +#define ASSEMBLY_INJECTION_NAME_LIST_LENGTH 3 #define CONSOLE_GROUP_LENGTH 2 -#define WINFORMS_GROUP_LENGTH 1 +#define WINFORMS_GROUP_LENGTH 4 #define WPF_GROUP_LENGTH 1 extern fastAllocator stackAllocator; @@ -21,6 +24,7 @@ extern HANDLE listMutex; extern LightweightList *allThreadLocalDatas; extern DWORD tls_index; +extern WCHAR *assemblyInjectionNameList[ASSEMBLY_INJECTION_NAME_LIST_LENGTH]; extern WCHAR *consoleGroupList[CONSOLE_GROUP_LENGTH]; extern WCHAR *winFormsGroupList[WINFORMS_GROUP_LENGTH]; extern WCHAR *wpfGroupList[WPF_GROUP_LENGTH]; From 4c8a325a5ec1df483f54ab66b77fef12cd3b9a4f Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 21 Dec 2010 12:34:18 +0100 Subject: [PATCH 2/8] ProfilerView: bring errors pad to front only if there were errors executing the query. --- .../Frontend/AddIn/Src/Views/ProfilerView.xaml.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs index 5fe8cb1213..ee232948b8 100644 --- a/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs +++ b/src/AddIns/Analysis/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs @@ -106,9 +106,12 @@ namespace ICSharpCode.Profiler.AddIn.Views Dispatcher.Invoke( (Action)( () => { - WorkbenchSingleton.Workbench.GetPad(typeof(ErrorListPad)).BringPadToFront(); - TaskService.ClearExceptCommentTasks(); - TaskService.AddRange(errors.Select(error => new Task(null, error.ErrorText, error.Column, error.Line, (error.IsWarning) ? TaskType.Warning : TaskType.Error))); + var tasks = errors.Select(error => new Task(null, error.ErrorText, error.Column, error.Line, (error.IsWarning) ? TaskType.Warning : TaskType.Error)).ToList(); + if (tasks.Count > 0) { + WorkbenchSingleton.Workbench.GetPad(typeof(ErrorListPad)).BringPadToFront(); + TaskService.ClearExceptCommentTasks(); + TaskService.AddRange(tasks); + } } ) ); From 2a5459a0b93a8b169b045fbb6edf1c0e8ac75fa8 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 22 Dec 2010 15:52:06 +0100 Subject: [PATCH 3/8] Fixed ArgumentOutOfRangeException in CodeCoverageControl.OpenFile (http://community.sharpdevelop.net/forums/t/12456.aspx). --- .../CodeCoverage/Project/Src/CodeCoverageControl.cs | 6 +++--- .../AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs b/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs index 07340f6827..9c8a992284 100644 --- a/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs +++ b/src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageControl.cs @@ -240,7 +240,7 @@ namespace ICSharpCode.CodeCoverage CodeCoverageSequencePoint sequencePoint = methodNode.Method.SequencePoints[0]; if (sequencePoint.HasDocument()) { if (classNode == null) { - OpenFile(sequencePoint.Document, sequencePoint.Line - 1, sequencePoint.Column - 1); + OpenFile(sequencePoint.Document, sequencePoint.Line, sequencePoint.Column); } else { OpenFile(sequencePoint.Document, 1, 1); } @@ -310,8 +310,8 @@ namespace ICSharpCode.CodeCoverage textEditor.Load(fileName); } textEditor.ScrollToEnd(); - textEditor.TextArea.Caret.Line = line - 1; - textEditor.ScrollToLine(line - 1); + textEditor.TextArea.Caret.Location = new ICSharpCode.AvalonEdit.Document.TextLocation(line, column); + textEditor.ScrollToLine(line); CodeCoverageService.ShowCodeCoverage(new AvalonEditTextEditorAdapter(textEditor), fileName); } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs index 4152385319..1e9ca34fc9 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs @@ -1102,6 +1102,11 @@ namespace ICSharpCode.AvalonEdit TextView textView = textArea.TextView; TextDocument document = textView.Document; if (scrollViewer != null && document != null) { + if (line < 1) + line = 1; + if (line > document.LineCount) + line = document.LineCount; + IScrollInfo scrollInfo = textView; if (!scrollInfo.CanHorizontallyScroll) { // Word wrap is enabled. Ensure that we have up-to-date info about line height so that we scroll From 9359f9af74545ce78aa6f5fd8db89711c60b9492 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 22 Dec 2010 16:37:48 +0100 Subject: [PATCH 4/8] Name resolution fix: prefer using aliases over imported types. --- .../ProjectContent/DefaultProjectContent.cs | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs index b456855ff3..7a2bb518e2 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs @@ -815,7 +815,7 @@ namespace ICSharpCode.SharpDevelop.Dom return GetNamespaces(language).ContainsKey(name); } - bool MatchesRequest(ref SearchTypeRequest request, ref SearchTypeResult result) + bool MatchesRequest(SearchTypeRequest request, ref SearchTypeResult result) { if (result.NamespaceResult != null) return request.TypeParameterCount == 0; @@ -852,7 +852,7 @@ namespace ICSharpCode.SharpDevelop.Dom foreach (IClass innerClass in baseClass.InnerClasses) { if (language.NameComparer.Equals(innerClass.Name, name)) { result = new SearchTypeResult(innerClass); - if (MatchesRequest(ref request, ref result)) { + if (MatchesRequest(request, ref result)) { return result; } } @@ -873,50 +873,55 @@ namespace ICSharpCode.SharpDevelop.Dom IClass c = GetClass(fullname, request.TypeParameterCount); if (c != null) { result = new SearchTypeResult(c); - if (MatchesRequest(ref request, ref result)) { + if (MatchesRequest(request, ref result)) { return result; } } if (NamespaceExists(fullname)) { result = new SearchTypeResult(fullname, null); - if (MatchesRequest(ref request, ref result)) { + if (MatchesRequest(request, ref result)) { return result; } } + // prefer aliases over imported types foreach (IUsing u in usingScope.Usings) { - foreach (IReturnType r in u.SearchType(name, request.TypeParameterCount)) { - result = new SearchTypeResult(r, u); - if (MatchesRequest(ref request, ref result)) { + if (u.HasAliases) { + if (SearchTypeInUsing(u, request, ref result)) return result; - } } - string nsResult = u.SearchNamespace(name); - if (nsResult != null) { - result = new SearchTypeResult(nsResult, null); - if (MatchesRequest(ref request, ref result)) { + } + foreach (IUsing u in usingScope.Usings) { + if (!u.HasAliases) { + if (SearchTypeInUsing(u, request, ref result)) return result; - } } } } if (defaultImports != null) { - foreach (IReturnType r in defaultImports.SearchType(name, request.TypeParameterCount)) { - result = new SearchTypeResult(r, defaultImports); - if (MatchesRequest(ref request, ref result)) { - return result; - } + if (SearchTypeInUsing(defaultImports, request, ref result)); + return result; + } + return result; + } + + bool SearchTypeInUsing(IUsing u, SearchTypeRequest request, ref SearchTypeResult result) + { + foreach (IReturnType r in u.SearchType(request.Name, request.TypeParameterCount)) { + result = new SearchTypeResult(r, u); + if (MatchesRequest(request, ref result)) { + return true; } - string nsResult = defaultImports.SearchNamespace(name); - if (nsResult != null) { - result = new SearchTypeResult(nsResult, null); - if (MatchesRequest(ref request, ref result)) { - return result; - } + } + string nsResult = u.SearchNamespace(request.Name); + if (nsResult != null) { + result = new SearchTypeResult(nsResult, null); + if (MatchesRequest(request, ref result)) { + return true; } } - return result; + return false; } /// From 62a6e2cd990f4e3811ad94b5ea67ce4248c716ff Mon Sep 17 00:00:00 2001 From: mkonicek Date: Wed, 22 Dec 2010 23:37:55 +0100 Subject: [PATCH 5/8] Context actions optimization - removed one unnecessary call to EditorContext ctor. --- .../Src/CaretReferencesRenderer.cs | 34 ++++++++++++------- .../ContextActions/ContextActionsService.cs | 11 +++--- .../ContextActions/EditorContext.cs | 2 +- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs index 72bb3ac568..3f1ad478d8 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs @@ -22,15 +22,22 @@ namespace ICSharpCode.AvalonEdit.AddIn public class CaretReferencesRenderer { /// - /// 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. + /// + DispatcherTimer delayMoveTimer; + const int delayMoveMs = 100; + + /// + /// Delays the Find references (and highlight) after the caret stays at one point for a while. /// DispatcherTimer delayTimer; - const int delayMilliseconds = 800; + const int delayMs = 800; + /// - /// 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. /// - 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 { 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 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 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 /// Resolves the current expression under caret. /// This gets called on every caret position change, so quite often. /// - ResolveResult GetExpressionUnderCaret() + ResolveResult GetExpressionAtCaret() { if (string.IsNullOrEmpty(Editor.FileName) || ParserService.LoadSolutionProjectsThreadRunning) return null; @@ -127,14 +134,14 @@ namespace ICSharpCode.AvalonEdit.AddIn /// /// Finds references to resolved expression in the current file. /// - List GetReferencesInCurrentFile(ResolveResult resolveResult) + List 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 /// /// 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. /// bool SameResolveResult(ResolveResult resolveResult, ResolveResult resolveResult2) { diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs index 9a4506d666..816ac8831f 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs @@ -59,7 +59,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring { ITextEditor editor { get; set; } IList providers { get; set; } - EditorContext context { get; set; } public EditorActionsProvider(ITextEditor editor, IList providers) { @@ -70,7 +69,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring this.editor = editor; this.providers = providers; ParserService.ParseCurrentViewContent(); - this.context = new EditorContext(editor); } public IEnumerable GetVisibleActions() @@ -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; diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs index 32e37b15ba..693791e5d2 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs @@ -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; From 62cad95369f60f5f86a466986428536cd9c86bbe Mon Sep 17 00:00:00 2001 From: mkonicek Date: Wed, 22 Dec 2010 23:44:36 +0100 Subject: [PATCH 6/8] Fixed build. --- .../RefactoringService/ContextActions/ContextActionsService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs index 816ac8831f..2e3f91c2ed 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs @@ -113,7 +113,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring // var sw = new Stopwatch(); sw.Start(); var editorContext = new EditorContext(this.editor); - long elapsedEditorContextMs = sw.ElapsedMilliseconds; + // long elapsedEditorContextMs = sw.ElapsedMilliseconds; // could run providers in parallel foreach (var provider in providers) { From df5acd812d86927c69ef155834b0cb1de46b868f Mon Sep 17 00:00:00 2001 From: mkonicek Date: Thu, 23 Dec 2010 00:24:56 +0100 Subject: [PATCH 7/8] Added comments to CaretReferencesRenderer. --- .../Src/CaretReferencesRenderer.cs | 34 ++++++++++++------- .../ContextActions/ContextActionsService.cs | 3 ++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs index 3f1ad478d8..f8b4a9b5f0 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CaretReferencesRenderer.cs @@ -74,6 +74,16 @@ namespace ICSharpCode.AvalonEdit.AddIn this.highlightRenderer.ClearHighlight(); } + /// + /// 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) + { + Restart(this.delayMoveTimer); + } + void TimerTick(object sender, EventArgs e) { this.delayTimer.Stop(); @@ -94,7 +104,7 @@ namespace ICSharpCode.AvalonEdit.AddIn var resolveResult = GetExpressionAtCaret(); if (resolveResult == null) { - this.lastResolveResult = resolveResult; + this.lastResolveResult = null; this.highlightRenderer.ClearHighlight(); return; } @@ -104,20 +114,11 @@ namespace ICSharpCode.AvalonEdit.AddIn this.lastResolveResult = resolveResult; this.highlightRenderer.ClearHighlight(); this.delayTimer.Start(); + } else { + // highlight stays the same, both timers are stopped (will start again when caret moves) } } - /// - /// 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. @@ -167,5 +168,14 @@ namespace ICSharpCode.AvalonEdit.AddIn // TODO determine if 2 ResolveResults refer to the same symbol return false; } + + /// + /// Restarts a timer. + /// + void Restart(DispatcherTimer timer) + { + timer.Stop(); + timer.Start(); + } } } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs index 2e3f91c2ed..0f67e17b57 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs @@ -18,6 +18,9 @@ namespace ICSharpCode.SharpDevelop.Refactoring { private static ContextActionsService instance = new ContextActionsService(); + /// + /// Key for storing the names of disabled providers in PropertyService. + /// const string PropertyServiceKey = "DisabledContextActionProviders"; public static ContextActionsService Instance { From d8083e0ce5c1da1d76b7528d85ca3b33fefa88ba Mon Sep 17 00:00:00 2001 From: mkonicek Date: Thu, 23 Dec 2010 03:03:12 +0100 Subject: [PATCH 8/8] Fixed comment. --- .../ContextActions/ContextActionsService.cs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs index 0f67e17b57..2079edda7b 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs @@ -71,6 +71,10 @@ namespace ICSharpCode.SharpDevelop.Refactoring throw new ArgumentNullException("providers"); this.editor = editor; this.providers = providers; + // DO NOT USE Wait on the main thread! + // causes deadlocks! + // parseTask.Wait(); + // Reparse so that we have up-to-date DOM. ParserService.ParseCurrentViewContent(); } @@ -105,18 +109,7 @@ 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(); - - // var sw = new Stopwatch(); sw.Start(); var editorContext = new EditorContext(this.editor); - // long elapsedEditorContextMs = sw.ElapsedMilliseconds; // could run providers in parallel foreach (var provider in providers) { @@ -125,8 +118,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring yield return action; } } -// ICSharpCode.Core.LoggingService.Debug(string.Format("Context actions elapsed {0}ms ({1}ms in EditorContext)", -// sw.ElapsedMilliseconds, elapsedEditorContextMs)); } } }