Browse Source

MainFile property now set when converting a project to IronPython.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4151 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Matt Ward 17 years ago
parent
commit
71711e3c7d
  1. 71
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/ConvertProjectToPythonProjectCommand.cs
  2. 28
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs
  3. 12
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonProject.cs
  4. 22
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ConvertToPythonProjectCommandTestFixture.cs
  5. 120
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ProjectHasStartupObjectTestFixture.cs
  6. 27
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/StaticMethodConversionTestFixture.cs
  7. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
  8. 20
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedConvertProjectToPythonProjectCommand.cs

71
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/ConvertProjectToPythonProjectCommand.cs

@ -6,10 +6,14 @@ @@ -6,10 +6,14 @@
// </file>
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Converter;
using ICSharpCode.TextEditor.Document;
@ -42,9 +46,9 @@ namespace ICSharpCode.PythonBinding @@ -42,9 +46,9 @@ namespace ICSharpCode.PythonBinding
protected override IProject CreateProject(string targetProjectDirectory, IProject sourceProject)
{
// Add IronPython reference.
IProject targetProject = base.CreateProject(targetProjectDirectory, sourceProject);
PythonProject targetProject = (PythonProject)base.CreateProject(targetProjectDirectory, sourceProject);
IProjectItemListProvider targetProjectItems = targetProject as IProjectItemListProvider;
targetProjectItems.AddProjectItem(CreateIronPythonReference(targetProject));
targetProjectItems.AddProjectItem(CreateIronPythonReference(targetProject));
return targetProject;
}
@ -55,15 +59,31 @@ namespace ICSharpCode.PythonBinding @@ -55,15 +59,31 @@ namespace ICSharpCode.PythonBinding
{
NRefactoryToPythonConverter converter = NRefactoryToPythonConverter.Create(sourceItem.Include);
if (converter != null) {
targetItem.Include = Path.ChangeExtension(sourceItem.Include, ".py");
targetItem.Include = ChangeExtension(sourceItem.Include);
string code = GetParseableFileContent(sourceItem.FileName);
string pythonCode = converter.Convert(code);
PythonProject pythonTargetProject = (PythonProject)targetItem.Project;
if ((converter.EntryPointMethods.Count > 0) && !pythonTargetProject.HasMainFile) {
pythonTargetProject.AddMainFile(targetItem.Include);
}
SaveFile(targetItem.FileName, pythonCode, textEditorProperties.Encoding);
} else {
LanguageConverterConvertFile(sourceItem, targetItem);
}
}
/// <summary>
/// Adds the MainFile property since adding it in the CreateProject method would mean
/// it gets removed via the base class CopyProperties method.
/// </summary>
protected override void CopyProperties(IProject sourceProject, IProject targetProject)
{
base.CopyProperties(sourceProject, targetProject);
AddMainFile(sourceProject, (PythonProject)targetProject);
}
/// <summary>
/// Calls the LanguageConverter class method ConvertFile which copies the source file to the target
@ -90,11 +110,56 @@ namespace ICSharpCode.PythonBinding @@ -90,11 +110,56 @@ namespace ICSharpCode.PythonBinding
return ParserService.GetParseableFileContent(fileName);
}
/// <summary>
/// Gets the project content for the specified project.
/// </summary>
protected virtual IProjectContent GetProjectContent(IProject project)
{
return ParserService.GetProjectContent(project);
}
ReferenceProjectItem CreateIronPythonReference(IProject project)
{
ReferenceProjectItem reference = new ReferenceProjectItem(project, "IronPython");
reference.SetMetadata("HintPath", @"$(PythonBinPath)\IronPython.dll");
return reference;
}
/// <summary>
/// Adds a MainFile if the source project has a StartupObject.
/// </summary>
void AddMainFile(IProject sourceProject, PythonProject targetProject)
{
string startupObject = GetStartupObject(sourceProject);
if (startupObject != null) {
IClass c = FindClass(sourceProject, startupObject);
if (c != null) {
string fileName = FileUtility.GetRelativePath(sourceProject.Directory, c.CompilationUnit.FileName);
targetProject.AddMainFile(ChangeExtension(fileName));
}
}
}
string GetStartupObject(IProject project)
{
MSBuildBasedProject msbuildProject = project as MSBuildBasedProject;
if (msbuildProject != null) {
return msbuildProject.GetProperty(null, null, "StartupObject");
}
return null;
}
IClass FindClass(IProject project, string name)
{
return GetProjectContent(project).GetClass(name, 0);
}
/// <summary>
/// Changes the extension to ".py"
/// </summary>
static string ChangeExtension(string fileName)
{
return Path.ChangeExtension(fileName, ".py");
}
}
}

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

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
using ICSharpCode.NRefactory;
@ -33,6 +34,7 @@ namespace ICSharpCode.PythonBinding @@ -33,6 +34,7 @@ namespace ICSharpCode.PythonBinding
// references to fields or parameters.
List<ParameterDeclarationExpression> methodParameters = new List<ParameterDeclarationExpression>();
SupportedLanguage language;
List<MethodDeclaration> entryPointMethods;
public NRefactoryToPythonConverter(SupportedLanguage language)
{
@ -124,12 +126,21 @@ namespace ICSharpCode.PythonBinding @@ -124,12 +126,21 @@ namespace ICSharpCode.PythonBinding
// Convert to NRefactory code DOM.
CompilationUnit unit = GenerateCompilationUnit(source, language);
// Convert to Python code.
// Convert to Python code.3
entryPointMethods = new List<MethodDeclaration>();
codeBuilder = new StringBuilder();
unit.AcceptVisitor(this, null);
return codeBuilder.ToString().TrimEnd();
}
/// <summary>
/// Gets a list of possible entry point methods found when converting the
/// python source code.
/// </summary>
public ReadOnlyCollection<MethodDeclaration> EntryPointMethods {
get { return entryPointMethods.AsReadOnly(); }
}
/// <summary>
/// Converts from the NRefactory's binary operator type to a string.
@ -793,6 +804,9 @@ namespace ICSharpCode.PythonBinding @@ -793,6 +804,9 @@ namespace ICSharpCode.PythonBinding
if (IsStatic(methodDeclaration)) {
AppendIndentedLine(methodDeclaration.Name + " = staticmethod(" + methodDeclaration.Name + ")");
AppendNewLine();
// Save Main entry point method.
SaveMethodIfMainEntryPoint(methodDeclaration);
}
return null;
@ -1684,6 +1698,16 @@ namespace ICSharpCode.PythonBinding @@ -1684,6 +1698,16 @@ namespace ICSharpCode.PythonBinding
return SupportedLanguage.VBNet;
}
return SupportedLanguage.CSharp;
}
}
/// <summary>
/// Saves the method declaration if it is a main entry point.
/// </summary>
void SaveMethodIfMainEntryPoint(MethodDeclaration method)
{
if (method.Name == "Main") {
entryPointMethods.Add(method);
}
}
}
}

12
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonProject.cs

@ -61,6 +61,18 @@ namespace ICSharpCode.PythonBinding @@ -61,6 +61,18 @@ namespace ICSharpCode.PythonBinding
return base.GetDefaultItemType(fileName);
}
public void AddMainFile(string fileName)
{
SetProperty(null, null, "MainFile", fileName, PropertyStorageLocations.Base, true);
}
/// <summary>
/// Returns true if a main file is already defined for this project.
/// </summary>
public bool HasMainFile {
get { return GetProperty(null, null, "MainFile") != null; }
}
protected override void Create(ProjectCreateInformation information)
{
base.Create(information);

22
src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ConvertToPythonProjectCommandTestFixture.cs

@ -27,13 +27,16 @@ namespace PythonBinding.Tests.Converter @@ -27,13 +27,16 @@ namespace PythonBinding.Tests.Converter
FileProjectItem source;
FileProjectItem target;
MockProject sourceProject;
IProject targetProject;
PythonProject targetProject;
FileProjectItem textFileSource;
FileProjectItem textFileTarget;
MockTextEditorProperties mockTextEditorProperties;
ReferenceProjectItem ironPythonReference;
string sourceCode = "class Foo\r\n" +
"{\r\n" +
" static void Main()\r\n" +
" {\r\n" +
" }\r\n" +
"}";
[TestFixtureSetUp]
@ -55,7 +58,7 @@ namespace PythonBinding.Tests.Converter @@ -55,7 +58,7 @@ namespace PythonBinding.Tests.Converter
sourceProject = new MockProject();
sourceProject.Directory = @"d:\projects\test";
source = new FileProjectItem(sourceProject, ItemType.Compile, @"src\Program.cs");
targetProject = convertProjectCommand.CallCreateProject(@"d:\projects\test\converted", sourceProject);
targetProject = (PythonProject)convertProjectCommand.CallCreateProject(@"d:\projects\test\converted", sourceProject);
target = new FileProjectItem(targetProject, source.ItemType, source.Include);
source.CopyMetadataTo(target);
@ -125,5 +128,20 @@ namespace PythonBinding.Tests.Converter @@ -125,5 +128,20 @@ namespace PythonBinding.Tests.Converter
{
Assert.AreEqual(@"$(PythonBinPath)\IronPython.dll", ironPythonReference.GetMetadata("HintPath"));
}
[Test]
public void MainFileIsProgramPyFile()
{
PropertyStorageLocations location;
Assert.AreEqual(@"src\Program.py", targetProject.GetProperty(null, null, "MainFile", out location));
}
[Test]
public void PropertyStorageLocationForMainFilePropertyIsGlobal()
{
PropertyStorageLocations location;
targetProject.GetProperty(null, null, "MainFile", out location);
Assert.AreEqual(PropertyStorageLocations.Base, location);
}
}
}

