From 7724781cf6f7d2fd4236e88302a763fd9c30def4 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Sun, 3 Feb 2008 16:32:31 +0000 Subject: [PATCH] Added support for casts and class method calls in the python code converter. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2937 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Src/NRefactoryToPythonConverter.cs | 33 ++++--- .../ArrayCastConversionTestFixture.cs | 79 ++++++++++++++++ .../IntegerMethodParameterTestFixture.cs | 89 +++++++++++++++++++ .../Test/CreateNewPythonProjectTestFixture.cs | 54 ++++++++--- .../Test/PythonBinding.Tests.csproj | 2 + 5 files changed, 230 insertions(+), 27 deletions(-) create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ArrayCastConversionTestFixture.cs create mode 100644 src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/IntegerMethodParameterTestFixture.cs diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs index f1419d190f..4f73a9badc 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs @@ -245,11 +245,13 @@ namespace ICSharpCode.PythonBinding Console.WriteLine("VisitCaseLabel"); return null; } - + + /// + /// Ignore the cast and just visit the expression inside the cast. + /// public object VisitCastExpression(CastExpression castExpression, object data) { - Console.WriteLine("VisitCastExpression"); - return null; + return castExpression.Expression.AcceptVisitor(this, data); } public object VisitCatchClause(CatchClause catchClause, object data) @@ -694,20 +696,23 @@ namespace ICSharpCode.PythonBinding /// public object VisitInvocationExpression(InvocationExpression invocationExpression, object data) { - // Create target object. - MemberReferenceExpression memberRefExpression = invocationExpression.TargetObject as MemberReferenceExpression; - CodeExpression targetObjectExpression = (CodeExpression)memberRefExpression.TargetObject.AcceptVisitor(this, data); - - // Create method ref. CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression(); - methodRef.MethodName = memberRefExpression.MemberName; - methodRef.TargetObject = targetObjectExpression; - + + MemberReferenceExpression memberRefExpression = invocationExpression.TargetObject as MemberReferenceExpression; + IdentifierExpression identifierExpression = invocationExpression.TargetObject as IdentifierExpression; + if (memberRefExpression != null) { + methodRef.MethodName = memberRefExpression.MemberName; + methodRef.TargetObject = (CodeExpression)memberRefExpression.TargetObject.AcceptVisitor(this, data); + + } else if (identifierExpression != null) { + methodRef.MethodName = identifierExpression.Identifier; + methodRef.TargetObject = new CodeThisReferenceExpression(); + } + // Create method invoke. CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(); methodInvoke.Parameters.AddRange(ConvertExpressions(invocationExpression.Arguments)); methodInvoke.Method = methodRef; - return methodInvoke; } @@ -1449,7 +1454,9 @@ namespace ICSharpCode.PythonBinding List codeExpressions = new List(); foreach (Expression expression in expressions) { CodeExpression convertedCodeExpression = (CodeExpression)expression.AcceptVisitor(this, null); - codeExpressions.Add(convertedCodeExpression); + if (convertedCodeExpression != null) { + codeExpressions.Add(convertedCodeExpression); + } } return codeExpressions.ToArray(); } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ArrayCastConversionTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ArrayCastConversionTestFixture.cs new file mode 100644 index 0000000000..7801827125 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ArrayCastConversionTestFixture.cs @@ -0,0 +1,79 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using ICSharpCode.PythonBinding; +using NUnit.Framework; + +namespace PythonBinding.Tests.Converter +{ + /// + /// Tests that an array cast is correctly converted to Python. + /// + [TestFixture] + public class ArrayCastConversionTestFixture + { + string csharp = "class Foo\r\n" + + "{\r\n" + + " public void Assign()\r\n" + + " {\r\n" + + " int[] elements = new int[10];\r\n" + + " List list = new List();\r\n" + + " list.Add((int[])elements.Clone());\r\n" + + " }\r\n" + + "}"; + + CodeExpression expression; + + [TestFixtureSetUp] + public void SetUpFixture() + { + CSharpToPythonConverter converter = new CSharpToPythonConverter(); + CodeCompileUnit unit = converter.ConvertToCodeCompileUnit(csharp); + if (unit.Namespaces.Count > 0) { + CodeNamespace ns = unit.Namespaces[0]; + if (ns.Types.Count > 0) { + CodeTypeDeclaration type = ns.Types[0]; + if (type.Members.Count > 0) { + CodeMemberMethod method = type.Members[0] as CodeMemberMethod; + if (method != null && method.Statements.Count > 0) { + CodeExpressionStatement statement = method.Statements[method.Statements.Count - 1] as CodeExpressionStatement; + if (statement != null) { + CodeMethodInvokeExpression methodInvokeExpression = statement.Expression as CodeMethodInvokeExpression; + if (methodInvokeExpression != null && methodInvokeExpression.Parameters.Count > 0) { + expression = methodInvokeExpression.Parameters[0]; + } + } + } + } + } + } + } + + [Test] + public void CodeExpressionExists() + { + Assert.IsNotNull(expression); + } + + [Test] + public void GeneratedPythonSourceCode() + { + CSharpToPythonConverter converter = new CSharpToPythonConverter(); + string python = converter.Convert(csharp); + string expectedPython = "class Foo(object):\r\n" + + "\tdef Assign(self):\r\n" + + "\t\telements = System.Array.CreateInstance(int,0)\r\n" + + "\t\tlist = List()\r\n" + + "\t\tlist.Add(elements.Clone())"; + + Assert.AreEqual(expectedPython, python); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/IntegerMethodParameterTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/IntegerMethodParameterTestFixture.cs new file mode 100644 index 0000000000..d6da27f340 --- /dev/null +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/IntegerMethodParameterTestFixture.cs @@ -0,0 +1,89 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using ICSharpCode.PythonBinding; +using NUnit.Framework; + +namespace PythonBinding.Tests.Converter +{ + /// + /// Tests that a method call is converted correctly. + /// + [TestFixture] + public class IntegerMethodParameterTestFixture + { + string csharp = "class Foo\r\n" + + "{\r\n" + + " public void Print()\r\n" + + " {\r\n" + + " int i = 0;\r\n" + + " PrintInt(i);\r\n" + + " }\r\n" + + "}"; + + CodeMethodReferenceExpression methodRefExpression; + + [TestFixtureSetUp] + public void SetUpFixture() + { + CSharpToPythonConverter converter = new CSharpToPythonConverter(); + CodeCompileUnit unit = converter.ConvertToCodeCompileUnit(csharp); + if (unit.Namespaces.Count > 0) { + CodeNamespace ns = unit.Namespaces[0]; + if (ns.Types.Count > 0) { + CodeTypeDeclaration type = ns.Types[0]; + if (type.Members.Count > 0) { + CodeMemberMethod method = type.Members[0] as CodeMemberMethod; + if (method != null && method.Statements.Count > 0) { + CodeExpressionStatement statement = method.Statements[method.Statements.Count - 1] as CodeExpressionStatement; + if (statement != null) { + CodeMethodInvokeExpression methodInvokeExpression = statement.Expression as CodeMethodInvokeExpression; + if (methodInvokeExpression != null) { + methodRefExpression = methodInvokeExpression.Method; + } + } + } + } + } + } + } + + [Test] + public void MethodRefExpressionExists() + { + Assert.IsNotNull(methodRefExpression); + } + + [Test] + public void MethodNameIsPrintInt() + { + Assert.AreEqual("PrintInt", methodRefExpression.MethodName); + } + + [Test] + public void MethodRefTargetObjectIsThisRef() + { + Assert.IsInstanceOfType(typeof(CodeThisReferenceExpression), methodRefExpression.TargetObject); + } + + [Test] + public void GeneratedPythonSourceCode() + { + CSharpToPythonConverter converter = new CSharpToPythonConverter(); + string python = converter.Convert(csharp); + string expectedPython = "class Foo(object):\r\n" + + "\tdef Print(self):\r\n" + + "\t\ti = 0\r\n" + + "\t\tself.PrintInt(i)"; + + Assert.AreEqual(expectedPython, python); + } + } +} diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/CreateNewPythonProjectTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/CreateNewPythonProjectTestFixture.cs index edacd5935e..ad4d5bd22d 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/CreateNewPythonProjectTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/CreateNewPythonProjectTestFixture.cs @@ -7,6 +7,7 @@ using System; using System.IO; +using System.Text; using ICSharpCode.PythonBinding; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; @@ -52,23 +53,13 @@ namespace PythonBinding.Tests { Assert.AreEqual(info.ProjectName, project.Name); } - - [Test] - public void TwoImports() - { - Assert.AreEqual(2, project.MSBuildProject.Imports.Count); - } - + [Test] public void Imports() { - Microsoft.Build.BuildEngine.Import[] imports = {null, null}; - project.MSBuildProject.Imports.CopyTo(imports, 0); - - string[] paths = new string[] {imports[0].ProjectPath, imports[1].ProjectPath}; - - Assert.Contains(PythonProject.DefaultTargetsFile, paths); - Assert.Contains(@"$(MSBuildBinPath)\Microsoft.Common.targets", paths); + string[] paths = GetImportPaths(); + Assert.Contains(PythonProject.DefaultTargetsFile, paths, "Could not find Python default target. Actual imports: " + GetArrayAsString(paths)); + Assert.Contains(@"$(MSBuildBinPath)\Microsoft.Common.targets", paths, "Could not find Microsoft.Common.targets. Actual imports: " + GetArrayAsString(paths)); } [Test] @@ -94,5 +85,40 @@ namespace PythonBinding.Tests { Assert.AreEqual(ItemType.None, project.GetDefaultItemType(null)); } + + /// + /// Gets the import paths from the project. + /// + string[] GetImportPaths() + { + int count = project.MSBuildProject.Imports.Count; + Microsoft.Build.BuildEngine.Import[] imports = new Microsoft.Build.BuildEngine.Import[count]; + project.MSBuildProject.Imports.CopyTo(imports, 0); + + string[] paths = new string[count]; + for (int i = 0; i < count; ++i) { + Microsoft.Build.BuildEngine.Import import = imports[i]; + paths[i] = import.ProjectPath; + } + return paths; + } + + /// + /// Takes the import paths in the project and creates a string with each import + /// on a new line. + /// + string GetImportPathsAsText() + { + return GetArrayAsString(GetImportPaths()); + } + + string GetArrayAsString(string[] array) + { + StringBuilder text = new StringBuilder(); + foreach (string item in array) { + text.AppendLine(item); + } + return text.ToString(); + } } } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj index 78775ce1f2..21dd3e3117 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj @@ -66,7 +66,9 @@ + +