diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/CompilerErrorTask.cs b/src/AddIns/Misc/TextTemplating/Project/Src/CompilerErrorTask.cs new file mode 100644 index 0000000000..b17b642a0f --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/CompilerErrorTask.cs @@ -0,0 +1,39 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom.Compiler; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; + +namespace ICSharpCode.TextTemplating +{ + public class CompilerErrorTask : Task + { + public CompilerErrorTask(CompilerError error) + : base( + GetFileName(error.FileName), + error.ErrorText, + error.Column, + error.Line, + GetTaskType(error.IsWarning)) + { + } + + static TaskType GetTaskType(bool warning) + { + if (warning) { + return TaskType.Warning; + } + return TaskType.Error; + } + + static FileName GetFileName(string fileName) + { + if (!String.IsNullOrEmpty(fileName)) { + return new FileName(fileName); + } + return null; + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs index f7f8c94501..599015bf96 100644 --- a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs +++ b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingCustomToolContext.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.TextTemplating @@ -9,5 +10,9 @@ namespace ICSharpCode.TextTemplating public interface ITextTemplatingCustomToolContext { FileProjectItem EnsureOutputFileIsInProject(FileProjectItem baseItem, string outputFileName); + + void ClearTasksExceptCommentTasks(); + void AddTask(Task task); + void BringErrorsPadToFront(); } } diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs index ce47ed5177..704a2551d0 100644 --- a/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs +++ b/src/AddIns/Misc/TextTemplating/Project/Src/ITextTemplatingHost.cs @@ -2,12 +2,15 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.CodeDom.Compiler; namespace ICSharpCode.TextTemplating { public interface ITextTemplatingHost : IDisposable { - bool ProcessTemplate(string inputFile, string outputFile); string OutputFile { get; } + CompilerErrorCollection Errors { get; } + + bool ProcessTemplate(string inputFile, string outputFile); } } diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TemplatingHostProcessTemplateError.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TemplatingHostProcessTemplateError.cs new file mode 100644 index 0000000000..d523fb7048 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TemplatingHostProcessTemplateError.cs @@ -0,0 +1,17 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom.Compiler; + +namespace ICSharpCode.TextTemplating +{ + public class TemplatingHostProcessTemplateError : CompilerError + { + public TemplatingHostProcessTemplateError(Exception ex, string fileName) + { + this.ErrorText = ex.Message; + this.FileName = fileName; + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs index b483b79751..8bc3c43690 100644 --- a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingCustomToolContext.cs @@ -2,6 +2,8 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.TextTemplating @@ -19,5 +21,20 @@ namespace ICSharpCode.TextTemplating { return context.EnsureOutputFileIsInProject(baseItem, outputFileName); } + + public void ClearTasksExceptCommentTasks() + { + TaskService.ClearExceptCommentTasks(); + } + + public void AddTask(Task task) + { + TaskService.Add(task); + } + + public void BringErrorsPadToFront() + { + WorkbenchSingleton.Workbench.GetPad(typeof(ErrorListPad)).BringPadToFront(); + } } } diff --git a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs index dde2ec5fa2..32fa4d08db 100644 --- a/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs +++ b/src/AddIns/Misc/TextTemplating/Project/Src/TextTemplatingFileGenerator.cs @@ -2,7 +2,10 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.CodeDom.Compiler; using System.IO; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.TextTemplating @@ -30,40 +33,65 @@ namespace ICSharpCode.TextTemplating public void ProcessTemplate() { - GenerateOutputFileForTemplate(); - AddOutputFileToProjectIfRequired(); + context.ClearTasksExceptCommentTasks(); + if (TryGenerateOutputFileForTemplate()) { + AddOutputFileToProjectIfRequired(); + } + AddAnyErrorsToTaskList(); + BringErrorsToFrontIfRequired(); + } + + void BringErrorsToFrontIfRequired() + { + if (host.Errors.HasErrors) { + context.BringErrorsPadToFront(); + } } - void GenerateOutputFileForTemplate() + bool TryGenerateOutputFileForTemplate() { string inputFileName = projectFile.FileName; string outputFileName = GetOutputFileName(inputFileName); - host.ProcessTemplate(inputFileName, outputFileName); + return TryProcessingTemplate(inputFileName, outputFileName); + } + + bool TryProcessingTemplate(string inputFileName, string outputFileName) + { + try { + return host.ProcessTemplate(inputFileName, outputFileName); + } catch (InvalidOperationException ex) { + AddCompilerErrorToTemplatingHost(ex, inputFileName); + } + return false; + } + + void AddCompilerErrorToTemplatingHost(Exception ex, string fileName) + { + var error = new TemplatingHostProcessTemplateError(ex, fileName); + host.Errors.Add(error); } string GetOutputFileName(string inputFileName) { return Path.ChangeExtension(inputFileName, ".cs"); } + + void AddAnyErrorsToTaskList() + { + foreach (CompilerError error in host.Errors) { + AddErrorToTaskList(error); + } + } + + void AddErrorToTaskList(CompilerError error) + { + var task = new CompilerErrorTask(error); + context.AddTask(task); + } void AddOutputFileToProjectIfRequired() { context.EnsureOutputFileIsInProject(projectFile, host.OutputFile); } - - -// internal static void LogicalSetData (string name, object value, -// System.CodeDom.Compiler.CompilerErrorCollection errors) -// { -// //FIXME: CallContext.LogicalSetData not implemented in Mono -// try { -// System.Runtime.Remoting.Messaging.CallContext.LogicalSetData (name, value); -// } catch (NotImplementedException) { -// errors.Add (new System.CodeDom.Compiler.CompilerError ( -// null, -1, -1, null, -// "Could not set " + name + " - CallContext.LogicalSetData not implemented in this Mono version" -// ) { IsWarning = true }); -// } -// } } } \ No newline at end of file diff --git a/src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj b/src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj index 712cceb77f..ecf999fbd3 100644 --- a/src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj +++ b/src/AddIns/Misc/TextTemplating/Project/TextTemplating.csproj @@ -50,11 +50,13 @@ Configuration\GlobalAssemblyInfo.cs + + diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs index 59a26fd62f..50d7637649 100644 --- a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingCustomToolContext.cs @@ -2,6 +2,8 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Collections.Generic; +using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.TextTemplating; @@ -11,14 +13,42 @@ namespace TextTemplating.Tests.Helpers { public FileProjectItem BaseItemPassedToEnsureOutputFileIsInProject; public string OutputFileNamePassedToEnsureOutputFileIsInProject; - public TestableFileProjectItem EnsureOutputFileIsInProjectReturnValue = new TestableFileProjectItem(@"d:\Projects\MyProject\template.tt"); + public bool IsOutputFileNamePassedToEnsureOutputFileIsInProject; + public bool IsClearTasksExceptCommentTasksCalled; + public bool IsBringErrorsPadToFrontCalled; + + public List TasksAdded = new List(); + + public Task FirstTaskAdded { + get { return TasksAdded[0]; } + } + + public TestableFileProjectItem EnsureOutputFileIsInProjectReturnValue = + new TestableFileProjectItem(@"d:\Projects\MyProject\template.tt"); public FileProjectItem EnsureOutputFileIsInProject(FileProjectItem baseItem, string outputFileName) { BaseItemPassedToEnsureOutputFileIsInProject = baseItem; OutputFileNamePassedToEnsureOutputFileIsInProject = outputFileName; + IsOutputFileNamePassedToEnsureOutputFileIsInProject = true; + return EnsureOutputFileIsInProjectReturnValue; } + + public void ClearTasksExceptCommentTasks() + { + IsClearTasksExceptCommentTasksCalled = true; + } + + public void AddTask(Task task) + { + TasksAdded.Add(task); + } + + public void BringErrorsPadToFront() + { + IsBringErrorsPadToFrontCalled = true; + } } } diff --git a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs index eb76391a25..07f1f99ea1 100644 --- a/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs +++ b/src/AddIns/Misc/TextTemplating/Test/Helpers/FakeTextTemplatingHost.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.CodeDom.Compiler; using ICSharpCode.TextTemplating; namespace TextTemplating.Tests.Helpers @@ -12,11 +13,23 @@ namespace TextTemplating.Tests.Helpers public string OutputFilePassedToProcessTemplate; public bool ProcessTemplateReturnValue = true; public bool IsDisposeCalled; + public Exception ExceptionToThrowWhenProcessTemplateCalled; + + public CompilerErrorCollection ErrorsCollection = new CompilerErrorCollection(); + + public CompilerErrorCollection Errors { + get { return ErrorsCollection; } + } public bool ProcessTemplate(string inputFile, string outputFile) { InputFilePassedToProcessTemplate = inputFile; OutputFilePassedToProcessTemplate = outputFile; + + if (ExceptionToThrowWhenProcessTemplateCalled != null) { + throw ExceptionToThrowWhenProcessTemplateCalled; + } + return ProcessTemplateReturnValue; } diff --git a/src/AddIns/Misc/TextTemplating/Test/Src/CompilerErrorTaskTests.cs b/src/AddIns/Misc/TextTemplating/Test/Src/CompilerErrorTaskTests.cs new file mode 100644 index 0000000000..0d66338729 --- /dev/null +++ b/src/AddIns/Misc/TextTemplating/Test/Src/CompilerErrorTaskTests.cs @@ -0,0 +1,69 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.CodeDom.Compiler; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; +using ICSharpCode.TextTemplating; +using NUnit.Framework; + +namespace TextTemplating.Tests +{ + [TestFixture] + public class CompilerErrorTaskTests + { + [Test] + public void FileName_CompilerErrorFileNameIsTestTxt_ReturnsTestTxt() + { + var error = new CompilerError(); + error.FileName = "test.txt"; + var task = new CompilerErrorTask(error); + + FileName expectedFileName = new FileName("test.txt"); + Assert.AreEqual(expectedFileName, task.FileName); + } + + [Test] + public void Column_CompilerErrorColumnIsTwo_ReturnsTwo() + { + var error = new CompilerError(); + error.FileName = "test.txt"; + error.Line = 1; + error.Column = 2; + var task = new CompilerErrorTask(error); + + Assert.AreEqual(2, task.Column); + } + + [Test] + public void Line_CompilerErrorLineIsThree_ReturnsThree() + { + var error = new CompilerError(); + error.FileName = "test.txt"; + error.Line = 3; + var task = new CompilerErrorTask(error); + + Assert.AreEqual(3, task.Line); + } + + [Test] + public void TaskType_CompilerErrorIsWarning_ReturnsWarning() + { + var error = new CompilerError(); + error.IsWarning = true; + var task = new CompilerErrorTask(error); + + Assert.AreEqual(TaskType.Warning, task.TaskType); + } + + [Test] + public void TaskType_CompilerErrorIsNotWarning_ReturnsError() + { + var error = new CompilerError(); + var task = new CompilerErrorTask(error); + + Assert.AreEqual(TaskType.Error, task.TaskType); + } + } +} diff --git a/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs index 37e7018555..8035649750 100644 --- a/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs +++ b/src/AddIns/Misc/TextTemplating/Test/Src/TextTemplatingFileGeneratorTests.cs @@ -2,6 +2,9 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.CodeDom.Compiler; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.TextTemplating; using NUnit.Framework; @@ -79,5 +82,95 @@ namespace TextTemplating.Tests Assert.AreEqual(@"d:\changed-output.test", customToolContext.OutputFileNamePassedToEnsureOutputFileIsInProject); } + + [Test] + public void ProcessTemplate_TemplateFileInProjectPassed_TaskServiceHasClearedTasksExceptForCommentTasks() + { + var file = ProcessTemplate(@"d:\template.tt"); + + Assert.IsTrue(customToolContext.IsClearTasksExceptCommentTasksCalled); + } + + [Test] + public void ProcessTemplate_TemplateHostHasOneErrorAfterProcessing_ErrorTaskAddedToTaskList() + { + CreateGenerator(@"d:\a.tt"); + templatingHost.ErrorsCollection.Add(new CompilerError()); + generator.ProcessTemplate(); + + Task task = customToolContext.FirstTaskAdded; + + Assert.AreEqual(TaskType.Error, task.TaskType); + } + + [Test] + public void ProcessTemplate_TemplateHostHasOneErrorAfterProcessing_ErrorDescriptionIsAddedToTaskList() + { + CreateGenerator(@"d:\a.tt"); + var error = new CompilerError(); + error.ErrorText = "error text"; + templatingHost.ErrorsCollection.Add(error); + generator.ProcessTemplate(); + + Task task = customToolContext.FirstTaskAdded; + + Assert.AreEqual("error text", task.Description); + } + + [Test] + public void ProcessTemplate_ThrowsInvalidOperationException_ErrorTaskAddedToTaskList() + { + CreateGenerator(@"d:\a.tt"); + var ex = new InvalidOperationException("invalid operation error"); + templatingHost.ExceptionToThrowWhenProcessTemplateCalled = ex; + generator.ProcessTemplate(); + + Task task = customToolContext.FirstTaskAdded; + + Assert.AreEqual("invalid operation error", task.Description); + } + + [Test] + public void ProcessTemplate_ThrowsInvalidOperationException_ErrorTaskAddedToTaskListWithTemplateFileName() + { + CreateGenerator(@"d:\a.tt"); + var ex = new InvalidOperationException("invalid operation error"); + templatingHost.ExceptionToThrowWhenProcessTemplateCalled = ex; + generator.ProcessTemplate(); + + Task task = customToolContext.FirstTaskAdded; + var expectedFileName = new FileName(@"d:\a.tt"); + + Assert.AreEqual(expectedFileName, task.FileName); + } + + [Test] + public void ProcessTemplate_MethodReturnsFalse_OutputFileNotAddedToProject() + { + CreateGenerator(@"d:\a.tt"); + templatingHost.ProcessTemplateReturnValue = false; + generator.ProcessTemplate(); + + Assert.IsFalse(customToolContext.IsOutputFileNamePassedToEnsureOutputFileIsInProject); + } + + [Test] + public void ProcessTemplate_TemplateHostHasOneErrorAfterProcessing_ErrorsPadBroughtToFront() + { + CreateGenerator(@"d:\a.tt"); + templatingHost.Errors.Add(new CompilerError()); + generator.ProcessTemplate(); + + Assert.IsTrue(customToolContext.IsBringErrorsPadToFrontCalled); + } + + [Test] + public void ProcessTemplate_NoErrorsAfterProcessing_ErrorsPadNotBroughtToFront() + { + CreateGenerator(@"d:\a.tt"); + generator.ProcessTemplate(); + + Assert.IsFalse(customToolContext.IsBringErrorsPadToFrontCalled); + } } } \ No newline at end of file diff --git a/src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj b/src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj index 09a6e946f9..fb3f4528ae 100644 --- a/src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj +++ b/src/AddIns/Misc/TextTemplating/Test/TextTemplating.Tests.csproj @@ -62,6 +62,7 @@ +