120
src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/ProjectHasStartupObjectTestFixture.cs

@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
// <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.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.PythonBinding;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.DefaultEditor.Codons;
using ICSharpCode.SharpDevelop.Project;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Converter
{
[TestFixture]
public class ProjectHasStartupObjectTestFixture
{
DerivedConvertProjectToPythonProjectCommand convertProjectCommand;
FileProjectItem mainFile;
FileProjectItem main2File;
FileProjectItem targetMainFile;
FileProjectItem targetMain2File;
MSBuildBasedProject sourceProject;
PythonProject targetProject;
MockTextEditorProperties mockTextEditorProperties;
MockProjectContent mockProjectContent;
string startupObject = "RootNamespace.Main";
string mainSource = "class Foo\r\n" +
"{\r\n" +
" static void Main()\r\n" +
" {\r\n" +
" }\r\n" +
"}";
string main2Source = "class Bar\r\n" +
"{\r\n" +
" static void Main()\r\n" +
" {\r\n" +
" }\r\n" +
"}";
[TestFixtureSetUp]
public void SetUpFixture()
{
MSBuildEngineHelper.InitMSBuildEngine();
List<LanguageBindingDescriptor> bindings = new List<LanguageBindingDescriptor>();
using (TextReader reader = PythonBindingAddInFile.ReadAddInFile()) {
AddIn addin = AddIn.Load(reader, String.Empty);
bindings.Add(new LanguageBindingDescriptor(AddInHelper.GetCodon(addin, "/SharpDevelop/Workbench/LanguageBindings", "Python")));
}
LanguageBindingService.SetBindings(bindings);
// Set up IProjectContent so the ConvertProjectToPythonProjectCommand can
// locate the startup object and determine it's filename.
mockProjectContent = new MockProjectContent();
MockClass mainClass = new MockClass(mockProjectContent, startupObject);
mainClass.CompilationUnit.FileName = @"d:\projects\test\src\Main2.cs";
mockProjectContent.ClassToReturnFromGetClass = mainClass;
mockTextEditorProperties = new MockTextEditorProperties();
convertProjectCommand = new DerivedConvertProjectToPythonProjectCommand(mockTextEditorProperties);
convertProjectCommand.ProjectContent = mockProjectContent;
mockTextEditorProperties.Encoding = Encoding.Unicode;
Solution solution = new Solution();
sourceProject = new MSBuildBasedProject(solution.BuildEngine);
sourceProject.Parent = solution;
sourceProject.FileName = @"d:\projects\test\source.csproj";
sourceProject.SetProperty(null, null, "StartupObject", startupObject, PropertyStorageLocations.Base, true);
mainFile = new FileProjectItem(sourceProject, ItemType.Compile, @"src\Main.cs");
targetProject = (PythonProject)convertProjectCommand.CallCreateProject(@"d:\projects\test\converted", sourceProject);
convertProjectCommand.CallCopyProperties(sourceProject, targetProject);
targetMainFile = new FileProjectItem(targetProject, mainFile.ItemType, mainFile.Include);
mainFile.CopyMetadataTo(targetMainFile);
main2File = new FileProjectItem(sourceProject, ItemType.Compile, @"src\Main2.cs");
targetMain2File = new FileProjectItem(targetProject, main2File.ItemType, main2File.Include);
main2File.CopyMetadataTo(targetMain2File);
convertProjectCommand.AddParseableFileContent(mainFile.FileName, mainSource);
convertProjectCommand.AddParseableFileContent(main2File.FileName, main2Source);
convertProjectCommand.CallConvertFile(mainFile, targetMainFile);
convertProjectCommand.CallConvertFile(main2File, targetMain2File);
}
[Test]
public void MainFileIsMain2PyFile()
{
PropertyStorageLocations location;
Assert.AreEqual(@"src\Main2.py", targetProject.GetProperty(null, null, "MainFile", out location));
}
[Test]
public void PropertyStorageLocationForMainFilePropertyIsGlobal()
{
PropertyStorageLocations location;
targetProject.GetProperty(null, null, "MainFile", out location);
Assert.AreEqual(PropertyStorageLocations.Base, location);
}
[Test]
public void ClassSearchedFor()
{
Assert.AreEqual(startupObject, mockProjectContent.GetClassName);
}
}
}

