Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3738 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
33 changed files with 1275 additions and 220 deletions
@ -0,0 +1,125 @@ |
|||||||
|
// <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.Text; |
||||||
|
using IronPython.Compiler.Ast; |
||||||
|
|
||||||
|
namespace ICSharpCode.PythonBinding |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Represents a member field expression in a Control or Form:
|
||||||
|
///
|
||||||
|
/// self._textBox1
|
||||||
|
/// self._textBox1.Name
|
||||||
|
/// </summary>
|
||||||
|
public class PythonControlFieldExpression |
||||||
|
{ |
||||||
|
string memberName = String.Empty; |
||||||
|
string fullMemberName = String.Empty; |
||||||
|
|
||||||
|
PythonControlFieldExpression(string memberName, string fullMemberName) |
||||||
|
{ |
||||||
|
this.memberName = memberName; |
||||||
|
this.fullMemberName = fullMemberName; |
||||||
|
} |
||||||
|
|
||||||
|
public string MemberName { |
||||||
|
get { return memberName; } |
||||||
|
} |
||||||
|
|
||||||
|
public string FullMemberName { |
||||||
|
get { return fullMemberName; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a PythonControlField from a member expression:
|
||||||
|
///
|
||||||
|
/// self._textBox1
|
||||||
|
/// self._textBox1.Name
|
||||||
|
/// </summary>
|
||||||
|
public static PythonControlFieldExpression Create(MemberExpression expression) |
||||||
|
{ |
||||||
|
string memberName = expression.Name.ToString(); |
||||||
|
string fullMemberName = PythonControlFieldExpression.GetMemberName(expression); |
||||||
|
return new PythonControlFieldExpression(memberName, fullMemberName); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the variable name from an expression of the form:
|
||||||
|
///
|
||||||
|
/// self._textBox1.Name
|
||||||
|
///
|
||||||
|
/// Returns "textBox1"
|
||||||
|
/// </summary>
|
||||||
|
public static string GetVariableNameFromSelfReference(string name) |
||||||
|
{ |
||||||
|
int startIndex = name.IndexOf('.'); |
||||||
|
if (startIndex > 0) { |
||||||
|
name = name.Substring(startIndex + 1); |
||||||
|
int endIndex = name.IndexOf('.'); |
||||||
|
if (endIndex > 0) { |
||||||
|
return GetVariableName(name.Substring(0, endIndex)); |
||||||
|
} |
||||||
|
return String.Empty; |
||||||
|
} |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the variable name of the control being added.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetControlNameBeingAdded(CallExpression node) |
||||||
|
{ |
||||||
|
//if (node.Args.Length > 0) {
|
||||||
|
Arg arg = node.Args[0]; |
||||||
|
MemberExpression memberExpression = arg.Expression as MemberExpression; |
||||||
|
return GetVariableName(memberExpression.Name.ToString()); |
||||||
|
//}
|
||||||
|
//return null;
|
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the underscore from the variable name.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetVariableName(string name) |
||||||
|
{ |
||||||
|
if (!String.IsNullOrEmpty(name)) { |
||||||
|
if (name.Length > 1) { |
||||||
|
if (name[0] == '_') { |
||||||
|
return name.Substring(1); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the fully qualified name being referenced in the MemberExpression.
|
||||||
|
/// </summary>
|
||||||
|
public static string GetMemberName(MemberExpression expression) |
||||||
|
{ |
||||||
|
StringBuilder typeName = new StringBuilder(); |
||||||
|
|
||||||
|
while (expression != null) { |
||||||
|
typeName.Insert(0, expression.Name); |
||||||
|
typeName.Insert(0, "."); |
||||||
|
|
||||||
|
NameExpression nameExpression = expression.Target as NameExpression; |
||||||
|
expression = expression.Target as MemberExpression; |
||||||
|
if (expression == null) { |
||||||
|
if (nameExpression != null) { |
||||||
|
typeName.Insert(0, nameExpression.Name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return typeName.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,33 +0,0 @@ |
|||||||
// <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.Drawing; |
|
||||||
using System.Windows.Forms; |
|
||||||
|
|
||||||
namespace ICSharpCode.PythonBinding |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Description of PythonFormVisitor.
|
|
||||||
/// </summary>
|
|
||||||
public class PythonFormVisitor |
|
||||||
{ |
|
||||||
public PythonFormVisitor() |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a form from python code.
|
|
||||||
/// </summary>
|
|
||||||
public Form CreateForm(string pythonCode, IComponentCreator componentCreator) |
|
||||||
{ |
|
||||||
Form form = (Form)componentCreator.CreateComponent(typeof(Form), "MainForm"); |
|
||||||
form.Name = "MainForm"; |
|
||||||
return form; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,196 @@ |
|||||||
|
// <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.ComponentModel; |
||||||
|
using System.Drawing; |
||||||
|
using System.Reflection; |
||||||
|
using System.Text; |
||||||
|
using System.Windows.Forms; |
||||||
|
|
||||||
|
using IronPython.Compiler.Ast; |
||||||
|
|
||||||
|
namespace ICSharpCode.PythonBinding |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Visits the code's Python AST and creates a Windows Form.
|
||||||
|
/// </summary>
|
||||||
|
public class PythonFormWalker : PythonWalker |
||||||
|
{ |
||||||
|
Form form; |
||||||
|
PythonControlFieldExpression fieldExpression; |
||||||
|
IComponentCreator componentCreator; |
||||||
|
bool walkingAssignment; |
||||||
|
Dictionary<string, object> createdObjects = new Dictionary<string, object>(); |
||||||
|
|
||||||
|
public PythonFormWalker(IComponentCreator componentCreator) |
||||||
|
{ |
||||||
|
this.componentCreator = componentCreator; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a form from python code.
|
||||||
|
/// </summary>
|
||||||
|
public Form CreateForm(string pythonCode) |
||||||
|
{ |
||||||
|
PythonParser parser = new PythonParser(); |
||||||
|
PythonAst ast = parser.CreateAst(@"Form.py", pythonCode); |
||||||
|
ast.Walk(this); |
||||||
|
|
||||||
|
// Did we find the InitializeComponent method?
|
||||||
|
if (form == null) { |
||||||
|
throw new PythonFormWalkerException("Unable to find InitializeComponents method."); |
||||||
|
} |
||||||
|
|
||||||
|
return form; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Walk(ClassDefinition node) |
||||||
|
{ |
||||||
|
if (node.Body != null) { |
||||||
|
node.Body.Walk(this); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Walk(FunctionDefinition node) |
||||||
|
{ |
||||||
|
if (IsInitializeComponentMethod(node)) { |
||||||
|
form = (Form)componentCreator.CreateComponent(typeof(Form), "MainForm"); |
||||||
|
node.Body.Walk(this); |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Walk(AssignmentStatement node) |
||||||
|
{ |
||||||
|
if (node.Left.Count > 0) { |
||||||
|
MemberExpression memberExpression = node.Left[0] as MemberExpression; |
||||||
|
if (memberExpression != null) { |
||||||
|
fieldExpression = PythonControlFieldExpression.Create(memberExpression); |
||||||
|
|
||||||
|
walkingAssignment = true; |
||||||
|
node.Right.Walk(this); |
||||||
|
walkingAssignment = false; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Walk(ConstantExpression node) |
||||||
|
{ |
||||||
|
Control control = GetCurrentControl(); |
||||||
|
SetPropertyValue(control, fieldExpression.MemberName, node.Value); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
Control GetCurrentControl() |
||||||
|
{ |
||||||
|
string variableName = PythonControlFieldExpression.GetVariableNameFromSelfReference(fieldExpression.FullMemberName); |
||||||
|
if (variableName.Length > 0) { |
||||||
|
return GetControl(variableName); |
||||||
|
} |
||||||
|
return form; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Walk(CallExpression node) |
||||||
|
{ |
||||||
|
MemberExpression memberExpression = node.Target as MemberExpression; |
||||||
|
if (memberExpression != null) { |
||||||
|
string name = PythonControlFieldExpression.GetMemberName(memberExpression); |
||||||
|
if (walkingAssignment) { |
||||||
|
Type type = GetType(name); |
||||||
|
List<object> args = GetArguments(node); |
||||||
|
object instance = componentCreator.CreateInstance(type, args, fieldExpression.MemberName, false); |
||||||
|
if (!SetPropertyValue(form, fieldExpression.MemberName, instance)) { |
||||||
|
AddComponent(fieldExpression.MemberName, instance); |
||||||
|
} |
||||||
|
} else if (name == "self.Controls.Add") { |
||||||
|
string controlName = PythonControlFieldExpression.GetControlNameBeingAdded(node); |
||||||
|
form.Controls.Add(GetControl(controlName)); |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the arguments passed to the call expression.
|
||||||
|
/// </summary>
|
||||||
|
static List<object> GetArguments(CallExpression expression) |
||||||
|
{ |
||||||
|
List<object> args = new List<object>(); |
||||||
|
foreach (Arg a in expression.Args) { |
||||||
|
ConstantExpression constantExpression = a.Expression as ConstantExpression; |
||||||
|
if (constantExpression != null) { |
||||||
|
args.Add(constantExpression.Value); |
||||||
|
} |
||||||
|
} |
||||||
|
return args; |
||||||
|
} |
||||||
|
|
||||||
|
static bool IsInitializeComponentMethod(FunctionDefinition node) |
||||||
|
{ |
||||||
|
string name = node.Name.ToString().ToLowerInvariant(); |
||||||
|
return name == "initializecomponent" || name == "initializecomponents"; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the value of a form's property.
|
||||||
|
/// </summary>
|
||||||
|
bool SetPropertyValue(Control control, string name, object @value) |
||||||
|
{ |
||||||
|
PropertyInfo propertyInfo = control.GetType().GetProperty(name); |
||||||
|
if (propertyInfo != null) { |
||||||
|
propertyInfo.SetValue(control, @value, null); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
Type GetType(string typeName) |
||||||
|
{ |
||||||
|
Type type = componentCreator.GetType(typeName); |
||||||
|
if (type == null) { |
||||||
|
throw new PythonFormWalkerException(String.Format("Could not find type '{0}'.", typeName)); |
||||||
|
} |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks for the control with the specified name in the objects that have been
|
||||||
|
/// created whilst processing the InitializeComponent method.
|
||||||
|
/// </summary>
|
||||||
|
Control GetControl(string name) |
||||||
|
{ |
||||||
|
object o = null; |
||||||
|
if (createdObjects.TryGetValue(name, out o)) { |
||||||
|
return o as Control; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a component to the list of created objects.
|
||||||
|
/// </summary>
|
||||||
|
void AddComponent(string name, object component) |
||||||
|
{ |
||||||
|
string variableName = PythonControlFieldExpression.GetVariableName(name); |
||||||
|
componentCreator.Add(component as IComponent, variableName); |
||||||
|
createdObjects.Add(variableName, component); |
||||||
|
} |
||||||
|
|
||||||
|
static string GetFirstArgumentAsString(CallExpression node) |
||||||
|
{ |
||||||
|
List<object> args = GetArguments(node); |
||||||
|
if (args.Count > 0) { |
||||||
|
return args[0] as String; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
// <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; |
||||||
|
|
||||||
|
namespace ICSharpCode.PythonBinding |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Exception thrown by the PythonFormWalker class.
|
||||||
|
/// </summary>
|
||||||
|
public class PythonFormWalkerException : Exception |
||||||
|
{ |
||||||
|
public PythonFormWalkerException(string message) : base(message) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,92 @@ |
|||||||
|
// <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.ComponentModel; |
||||||
|
using System.Drawing; |
||||||
|
using System.IO; |
||||||
|
using System.Windows.Forms; |
||||||
|
|
||||||
|
using ICSharpCode.PythonBinding; |
||||||
|
using NUnit.Framework; |
||||||
|
using PythonBinding.Tests.Utils; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Designer |
||||||
|
{ |
||||||
|
[TestFixture] |
||||||
|
public class LoadTextBoxTestFixture : LoadFormTestFixtureBase |
||||||
|
{ |
||||||
|
string pythonCode = "class MainForm(System.Windows.Forms.Form):\r\n" + |
||||||
|
" def InitializeComponent(self):\r\n" + |
||||||
|
" self._textBox1 = System.Windows.Forms.TextBox()\r\n" + |
||||||
|
" self.SuspendLayout()\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" # textBox1\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" self._textBox1.Name = \"textBoxName\"\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" # form1\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" self.Name = \"form1\"\r\n" + |
||||||
|
" self.Controls.Add(self._textBox1)\r\n" + |
||||||
|
" self.ResumeLayout(False)\r\n"; |
||||||
|
Form form; |
||||||
|
TextBox textBox; |
||||||
|
|
||||||
|
[TestFixtureSetUp] |
||||||
|
public void SetUpFixture() |
||||||
|
{ |
||||||
|
PythonFormWalker walker = new PythonFormWalker(this); |
||||||
|
form = walker.CreateForm(pythonCode); |
||||||
|
if (form.Controls.Count > 0) { |
||||||
|
textBox = form.Controls[0] as TextBox; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[TestFixtureTearDown] |
||||||
|
public void TearDownFixture() |
||||||
|
{ |
||||||
|
form.Dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void TextBoxInstanceCreated() |
||||||
|
{ |
||||||
|
CreatedInstance instance = new CreatedInstance(typeof(TextBox), new List<object>(), "_textBox1", false); |
||||||
|
Assert.Contains(instance, CreatedInstances); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void AddedComponentsContainsTextBox() |
||||||
|
{ |
||||||
|
CreatedInstance instance = GetCreatedInstance(typeof(TextBox)); |
||||||
|
|
||||||
|
AddedComponent component = new AddedComponent(instance.Object as IComponent, "textBox1"); |
||||||
|
Assert.Contains(component, AddedComponents); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void TextBoxAddedToForm() |
||||||
|
{ |
||||||
|
Assert.IsNotNull(textBox); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void TextBoxObjectMatchesObjectAddedToComponentCreator() |
||||||
|
{ |
||||||
|
CreatedInstance instance = GetCreatedInstance(typeof(TextBox)); |
||||||
|
Assert.AreSame(textBox, instance.Object as TextBox); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void TextBoxName() |
||||||
|
{ |
||||||
|
Assert.AreEqual("textBoxName", textBox.Name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,70 @@ |
|||||||
|
// <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.Drawing; |
||||||
|
using System.IO; |
||||||
|
using System.Windows.Forms; |
||||||
|
|
||||||
|
using ICSharpCode.PythonBinding; |
||||||
|
using IronPython.Compiler.Ast; |
||||||
|
using Microsoft.Scripting; |
||||||
|
using NUnit.Framework; |
||||||
|
using PythonBinding.Tests.Utils; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Designer |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Tests that the PythonFormVisitor throws an exception if no InitializeComponent or
|
||||||
|
/// InitializeComponent method can be found.
|
||||||
|
/// </summary>
|
||||||
|
[TestFixture] |
||||||
|
public class MissingInitializeComponentMethodTestFixture : LoadFormTestFixtureBase |
||||||
|
{ |
||||||
|
string pythonCode = "from System.Windows.Forms import Form\r\n" + |
||||||
|
"\r\n" + |
||||||
|
"class MainForm(System.Windows.Forms.Form):\r\n" + |
||||||
|
" def __init__(self):\r\n" + |
||||||
|
" self.MissingMethod()\r\n" + |
||||||
|
"\r\n" + |
||||||
|
" def MissingMethod(self):\r\n" + |
||||||
|
" pass\r\n"; |
||||||
|
[Test] |
||||||
|
[ExpectedException(typeof(PythonFormWalkerException))] |
||||||
|
public void PythonFormWalkerExceptionThrown() |
||||||
|
{ |
||||||
|
PythonFormWalker walker = new PythonFormWalker(this); |
||||||
|
walker.CreateForm(pythonCode); |
||||||
|
Assert.Fail("Exception should have been thrown before this."); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check that the PythonFormWalker does not try to walk the class body if it is null.
|
||||||
|
/// </summary>
|
||||||
|
[Test] |
||||||
|
public void ClassWithNoBody() |
||||||
|
{ |
||||||
|
ClassDefinition classDef = new ClassDefinition(new SymbolId(10), null, null); |
||||||
|
PythonFormWalker walker = new PythonFormWalker(this); |
||||||
|
walker.Walk(classDef); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make sure we do not get an ArgumentOutOfRangeException when walking the
|
||||||
|
/// AssignmentStatement.
|
||||||
|
/// </summary>
|
||||||
|
[Test] |
||||||
|
public void NoLeftHandSideExpressionsInAssignment() |
||||||
|
{ |
||||||
|
List<Expression> lhs = new List<Expression>(); |
||||||
|
AssignmentStatement assign = new AssignmentStatement(lhs.ToArray(), null); |
||||||
|
PythonFormWalker walker = new PythonFormWalker(this); |
||||||
|
walker.Walk(assign); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,87 @@ |
|||||||
|
// <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.Drawing; |
||||||
|
using System.IO; |
||||||
|
using System.Windows.Forms; |
||||||
|
|
||||||
|
using ICSharpCode.PythonBinding; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.TextEditor; |
||||||
|
using ICSharpCode.TextEditor.Document; |
||||||
|
using NUnit.Framework; |
||||||
|
using PythonBinding.Tests.Utils; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Designer |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Tests the code can be generated if there is no new line after the InitializeComponent method.
|
||||||
|
/// </summary>
|
||||||
|
[TestFixture] |
||||||
|
public class NoNewLineAfterInitializeComponentMethodTestFixture |
||||||
|
{ |
||||||
|
IDocument document; |
||||||
|
|
||||||
|
[TestFixtureSetUp] |
||||||
|
public void SetUpFixture() |
||||||
|
{ |
||||||
|
using (TextEditorControl textEditor = new TextEditorControl()) { |
||||||
|
document = textEditor.Document; |
||||||
|
textEditor.Text = GetTextEditorCode(); |
||||||
|
|
||||||
|
PythonParser parser = new PythonParser(); |
||||||
|
ICompilationUnit compilationUnit = parser.Parse(new DefaultProjectContent(), @"test.py", document.TextContent); |
||||||
|
|
||||||
|
using (Form form = new Form()) { |
||||||
|
form.Name = "MainForm"; |
||||||
|
form.ClientSize = new Size(499, 309); |
||||||
|
|
||||||
|
PythonDesignerGenerator.Merge(form, document, compilationUnit, new MockTextEditorProperties()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void GeneratedCode() |
||||||
|
{ |
||||||
|
string expectedCode = "from System.Windows.Forms import Form\r\n" + |
||||||
|
"\r\n" + |
||||||
|
"class MainForm(Form):\r\n" + |
||||||
|
"\tdef __init__(self):\r\n" + |
||||||
|
"\t\tself.InitializeComponent()\r\n" + |
||||||
|
"\t\r\n" + |
||||||
|
"\tdef InitializeComponent(self):\r\n" + |
||||||
|
"\t\tself.SuspendLayout()\r\n" + |
||||||
|
"\t\t# \r\n" + |
||||||
|
"\t\t# MainForm\r\n" + |
||||||
|
"\t\t# \r\n" + |
||||||
|
"\t\tself.ClientSize = System.Drawing.Size(499, 309)\r\n" + |
||||||
|
"\t\tself.Name = \"MainForm\"\r\n" + |
||||||
|
"\t\tself.ResumeLayout(False)\r\n" + |
||||||
|
"\t\tself.PerformLayout()\r\n"; |
||||||
|
|
||||||
|
Assert.AreEqual(expectedCode, document.TextContent); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// No new line after the pass statement for InitializeComponent method.
|
||||||
|
/// </summary>
|
||||||
|
string GetTextEditorCode() |
||||||
|
{ |
||||||
|
return "from System.Windows.Forms import Form\r\n" + |
||||||
|
"\r\n" + |
||||||
|
"class MainForm(Form):\r\n" + |
||||||
|
"\tdef __init__(self):\r\n" + |
||||||
|
"\t\tself.InitializeComponent()\r\n" + |
||||||
|
"\t\r\n" + |
||||||
|
"\tdef InitializeComponent(self):\r\n" + |
||||||
|
"\t\tpass"; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,73 @@ |
|||||||
|
// <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.ComponentModel; |
||||||
|
using System.Drawing; |
||||||
|
using System.IO; |
||||||
|
using System.Windows.Forms; |
||||||
|
|
||||||
|
using ICSharpCode.PythonBinding; |
||||||
|
using NUnit.Framework; |
||||||
|
using PythonBinding.Tests.Utils; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Designer |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// When a text box is not added to the form's Control collection in InitializeComponent then:
|
||||||
|
///
|
||||||
|
/// 1) Text box should not be added to the form's Control collection when the form is created.
|
||||||
|
/// 2) Text box should be registered with the designer via the IComponentCreator.Add method.
|
||||||
|
/// 3) Text box should be created via the IComponentCreator.CreateInstance method.
|
||||||
|
/// </summary>
|
||||||
|
[TestFixture] |
||||||
|
public class TextBoxNotAddedToFormTestFixture : LoadFormTestFixtureBase |
||||||
|
{ |
||||||
|
string pythonCode = "class MainForm(System.Windows.Forms.Form):\r\n" + |
||||||
|
" def InitializeComponent(self):\r\n" + |
||||||
|
" self._textBox1 = System.Windows.Forms.TextBox()\r\n" + |
||||||
|
" self.SuspendLayout()\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" # textBox1\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" self._textBox1.Name = \"textBox1\"\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" # form1\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" self.ResumeLayout(False)\r\n"; |
||||||
|
Form form; |
||||||
|
|
||||||
|
[TestFixtureSetUp] |
||||||
|
public void SetUpFixture() |
||||||
|
{ |
||||||
|
PythonFormWalker walker = new PythonFormWalker(this); |
||||||
|
form = walker.CreateForm(pythonCode); |
||||||
|
} |
||||||
|
|
||||||
|
[TestFixtureTearDown] |
||||||
|
public void TearDownFixture() |
||||||
|
{ |
||||||
|
form.Dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void AddedComponentsContainsTextBox() |
||||||
|
{ |
||||||
|
CreatedInstance instance = GetCreatedInstance(typeof(TextBox)); |
||||||
|
|
||||||
|
AddedComponent c = new AddedComponent(instance.Object as IComponent, "textBox1"); |
||||||
|
Assert.Contains(c, AddedComponents); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void TextBoxIsNotAddedToForm() |
||||||
|
{ |
||||||
|
Assert.AreEqual(0, form.Controls.Count); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,85 @@ |
|||||||
|
// <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.Drawing; |
||||||
|
using System.IO; |
||||||
|
using System.Windows.Forms; |
||||||
|
|
||||||
|
using ICSharpCode.FormsDesigner; |
||||||
|
using ICSharpCode.PythonBinding; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.TextEditor; |
||||||
|
using ICSharpCode.TextEditor.Document; |
||||||
|
using NUnit.Framework; |
||||||
|
using PythonBinding.Tests.Utils; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Designer |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Tests that the indent information in the ITextEditorProperties is passed to the generator.
|
||||||
|
/// </summary>
|
||||||
|
[TestFixture] |
||||||
|
public class TextEditorIndentPassedToGeneratorTestFixture |
||||||
|
{ |
||||||
|
IDocument document; |
||||||
|
|
||||||
|
[TestFixtureSetUp] |
||||||
|
public void SetUpFixture() |
||||||
|
{ |
||||||
|
using (FormsDesignerViewContent viewContent = new FormsDesignerViewContent(null, new MockOpenedFile("Test.py"))) { |
||||||
|
viewContent.DesignerCodeFileContent = "class MainForm(Form):\r\n" + |
||||||
|
" def __init__(self):\r\n" + |
||||||
|
" self.InitializeComponent()\r\n" + |
||||||
|
"\r\n" + |
||||||
|
" def InitializeComponent(self):\r\n" + |
||||||
|
" pass\r\n"; |
||||||
|
|
||||||
|
document = viewContent.DesignerCodeFileDocument; |
||||||
|
|
||||||
|
ParseInformation parseInfo = new ParseInformation(); |
||||||
|
PythonParser parser = new PythonParser(); |
||||||
|
ICompilationUnit compilationUnit = parser.Parse(new DefaultProjectContent(), @"test.py", document.TextContent); |
||||||
|
parseInfo.SetCompilationUnit(compilationUnit); |
||||||
|
|
||||||
|
using (Form form = new Form()) { |
||||||
|
form.Name = "MainForm"; |
||||||
|
|
||||||
|
MockTextEditorProperties textEditorProperties = new MockTextEditorProperties(); |
||||||
|
textEditorProperties.ConvertTabsToSpaces = true; |
||||||
|
textEditorProperties.IndentationSize = 1; |
||||||
|
|
||||||
|
DerivedPythonDesignerGenerator generator = new DerivedPythonDesignerGenerator(textEditorProperties); |
||||||
|
generator.ParseInfoToReturnFromParseFileMethod = parseInfo; |
||||||
|
generator.Attach(viewContent); |
||||||
|
generator.MergeRootComponentChanges(form); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void GeneratedCode() |
||||||
|
{ |
||||||
|
string expectedCode = "class MainForm(Form):\r\n" + |
||||||
|
" def __init__(self):\r\n" + |
||||||
|
" self.InitializeComponent()\r\n" + |
||||||
|
"\r\n" + |
||||||
|
" def InitializeComponent(self):\r\n" + |
||||||
|
" self.SuspendLayout()\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" # MainForm\r\n" + |
||||||
|
" # \r\n" + |
||||||
|
" self.ClientSize = System.Drawing.Size(284, 264)\r\n" + |
||||||
|
" self.Name = \"MainForm\"\r\n" + |
||||||
|
" self.ResumeLayout(False)\r\n" + |
||||||
|
" self.PerformLayout()\r\n"; |
||||||
|
|
||||||
|
Assert.AreEqual(expectedCode, document.TextContent); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,46 @@ |
|||||||
|
// <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.Drawing; |
||||||
|
using System.IO; |
||||||
|
using System.Windows.Forms; |
||||||
|
|
||||||
|
using ICSharpCode.PythonBinding; |
||||||
|
using IronPython.Compiler.Ast; |
||||||
|
using Microsoft.Scripting; |
||||||
|
using NUnit.Framework; |
||||||
|
using PythonBinding.Tests.Utils; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Designer |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Tests that the PythonFormWalker throws a PythonFormWalkerException if a unknown type is used in the
|
||||||
|
/// form.
|
||||||
|
/// </summary>
|
||||||
|
[TestFixture] |
||||||
|
public class UnknownTypeTestFixture : LoadFormTestFixtureBase |
||||||
|
{ |
||||||
|
string pythonCode = "from System.Windows.Forms import Form\r\n" + |
||||||
|
"\r\n" + |
||||||
|
"class MainForm(System.Windows.Forms.Form):\r\n" + |
||||||
|
" def __init__(self):\r\n" + |
||||||
|
" self.InitializeComponent()\r\n" + |
||||||
|
"\r\n" + |
||||||
|
" def InitializeComponent(self):\r\n" + |
||||||
|
" self.ClientSize = Unknown.Type(10)\r\n"; |
||||||
|
[Test] |
||||||
|
[ExpectedException(typeof(PythonFormWalkerException))] |
||||||
|
public void PythonFormWalkerExceptionThrown() |
||||||
|
{ |
||||||
|
PythonFormWalker walker = new PythonFormWalker(this); |
||||||
|
walker.CreateForm(pythonCode); |
||||||
|
Assert.Fail("Exception should have been thrown before this."); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,68 +0,0 @@ |
|||||||
// <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 Microsoft.Scripting.Runtime; |
|
||||||
using System; |
|
||||||
using System.CodeDom; |
|
||||||
using System.CodeDom.Compiler; |
|
||||||
using System.IO; |
|
||||||
using IronPython; |
|
||||||
using IronPython.Compiler; |
|
||||||
using IronPython.Compiler.Ast; |
|
||||||
using IronPython.Runtime; |
|
||||||
using NUnit.Framework; |
|
||||||
|
|
||||||
namespace PythonBinding.Tests.Parsing |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Tests the IronPython's parser.
|
|
||||||
/// </summary>
|
|
||||||
[TestFixture] |
|
||||||
public class IronPythonParserTestFixture |
|
||||||
{ |
|
||||||
/// <summary>
|
|
||||||
/// Cannot create PrintStatement for code com.
|
|
||||||
/// </summary>
|
|
||||||
// [Test]s
|
|
||||||
// public void Test()
|
|
||||||
// {
|
|
||||||
// string pythonScript = "print 'Hello'";
|
|
||||||
// PythonProvider provider = new PythonProvider();
|
|
||||||
// CodeCompileUnit unit = provider.Parse(new StringReader(pythonScript));
|
|
||||||
// }
|
|
||||||
|
|
||||||
[Test] |
|
||||||
public void Test2() |
|
||||||
{ |
|
||||||
// string pythonScript = "print 'Hello'";
|
|
||||||
// CompilerContext context = new CompilerContext();
|
|
||||||
// Parser parser = Parser.FromString(null, context, pythonScript);
|
|
||||||
// Statement statement = parser.ParseFileInput();
|
|
||||||
} |
|
||||||
|
|
||||||
[Test] |
|
||||||
public void Test3() |
|
||||||
{ |
|
||||||
// string pythonScript = "Console.WriteLine";
|
|
||||||
// CompilerContext context = new CompilerContext();
|
|
||||||
// Parser parser = Parser.FromString(null, context, pythonScript);
|
|
||||||
// Statement statement = parser.ParseFileInput();
|
|
||||||
// ResolveVisitor visitor = new ResolveVisitor();
|
|
||||||
// statement.Walk(visitor);
|
|
||||||
// Console.WriteLine(statement.GetType().FullName);
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public class ResolveVisitor : PythonWalker |
|
||||||
{ |
|
||||||
public override bool Walk(NameExpression node) |
|
||||||
{ |
|
||||||
System.Console.WriteLine("NameExpression: " + node.Name); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -0,0 +1,54 @@ |
|||||||
|
// <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.ComponentModel; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Utils |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Component passed to the IComponentCreator.Add method.
|
||||||
|
/// </summary>
|
||||||
|
public class AddedComponent |
||||||
|
{ |
||||||
|
public AddedComponent(IComponent component, string name) |
||||||
|
{ |
||||||
|
Component = component; |
||||||
|
Name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public string Name { get; set; } |
||||||
|
public IComponent Component { get; set; } |
||||||
|
|
||||||
|
public override bool Equals(object obj) |
||||||
|
{ |
||||||
|
AddedComponent rhs = obj as AddedComponent; |
||||||
|
if (rhs != null) { |
||||||
|
return Name == rhs.Name && Component == rhs.Component; |
||||||
|
} |
||||||
|
return base.Equals(obj); |
||||||
|
} |
||||||
|
|
||||||
|
public override int GetHashCode() |
||||||
|
{ |
||||||
|
return Component.GetHashCode() ^ Name.GetHashCode(); |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() |
||||||
|
{ |
||||||
|
return "AddedComponent [Component=" + GetComponentTypeName() + "Name=" + Name + "]"; |
||||||
|
} |
||||||
|
|
||||||
|
string GetComponentTypeName() |
||||||
|
{ |
||||||
|
if (Component != null) { |
||||||
|
return Component.GetType().Name; |
||||||
|
} |
||||||
|
return "<null>"; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,69 @@ |
|||||||
|
// <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; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
namespace PythonBinding.Tests.Utils |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// Helper class that stores the parameters passed when the IComponentCreator.CreateInstance method is called.
|
||||||
|
/// </summary>
|
||||||
|
public class CreatedInstance |
||||||
|
{ |
||||||
|
public CreatedInstance(Type type, ICollection arguments, string name, bool addToContainer) |
||||||
|
{ |
||||||
|
InstanceType = type; |
||||||
|
Arguments = arguments; |
||||||
|
Name = name; |
||||||
|
AddToContainer = addToContainer; |
||||||
|
} |
||||||
|
|
||||||
|
public Type InstanceType { get; set; } |
||||||
|
public ICollection Arguments { get; set; } |
||||||
|
public string Name { get; set; } |
||||||
|
public bool AddToContainer { get; set; } |
||||||
|
public object Object { get; set; } |
||||||
|
|
||||||
|
public override bool Equals(object obj) |
||||||
|
{ |
||||||
|
CreatedInstance rhs = obj as CreatedInstance; |
||||||
|
if (rhs != null) { |
||||||
|
return ToString() == rhs.ToString(); |
||||||
|
} |
||||||
|
return base.Equals(obj); |
||||||
|
} |
||||||
|
|
||||||
|
public override int GetHashCode() |
||||||
|
{ |
||||||
|
return InstanceType.GetHashCode(); |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() |
||||||
|
{ |
||||||
|
return "CreatedInstance [Type=" + InstanceType + ", Name=" + Name + ArgsToString() + "]"; |
||||||
|
} |
||||||
|
|
||||||
|
string ArgsToString() |
||||||
|
{ |
||||||
|
StringBuilder s = new StringBuilder(); |
||||||
|
s.Append("[Args="); |
||||||
|
|
||||||
|
bool firstArg = true; |
||||||
|
foreach (object o in Arguments) { |
||||||
|
if (!firstArg) { |
||||||
|
s.Append(", "); |
||||||
|
} |
||||||
|
s.Append(o); |
||||||
|
firstArg = false; |
||||||
|
} |
||||||
|
s.Append("]"); |
||||||
|
return s.ToString(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue