Browse Source

Use PermanentAnchor for Tasks.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5029 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 16 years ago
parent
commit
5c5c4ff93c
  1. 12
      src/AddIns/BackendBindings/WixBinding/Project/Src/WixBindingService.cs
  2. 8
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs
  3. 9
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs
  4. 2
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs
  5. 2
      src/AddIns/Misc/CodeCoverage/Project/Src/RunTestWithCodeCoverageCommand.cs
  6. 2
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs
  7. 4
      src/AddIns/Misc/UnitTesting/Src/RunTestCommands.cs
  8. 2
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Util/WeakCollection.cs
  9. 51
      src/Main/Base/Project/Src/Editor/PermanentAnchor.cs
  10. 2
      src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskView.cs
  11. 12
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
  12. 14
      src/Main/Base/Project/Src/Services/Tasks/ErrorPainter.cs
  13. 77
      src/Main/Base/Project/Src/Services/Tasks/Task.cs
  14. 33
      src/Main/Base/Project/Src/Services/Tasks/TaskService.cs
  15. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/ErrorDrawer.cs
  16. 10
      src/Main/Core/Project/Src/Services/FileUtility/FileName.cs
  17. 5
      src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

12
src/AddIns/BackendBindings/WixBinding/Project/Src/WixBindingService.cs

@ -13,12 +13,12 @@ using ICSharpCode.SharpDevelop.Gui; @@ -13,12 +13,12 @@ using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.WixBinding
{
public sealed class WixBindingService
public sealed class WixBindingService
{
WixBindingService()
{
}
/// <summary>
/// Clears the error list and the output messages.
/// </summary>
@ -43,7 +43,7 @@ namespace ICSharpCode.WixBinding @@ -43,7 +43,7 @@ namespace ICSharpCode.WixBinding
/// Adds an error to the error list.
/// </summary>
public static void AddErrorToErrorList(string fileName, Exception ex)
{
{
AddError(fileName, ex);
}
@ -67,11 +67,11 @@ namespace ICSharpCode.WixBinding @@ -67,11 +67,11 @@ namespace ICSharpCode.WixBinding
XmlException xmlEx = ex as XmlException;
if (xmlEx != null) {
column = xmlEx.LinePosition - 1;
line = xmlEx.LineNumber - 1;
column = xmlEx.LinePosition;
line = xmlEx.LineNumber;
}
LoggingService.Debug(ex.ToString());
TaskService.Add(new Task(fileName, ex.Message, column, line, TaskType.Error));
TaskService.Add(new Task(FileName.Create(fileName), ex.Message, column, line, TaskType.Error));
}
}
}

8
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditViewContent.cs

@ -95,11 +95,15 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -95,11 +95,15 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (!string.IsNullOrEmpty(oldFileName))
ParserService.ClearParseInformation(oldFileName);
BookmarksNotifyNameChange(oldFileName, newFileName);
// changing the filename on the codeEditor raises several events; ensure
// we got our state updated first (bookmarks, persistent anchors) before other code
// processes the file name change
codeEditor.FileName = newFileName;
ParserService.BeginParse(file.FileName, codeEditor.DocumentAdapter);
BookmarksNotifyNameChange(oldFileName, newFileName);
}
}

9
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditor.cs

@ -117,10 +117,11 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -117,10 +117,11 @@ namespace ICSharpCode.AvalonEdit.AddIn
if (secondaryTextEditorAdapter != null)
secondaryTextEditorAdapter.FileNameChanged();
if (this.errorPainter != null)
this.errorPainter.Dispose();
this.errorPainter = new ErrorPainter(primaryTextEditorAdapter);
if (this.errorPainter == null) {
this.errorPainter = new ErrorPainter(primaryTextEditorAdapter);
} else {
this.errorPainter.UpdateErrors();
}
FetchParseInformation();
}

2
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlView.cs

@ -209,7 +209,7 @@ namespace ICSharpCode.XmlEditor @@ -209,7 +209,7 @@ namespace ICSharpCode.XmlEditor
static void AddTask(string fileName, string message, int column, int line, TaskType taskType)
{
TaskService.Add(new Task(fileName, message, column, line, taskType));
TaskService.Add(new Task(FileName.Create(fileName), message, column, line, taskType));
}
#region XmlView methods

