diff --git a/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Project/Src/PythonCompilerTask.cs b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Project/Src/PythonCompilerTask.cs index 6745c38b1d..44aea22d4c 100644 --- a/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Project/Src/PythonCompilerTask.cs +++ b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Project/Src/PythonCompilerTask.cs @@ -174,15 +174,21 @@ namespace ICSharpCode.Python.Build.Tasks /// Matches the syntax exception SourcePath against filenames being compiled. The /// syntax exception only contains the file name without its path and without its file extension. /// - static string GetFileName(SyntaxErrorException ex, ITaskItem[] sources) + string GetFileName(SyntaxErrorException ex, ITaskItem[] sources) { + if (ex.SourcePath == null) { + return null; + } + + string sourcePath = ex.SourcePath.Replace('\\', '.'); foreach (ITaskItem item in sources) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item.ItemSpec); - if (fileNameWithoutExtension == ex.SourcePath) { + if (fileNameWithoutExtension == sourcePath) { return item.ItemSpec; } } - return null; + string fileName = sourcePath + ".py"; + return Path.Combine(GetCurrentFolder(), fileName); } /// diff --git a/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/Python.Build.Tasks.Tests.csproj b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/Python.Build.Tasks.Tests.csproj index de97df4ce9..e7401a17bf 100644 --- a/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/Python.Build.Tasks.Tests.csproj +++ b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/Python.Build.Tasks.Tests.csproj @@ -75,7 +75,10 @@ + + + diff --git a/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorFileNameWithDotCharTestFixture.cs b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorFileNameWithDotCharTestFixture.cs new file mode 100644 index 0000000000..3c394c8608 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorFileNameWithDotCharTestFixture.cs @@ -0,0 +1,68 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Reflection; +using System.Reflection.Emit; +using IronPython.Runtime; +using ICSharpCode.Python.Build.Tasks; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.Scripting; +using Microsoft.Scripting.Hosting; +using Microsoft.Scripting.Runtime; +using NUnit.Framework; + +namespace Python.Build.Tasks.Tests +{ + /// + /// If the project has a filename with a dot character in it (e.g. Resources.Designer.py) and this file + /// has a syntax error then IronPython's ClrModule.CompileModules method will throw a syntax error exception but the + /// filename will have a '\' replacing the dot character (i.e. Resources\Designer.py). + /// + [TestFixture] + public class SyntaxErrorFileNameWithDotCharTestFixture + { + MockPythonCompiler mockCompiler; + DummyPythonCompilerTask compiler; + bool success; + + [TestFixtureSetUp] + public void SetUpFixture() + { + ScriptEngine engine = IronPython.Hosting.Python.CreateEngine(); + } + + [SetUp] + public void Init() + { + mockCompiler = new MockPythonCompiler(); + compiler = new DummyPythonCompilerTask(mockCompiler, @"C:\Projects\MyProject"); + compiler.TargetType = "Exe"; + compiler.OutputAssembly = "test.exe"; + + TaskItem sourceFile = new TaskItem(@"D:\Projects\MyProject\PythonApp.Program.py"); + compiler.Sources = new ITaskItem[] {sourceFile}; + + SourceUnit source = DefaultContext.DefaultPythonContext.CreateSourceUnit(NullTextContentProvider.Null, @"PythonApp\Program", SourceCodeKind.InteractiveCode); + + SourceLocation start = new SourceLocation(0, 1, 1); + SourceLocation end = new SourceLocation(0, 2, 3); + SourceSpan span = new SourceSpan(start, end); + SyntaxErrorException ex = new SyntaxErrorException("Error", source, span, 1000, Severity.FatalError); + mockCompiler.ThrowExceptionAtCompile = ex; + + success = compiler.Execute(); + } + + [Test] + public void SourceFile() + { + Assert.AreEqual(@"D:\Projects\MyProject\PythonApp.Program.py", compiler.LoggedErrorFile); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorNullFileNameTestFixture.cs b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorNullFileNameTestFixture.cs new file mode 100644 index 0000000000..5d7f0a5c30 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorNullFileNameTestFixture.cs @@ -0,0 +1,60 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Reflection; +using System.Reflection.Emit; +using IronPython.Runtime; +using ICSharpCode.Python.Build.Tasks; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.Scripting; +using Microsoft.Scripting.Hosting; +using Microsoft.Scripting.Runtime; +using NUnit.Framework; + +namespace Python.Build.Tasks.Tests +{ + [TestFixture] + public class SyntaxErrorNullFileNameTestFixture + { + MockPythonCompiler mockCompiler; + DummyPythonCompilerTask compiler; + bool success; + + [TestFixtureSetUp] + public void SetUpFixture() + { + ScriptEngine engine = IronPython.Hosting.Python.CreateEngine(); + } + + [SetUp] + public void Init() + { + mockCompiler = new MockPythonCompiler(); + compiler = new DummyPythonCompilerTask(mockCompiler, @"C:\Projects\MyProject"); + compiler.TargetType = "Exe"; + compiler.OutputAssembly = "test.exe"; + + TaskItem sourceFile = new TaskItem(@"D:\Projects\MyProject\test.py"); + compiler.Sources = new ITaskItem[] {sourceFile}; + + SourceUnit source = DefaultContext.DefaultPythonContext.CreateSourceUnit(NullTextContentProvider.Null, @"test", SourceCodeKind.InteractiveCode); + + SyntaxErrorException ex = new SyntaxErrorException("Error", null, SourceSpan.None, 1000, Severity.FatalError); + mockCompiler.ThrowExceptionAtCompile = ex; + + success = compiler.Execute(); + } + + [Test] + public void IsExceptionMessageLogged() + { + Assert.AreEqual("Error", compiler.LoggedErrorMessage); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorUnknownFileNameTestFixture.cs b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorUnknownFileNameTestFixture.cs new file mode 100644 index 0000000000..7de397cb02 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/Python.Build.Tasks/Test/SyntaxErrorUnknownFileNameTestFixture.cs @@ -0,0 +1,67 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Reflection; +using System.Reflection.Emit; +using IronPython.Runtime; +using ICSharpCode.Python.Build.Tasks; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Microsoft.Scripting; +using Microsoft.Scripting.Hosting; +using Microsoft.Scripting.Runtime; +using NUnit.Framework; + +namespace Python.Build.Tasks.Tests +{ + /// + /// If the filename returned from the SyntaxErrorException cannot be found in the project then + /// just use the project's folder concatenated with the filename. + /// + [TestFixture] + public class SyntaxErrorUnknownFileNameTestFixture + { + MockPythonCompiler mockCompiler; + DummyPythonCompilerTask compiler; + bool success; + + [TestFixtureSetUp] + public void SetUpFixture() + { + ScriptEngine engine = IronPython.Hosting.Python.CreateEngine(); + } + + [SetUp] + public void Init() + { + mockCompiler = new MockPythonCompiler(); + compiler = new DummyPythonCompilerTask(mockCompiler, @"D:\Projects\MyProject"); + compiler.TargetType = "Exe"; + compiler.OutputAssembly = "test.exe"; + + TaskItem sourceFile = new TaskItem(@"D:\Projects\MyProject\test.py"); + compiler.Sources = new ITaskItem[] {sourceFile}; + + SourceUnit source = DefaultContext.DefaultPythonContext.CreateSourceUnit(NullTextContentProvider.Null, @"test\unknown", SourceCodeKind.InteractiveCode); + + SourceLocation start = new SourceLocation(0, 1, 1); + SourceLocation end = new SourceLocation(0, 2, 3); + SourceSpan span = new SourceSpan(start, end); + SyntaxErrorException ex = new SyntaxErrorException("Error", source, span, 1000, Severity.FatalError); + mockCompiler.ThrowExceptionAtCompile = ex; + + success = compiler.Execute(); + } + + [Test] + public void SourceFile() + { + Assert.AreEqual(@"D:\Projects\MyProject\test.unknown.py", compiler.LoggedErrorFile); + } + } +}