27
src/AddIns/BackendBindings/Python/PythonBinding/Test/Converter/StaticMethodConversionTestFixture.cs

@ -35,12 +35,20 @@ namespace PythonBinding.Tests.Converter @@ -35,12 +35,20 @@ namespace PythonBinding.Tests.Converter
" }\r\n" +
"}";
string python;
NRefactoryToPythonConverter converter;
[SetUp]
public void Init()
{
converter = new NRefactoryToPythonConverter(SupportedLanguage.CSharp);
converter.IndentString = " ";
python = converter.Convert(csharp);
}
[Test]
public void ConvertedPythonCode()
{
NRefactoryToPythonConverter converter = new NRefactoryToPythonConverter(SupportedLanguage.CSharp);
converter.IndentString = " ";
string python = converter.Convert(csharp);
string expectedPython = "class Foo(object):\r\n" +
" def Main(args):\r\n" +
" pass\r\n" +
@ -54,8 +62,19 @@ namespace PythonBinding.Tests.Converter @@ -54,8 +62,19 @@ namespace PythonBinding.Tests.Converter
"\r\n" +
" def Run(self):\r\n" +
" pass";
Assert.AreEqual(expectedPython, python);
}
[Test]
public void EntryPointMethodFound()
{
Assert.AreEqual(1, converter.EntryPointMethods.Count);
}
[Test]
public void MainEntryPointMethodNameIsMain()
{
Assert.AreEqual("Main", converter.EntryPointMethods[0].Name);
}
}
}

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

@ -133,6 +133,7 @@ @@ -133,6 +133,7 @@
<Compile Include="Converter\NullConversionTestFixture.cs" />
<Compile Include="Converter\ObjectCreationTestFixture.cs" />
<Compile Include="Converter\ObjectInitializerConversionTestFixture.cs" />
<Compile Include="Converter\ProjectHasStartupObjectTestFixture.cs" />
<Compile Include="Converter\PropertyConversionTestFixture.cs" />
<Compile Include="Converter\PropertyWithGetSetStatementsTestfixture.cs" />
<Compile Include="Converter\RemoveHandlerConversionTestFixture.cs" />

20
src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/DerivedConvertProjectToPythonProjectCommand.cs

@ -10,6 +10,7 @@ using System.Collections.Generic; @@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Text;
using ICSharpCode.PythonBinding;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.TextEditor.Document;
@ -35,6 +36,7 @@ namespace PythonBinding.Tests.Utils @@ -35,6 +36,7 @@ namespace PythonBinding.Tests.Utils
List<SourceAndTargetFile> sourceAndTargetFilesPassedToBaseClass = new List<SourceAndTargetFile>();
List<ConvertedFile> savedFiles = new List<ConvertedFile>();
List<ConvertedFile> parseableFileContent = new List<ConvertedFile>();
IProjectContent projectContent;
public DerivedConvertProjectToPythonProjectCommand(ITextEditorProperties textEditorProperties)
: base(textEditorProperties)
@ -52,6 +54,14 @@ namespace PythonBinding.Tests.Utils @@ -52,6 +54,14 @@ namespace PythonBinding.Tests.Utils
get { return savedFiles; }
}
/// <summary>
/// Sets the project content to be returned from the GetProjectContent method.
/// </summary>
public IProjectContent ProjectContent {
get { return projectContent; }
set { projectContent = value; }
}
public void AddParseableFileContent(string fileName, string content)
{
parseableFileContent.Add(new ConvertedFile(fileName, content, null));
@ -67,6 +77,11 @@ namespace PythonBinding.Tests.Utils @@ -67,6 +77,11 @@ namespace PythonBinding.Tests.Utils
return base.CreateProject(directory, sourceProject);
}
public void CallCopyProperties(IProject source, IProject target)
{
base.CopyProperties(source, target);
}
protected override void LanguageConverterConvertFile(FileProjectItem source, FileProjectItem target)
{
sourceAndTargetFilesPassedToBaseClass.Add(new SourceAndTargetFile(source, target));
@ -86,5 +101,10 @@ namespace PythonBinding.Tests.Utils @@ -86,5 +101,10 @@ namespace PythonBinding.Tests.Utils
}
return null;
}
protected override IProjectContent GetProjectContent(IProject project)
{
return projectContent;
}
}
}

Loading…
Cancel
Save