2
src/AddIns/Misc/CodeCoverage/Project/Src/RunTestWithCodeCoverageCommand.cs

@ -139,7 +139,7 @@ namespace ICSharpCode.CodeCoverage @@ -139,7 +139,7 @@ namespace ICSharpCode.CodeCoverage
void DisplayCoverageResults(string fileName)
{
if (!File.Exists(fileName)) {
Task task = new Task(String.Empty, String.Concat(StringParser.Parse("${res:ICSharpCode.CodeCoverage.NoCodeCoverageResultsGenerated}"), " ", fileName), 0, 0, TaskType.Error);
Task task = new Task(null, String.Concat(StringParser.Parse("${res:ICSharpCode.CodeCoverage.NoCodeCoverageResultsGenerated}"), " ", fileName), 0, 0, TaskType.Error);
WorkbenchSingleton.SafeThreadAsyncCall(TaskService.Add, task);
return;
}

2
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs

@ -117,7 +117,7 @@ namespace ICSharpCode.Profiler.AddIn.Views @@ -117,7 +117,7 @@ namespace ICSharpCode.Profiler.AddIn.Views
() => {
WorkbenchSingleton.Workbench.GetPad(typeof(ErrorListPad)).BringPadToFront();
TaskService.ClearExceptCommentTasks();
TaskService.AddRange(errors.Select(error => new Task("", error.ErrorText, error.Column, error.Line, (error.IsWarning) ? TaskType.Warning : TaskType.Error)));
TaskService.AddRange(errors.Select(error => new Task(null, error.ErrorText, error.Column, error.Line, (error.IsWarning) ? TaskType.Warning : TaskType.Error)));
}
)
);

4
src/AddIns/Misc/UnitTesting/Src/RunTestCommands.cs

@ -253,10 +253,10 @@ namespace ICSharpCode.UnitTesting @@ -253,10 +253,10 @@ namespace ICSharpCode.UnitTesting
lineRef = FindTest(result.Name);
}
if (lineRef != null) {
return new Task(Path.GetFullPath(lineRef.FileName),
return new Task(FileName.Create(lineRef.FileName),
message, lineRef.Column, lineRef.Line, taskType);
}
return new Task(String.Empty, message, 0, 0, taskType);
return new Task(null, message, 0, 0, taskType);
}
/// <summary>

2
src/Libraries/ICSharpCode.TextEditor/Project/Src/Util/WeakCollection.cs

@ -11,7 +11,7 @@ using System.Collections.Generic; @@ -11,7 +11,7 @@ using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Util
{
/// <summary>
/// A collection that does not allows its elements to be garbage-collected (unless there are other
/// A collection that allows its elements to be garbage-collected (unless there are other
/// references to the elements). Elements will disappear from the collection when they are
/// garbage-collected.
///

51
src/Main/Base/Project/Src/Editor/PermanentAnchor.cs

@ -80,6 +80,14 @@ namespace ICSharpCode.SharpDevelop.Editor @@ -80,6 +80,14 @@ namespace ICSharpCode.SharpDevelop.Editor
this.fileName = newName;
}
internal void FileDeleted()
{
Debug.Assert(currentDocument == null);
if (!surviveDeletion) {
baseAnchor_Deleted(null, EventArgs.Empty);
}
}
void baseAnchor_Deleted(object sender, EventArgs e)
{
isDeleted = true;
@ -174,7 +182,7 @@ namespace ICSharpCode.SharpDevelop.Editor @@ -174,7 +182,7 @@ namespace ICSharpCode.SharpDevelop.Editor
if (baseAnchor != null)
return baseAnchor.Column;
else
return line;
return column;
}
}
}
@ -193,6 +201,47 @@ namespace ICSharpCode.SharpDevelop.Editor @@ -193,6 +201,47 @@ namespace ICSharpCode.SharpDevelop.Editor
anchor.AttachTo(doc);
}
/// <summary>
/// Renames anchors without document.
/// </summary>
internal static void FileRenamed(FileRenameEventArgs e)
{
FileName sourceFile = new FileName(e.SourceFile);
FileName targetFile = new FileName(e.TargetFile);
foreach (PermanentAnchor anchor in permanentAnchors) {
if (anchor.CurrentDocument == null) {
if (e.IsDirectory) {
if (FileUtility.IsBaseDirectory(e.SourceFile, anchor.FileName)) {
anchor.SetFileName(new FileName(FileUtility.RenameBaseDirectory(anchor.FileName, e.SourceFile, e.TargetFile)));
}
} else {
if (anchor.FileName == sourceFile)
anchor.SetFileName(targetFile);
}
}
}
}
/// <summary>
/// Deletes anchors without document.
/// </summary>
internal static void FileDeleted(FileEventArgs e)
{
FileName fileName = new FileName(e.FileName);
foreach (PermanentAnchor anchor in permanentAnchors) {
if (anchor.CurrentDocument == null) {
if (e.IsDirectory) {
if (FileUtility.IsBaseDirectory(fileName, anchor.FileName))
anchor.FileDeleted();
} else {
if (fileName == anchor.FileName)
anchor.FileDeleted();
}
}
}
}
/// <summary>
/// Tells detached permanent anchors to attach to the specified text editor.
/// </summary>

