Browse Source

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
shortcuts
Matt Ward 18 years ago
parent
commit
7724781cf6
  1. 33
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs
  2. 79
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ArrayCastConversionTestFixture.cs
  3. 89
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/IntegerMethodParameterTestFixture.cs
  4. 54
      src/AddIns/BackendBindings/Python/PythonBinding/Test/CreateNewPythonProjectTestFixture.cs
  5. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

33
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs

@ -245,11 +245,13 @@ namespace ICSharpCode.PythonBinding
Console.WriteLine("VisitCaseLabel"); Console.WriteLine("VisitCaseLabel");
return null; return null;
} }
/// <summary>
/// Ignore the cast and just visit the expression inside the cast.
/// </summary>
public object VisitCastExpression(CastExpression castExpression, object data) public object VisitCastExpression(CastExpression castExpression, object data)
{ {
Console.WriteLine("VisitCastExpression"); return castExpression.Expression.AcceptVisitor(this, data);
return null;
} }
public object VisitCatchClause(CatchClause catchClause, object data) public object VisitCatchClause(CatchClause catchClause, object data)
@ -694,20 +696,23 @@ namespace ICSharpCode.PythonBinding
/// </summary> /// </summary>
public object VisitInvocationExpression(InvocationExpression invocationExpression, object data) 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(); 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. // Create method invoke.
CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(); CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression();
methodInvoke.Parameters.AddRange(ConvertExpressions(invocationExpression.Arguments)); methodInvoke.Parameters.AddRange(ConvertExpressions(invocationExpression.Arguments));
methodInvoke.Method = methodRef; methodInvoke.Method = methodRef;
return methodInvoke; return methodInvoke;
} }
@ -1449,7 +1454,9 @@ namespace ICSharpCode.PythonBinding
List<CodeExpression> codeExpressions = new List<CodeExpression>(); List<CodeExpression> codeExpressions = new List<CodeExpression>();
foreach (Expression expression in expressions) { foreach (Expression expression in expressions) {
CodeExpression convertedCodeExpression = (CodeExpression)expression.AcceptVisitor(this, null); CodeExpression convertedCodeExpression = (CodeExpression)expression.AcceptVisitor(this, null);
codeExpressions.Add(convertedCodeExpression); if (convertedCodeExpression != null) {
codeExpressions.Add(convertedCodeExpression);
}
} }
return codeExpressions.ToArray(); return codeExpressions.ToArray();
} }

79
src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ArrayCastConversionTestFixture.cs

@ -0,0 +1,79 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using ICSharpCode.PythonBinding;
using NUnit.Framework;
namespace PythonBinding.Tests.Converter
{
/// <summary>
/// Tests that an array cast is correctly converted to Python.
/// </summary>
[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<int[]> list = new List<int[]>();\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);
}
}
}

89
src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/IntegerMethodParameterTestFixture.cs

@ -0,0 +1,89 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using ICSharpCode.PythonBinding;
using NUnit.Framework;
namespace PythonBinding.Tests.Converter
{
/// <summary>
/// Tests that a method call is converted correctly.
/// </summary>
[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);
}
}
}

54
src/AddIns/BackendBindings/Python/PythonBinding/Test/CreateNewPythonProjectTestFixture.cs

@ -7,6 +7,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Text;
using ICSharpCode.PythonBinding; using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
@ -52,23 +53,13 @@ namespace PythonBinding.Tests
{ {
Assert.AreEqual(info.ProjectName, project.Name); Assert.AreEqual(info.ProjectName, project.Name);
} }
[Test]
public void TwoImports()
{
Assert.AreEqual(2, project.MSBuildProject.Imports.Count);
}
[Test] [Test]
public void Imports() public void Imports()
{ {
Microsoft.Build.BuildEngine.Import[] imports = {null, null}; string[] paths = GetImportPaths();
project.MSBuildProject.Imports.CopyTo(imports, 0); 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));
string[] paths = new string[] {imports[0].ProjectPath, imports[1].ProjectPath};
Assert.Contains(PythonProject.DefaultTargetsFile, paths);
Assert.Contains(@"$(MSBuildBinPath)\Microsoft.Common.targets", paths);
} }
[Test] [Test]
@ -94,5 +85,40 @@ namespace PythonBinding.Tests
{ {
Assert.AreEqual(ItemType.None, project.GetDefaultItemType(null)); Assert.AreEqual(ItemType.None, project.GetDefaultItemType(null));
} }
/// <summary>
/// Gets the import paths from the project.
/// </summary>
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;
}
/// <summary>
/// Takes the import paths in the project and creates a string with each import
/// on a new line.
/// </summary>
string GetImportPathsAsText()
{
return GetArrayAsString(GetImportPaths());
}
string GetArrayAsString(string[] array)
{
StringBuilder text = new StringBuilder();
foreach (string item in array) {
text.AppendLine(item);
}
return text.ToString();
}
} }
} }

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

@ -66,7 +66,9 @@
<Compile Include="AddInFileTestFixture.cs" /> <Compile Include="AddInFileTestFixture.cs" />
<Compile Include="CompilingOptionsPanelTestFixture.cs" /> <Compile Include="CompilingOptionsPanelTestFixture.cs" />
<Compile Include="Converter\AddHandlerConversionTestFixture.cs" /> <Compile Include="Converter\AddHandlerConversionTestFixture.cs" />
<Compile Include="Converter\ArrayCastConversionTestFixture.cs" />
<Compile Include="Converter\ArrayConversionTestFixture.cs" /> <Compile Include="Converter\ArrayConversionTestFixture.cs" />
<Compile Include="Converter\IntegerMethodParameterTestFixture.cs" />
<Compile Include="Converter\BaseClassReferenceTestFixture.cs" /> <Compile Include="Converter\BaseClassReferenceTestFixture.cs" />
<Compile Include="Converter\BinaryOperatorConversionTests.cs" /> <Compile Include="Converter\BinaryOperatorConversionTests.cs" />
<Compile Include="Converter\ClassConstructorConversionTestFixture.cs" /> <Compile Include="Converter\ClassConstructorConversionTestFixture.cs" />

Loading…
Cancel
Save