2
src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskView.cs

@ -73,7 +73,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -73,7 +73,7 @@ namespace ICSharpCode.SharpDevelop.Gui
if (!string.IsNullOrEmpty(t.FileName)) {
b.Append(" - ");
b.Append(t.FileName);
if (t.Line >= 0) {
if (t.Line >= 1) {
b.Append(':');
b.Append(t.Line);
if (t.Column > 1) {

12
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -158,6 +158,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -158,6 +158,7 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
}
Editor.PermanentAnchorService.FileDeleted(e);
}
void CheckRenamedFile(object sender, FileRenameEventArgs e)
@ -169,15 +170,12 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -169,15 +170,12 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
} else {
foreach (OpenedFile file in FileService.OpenedFiles) {
if (file.FileName != null &&
FileUtility.IsEqualFileName(file.FileName, e.SourceFile))
{
file.FileName = new FileName(e.TargetFile);
return;
}
OpenedFile file = FileService.GetOpenedFile(e.SourceFile);
if (file != null) {
file.FileName = new FileName(e.TargetFile);
}
}
Editor.PermanentAnchorService.FileRenamed(e);
}
void UpdateMenu()

14
src/Main/Base/Project/Src/Services/Tasks/ErrorPainter.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.SharpDevelop @@ -40,7 +40,7 @@ namespace ICSharpCode.SharpDevelop
bool isDisposed;
/// <summary>
/// Deregisters the event handlers so the error drawer (and associated TextEditorControl)
/// Deregisters the event handlers so the error painter (and associated TextEditor)
/// can be garbage collected.
/// </summary>
public void Dispose()
@ -96,7 +96,7 @@ namespace ICSharpCode.SharpDevelop @@ -96,7 +96,7 @@ namespace ICSharpCode.SharpDevelop
{
if (textEditor.FileName == null)
return false;
if (task.FileName == null || task.FileName.Length == 0 || task.Column < 0)
if (task.FileName == null || task.Column <= 0)
return false;
if (task.TaskType != TaskType.Warning && task.TaskType != TaskType.Error)
return false;
@ -105,9 +105,13 @@ namespace ICSharpCode.SharpDevelop @@ -105,9 +105,13 @@ namespace ICSharpCode.SharpDevelop
void AddTask(Task task)
{
if (!CheckTask(task)) return;
if (DebuggerService.IsDebuggerLoaded && DebuggerService.CurrentDebugger.IsDebugging)
return;
if (!CheckTask(task))
return;
if (task.Line >= 0 && task.Line < textEditor.Document.TotalNumberOfLines) {
if (task.Line >= 1 && task.Line <= textEditor.Document.TotalNumberOfLines) {
LoggingService.Debug(task.ToString());
int offset = textEditor.Document.PositionToOffset(task.Line, task.Column);
int length = textEditor.Document.GetWordAt(offset).Length;
@ -144,6 +148,8 @@ namespace ICSharpCode.SharpDevelop @@ -144,6 +148,8 @@ namespace ICSharpCode.SharpDevelop
/// </summary>
public void UpdateErrors()
{
if (isDisposed)
return;
ClearErrors();
foreach (Task task in TaskService.Tasks) {
AddTask(task);

77
src/Main/Base/Project/Src/Services/Tasks/Task.cs

@ -6,6 +6,8 @@ @@ -6,6 +6,8 @@
// </file>
using System;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.SharpDevelop
@ -23,19 +25,18 @@ namespace ICSharpCode.SharpDevelop @@ -23,19 +25,18 @@ namespace ICSharpCode.SharpDevelop
public const string DefaultContextMenuAddInTreeEntry = "/SharpDevelop/Pads/ErrorList/TaskContextMenu";
string description;
string fileName;
TaskType type;
int line;
int column;
PermanentAnchor position;
bool hasLocation;
string contextMenuAddInTreeEntry = DefaultContextMenuAddInTreeEntry;
object tag;
public override string ToString()
{
return String.Format("[Task:File={0}, Line={1}, Column={2}, Type={3}, Description={4}",
fileName,
line,
column,
FileName,
Line,
Column,
type,
description);
}
@ -45,7 +46,10 @@ namespace ICSharpCode.SharpDevelop @@ -45,7 +46,10 @@ namespace ICSharpCode.SharpDevelop
/// </summary>
public int Line {
get {
return line;
if (hasLocation && !position.IsDeleted)
return position.Line;
else
return 0;
}
}
@ -54,7 +58,10 @@ namespace ICSharpCode.SharpDevelop @@ -54,7 +58,10 @@ namespace ICSharpCode.SharpDevelop
/// </summary>
public int Column {
get {
return column;
if (hasLocation && !position.IsDeleted)
return position.Column;
else
return 0;
}
}
@ -64,12 +71,12 @@ namespace ICSharpCode.SharpDevelop @@ -64,12 +71,12 @@ namespace ICSharpCode.SharpDevelop
}
}
public string FileName {
public FileName FileName {
get {
return fileName;
}
set {
fileName = value;
if (position != null)
return position.FileName;
else
return null;
}
}
@ -102,21 +109,44 @@ namespace ICSharpCode.SharpDevelop @@ -102,21 +109,44 @@ namespace ICSharpCode.SharpDevelop
/// </summary>
public BuildError BuildError { get; private set; }
public Task(string fileName, string description, int column, int line, TaskType type)
/// <summary>
/// Creates a new Task instance.
/// </summary>
/// <param name="fileName">The file that the task refers to. Use null if the task does not refer to a file.</param>
/// <param name="description">Description of the task. This parameter cannot be null.</param>
/// <param name="column">Task column (1-based), use 0 if no column is known</param>
/// <param name="line">Task line (1-based), use 0 if no line number is known</param>
/// <param name="type">Type of the task</param>
public Task(FileName fileName, string description, int column, int line, TaskType type)
{
if (description == null)
throw new ArgumentNullException("description");
this.type = type;
this.fileName = fileName;
this.description = description.Trim();
this.column = column;
this.line = line;
if (fileName != null) {
hasLocation = line >= 1;
this.position = new PermanentAnchor(fileName, Math.Max(1, line), Math.Max(1, column));
position.Deleted += position_Deleted;
}
}
void position_Deleted(object sender, EventArgs e)
{
TaskService.Remove(this);
}
public Task(BuildError error)
{
type = error.IsWarning ? TaskType.Warning : TaskType.Error;
column = Math.Max(error.Column, 1);
line = Math.Max(error.Line, 1);
fileName = error.FileName;
if (error == null)
throw new ArgumentNullException("error");
type = error.IsWarning ? TaskType.Warning : TaskType.Error;
int line = Math.Max(error.Line, 1);
int column = Math.Max(error.Column, 1);
if (!string.IsNullOrEmpty(error.FileName)) {
hasLocation = error.Line >= 1;
this.position = new PermanentAnchor(FileName.Create(error.FileName), line, column);
position.Deleted += position_Deleted;
}
if (string.IsNullOrEmpty(error.ErrorCode)) {
description = error.ErrorText;
} else {
@ -131,7 +161,10 @@ namespace ICSharpCode.SharpDevelop @@ -131,7 +161,10 @@ namespace ICSharpCode.SharpDevelop
public void JumpToPosition()
{
FileService.JumpToFilePosition(fileName, line, column);
if (hasLocation && !position.IsDeleted)
FileService.JumpToFilePosition(position.FileName, position.Line, position.Column);
else if (position != null)
FileService.OpenFile(position.FileName);
}
}
}

33
src/Main/Base/Project/Src/Services/Tasks/TaskService.cs

@ -81,9 +81,6 @@ namespace ICSharpCode.SharpDevelop @@ -81,9 +81,6 @@ namespace ICSharpCode.SharpDevelop
static TaskService()
{
FileService.FileRenamed += CheckFileRename;
FileService.FileRemoved += CheckFileRemove;
ProjectService.SolutionClosed += new EventHandler(ProjectServiceSolutionClosed);
}
@ -92,30 +89,6 @@ namespace ICSharpCode.SharpDevelop @@ -92,30 +89,6 @@ namespace ICSharpCode.SharpDevelop
Clear();
}
static void CheckFileRemove(object sender, FileEventArgs e)
{
for (int i = 0; i < tasks.Count; ++i) {
Task curTask = tasks[i];
if (FileUtility.IsEqualFileName(curTask.FileName, e.FileName)) {
Remove(curTask);
--i;
}
}
}
static void CheckFileRename(object sender, FileRenameEventArgs e)
{
for (int i = 0; i < tasks.Count; ++i) {
Task curTask = tasks[i];
if (FileUtility.IsEqualFileName(curTask.FileName, e.SourceFile)) {
Remove(curTask);
curTask.FileName = FileUtility.NormalizePath(e.TargetFile);
Add(curTask);
--i;
}
}
}
public static void Clear()
{
taskCount.Clear();
@ -164,10 +137,10 @@ namespace ICSharpCode.SharpDevelop @@ -164,10 +137,10 @@ namespace ICSharpCode.SharpDevelop
if (fileName == null || tagComments == null) {
return;
}
WorkbenchSingleton.SafeThreadAsyncCall(UpdateCommentTagsInvoked, fileName, tagComments);
WorkbenchSingleton.SafeThreadAsyncCall(UpdateCommentTagsInvoked, FileName.Create(fileName), tagComments);
}
static void UpdateCommentTagsInvoked(string fileName, IList<TagComment> tagComments)
static void UpdateCommentTagsInvoked(FileName fileName, IList<TagComment> tagComments)
{
List<Task> newTasks = new List<Task>();
foreach (TagComment tag in tagComments) {
@ -180,7 +153,7 @@ namespace ICSharpCode.SharpDevelop @@ -180,7 +153,7 @@ namespace ICSharpCode.SharpDevelop
List<Task> oldTasks = new List<Task>();
foreach (Task task in CommentTasks) {
if (FileUtility.IsEqualFileName(task.FileName, fileName)) {
if (task.FileName == fileName) {
oldTasks.Add(task);
}
}

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/ErrorDrawer.cs

@ -150,7 +150,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -150,7 +150,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
{
if (textEditor.FileName == null)
return false;
if (task.FileName == null || task.FileName.Length == 0 || task.Column < 0)
if (task.FileName == null || task.Column < 0)
return false;
if (task.TaskType != TaskType.Warning && task.TaskType != TaskType.Error)
return false;

10
src/Main/Core/Project/Src/Services/FileUtility/FileName.cs

@ -21,19 +21,21 @@ namespace ICSharpCode.Core @@ -21,19 +21,21 @@ namespace ICSharpCode.Core
{
if (fileName == null)
throw new ArgumentNullException("fileName");
if (fileName.Length == 0)
throw new ArgumentException("The empty string is not a valid FileName");
this.normalizedFileName = FileUtility.NormalizePath(fileName);
}
/// <summary>
/// Creates a FileName instance from the string.
/// It is valid to pass null to this method (in that case, a null reference will be returned).
/// It is valid to pass null or an empty string to this method (in that case, a null reference will be returned).
/// </summary>
public static FileName Create(string fileName)
{
if (fileName != null)
return new FileName(fileName);
else
if (string.IsNullOrEmpty(fileName))
return null;
else
return new FileName(fileName);
}
public static implicit operator string(FileName fileName)

5
src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

@ -166,6 +166,11 @@ namespace ICSharpCode.Core @@ -166,6 +166,11 @@ namespace ICSharpCode.Core
return path.IndexOf("://", StringComparison.Ordinal) > 0;
}
public static bool IsEqualFileName(FileName fileName1, FileName fileName2)
{
return fileName1 == fileName2;
}
public static string GetCommonBaseDirectory(string dir1, string dir2)
{
if (dir1 == null || dir2 == null) return null;

Loading…
Cancel
Save