Browse Source

Fix Python forms designer.

The Python forms designer was walking code after the
InitializeComponents and if this code tried to create an
instance of the form it would fail. Now the forms
designer only walks the code inside the InitializeComponents.
pull/61/merge
Matt Ward 12 years ago
parent
commit
41e0c5bea5
  1. 27
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs
  2. 62
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/AssignmentAfterFormClassTests.cs
  3. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

27
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs

@ -31,6 +31,7 @@ namespace ICSharpCode.PythonBinding @@ -31,6 +31,7 @@ namespace ICSharpCode.PythonBinding
string componentName = String.Empty;
PythonCodeDeserializer deserializer;
ClassDefinition classDefinition;
bool walkingInitializeComponentMethod;
public PythonComponentWalker(IComponentCreator componentCreator)
{
@ -42,13 +43,13 @@ namespace ICSharpCode.PythonBinding @@ -42,13 +43,13 @@ namespace ICSharpCode.PythonBinding
/// Creates a control either a UserControl or Form from the python code.
/// </summary>
public IComponent CreateComponent(string pythonCode)
{
{
PythonParser parser = new PythonParser();
PythonAst ast = parser.CreateAst(@"Control.py", new StringTextBuffer(pythonCode));
ast.Walk(this);
// Did we find the InitializeComponent method?
if (!FoundInitializeComponentMethod) {
if (component == null) {
throw new PythonComponentWalkerException("Unable to find InitializeComponents method.");
}
return component;
@ -88,14 +89,16 @@ namespace ICSharpCode.PythonBinding @@ -88,14 +89,16 @@ namespace ICSharpCode.PythonBinding
if (reader != null) {
reader.Dispose();
}
walkingInitializeComponentMethod = true;
node.Body.Walk(this);
walkingInitializeComponentMethod = false;
}
return false;
}
public override bool Walk(AssignmentStatement node)
{
if (!FoundInitializeComponentMethod) {
{
if (!walkingInitializeComponentMethod) {
return false;
}
@ -120,7 +123,7 @@ namespace ICSharpCode.PythonBinding @@ -120,7 +123,7 @@ namespace ICSharpCode.PythonBinding
public override bool Walk(ConstantExpression node)
{
if (!FoundInitializeComponentMethod) {
if (!walkingInitializeComponentMethod) {
return false;
}
@ -129,8 +132,8 @@ namespace ICSharpCode.PythonBinding @@ -129,8 +132,8 @@ namespace ICSharpCode.PythonBinding
}
public override bool Walk(CallExpression node)
{
if (!FoundInitializeComponentMethod) {
{
if (!walkingInitializeComponentMethod) {
return false;
}
@ -144,7 +147,7 @@ namespace ICSharpCode.PythonBinding @@ -144,7 +147,7 @@ namespace ICSharpCode.PythonBinding
public override bool Walk(NameExpression node)
{
if (!FoundInitializeComponentMethod) {
if (!walkingInitializeComponentMethod) {
return false;
}
@ -159,7 +162,7 @@ namespace ICSharpCode.PythonBinding @@ -159,7 +162,7 @@ namespace ICSharpCode.PythonBinding
/// </summary>
public override bool Walk(AugmentedAssignStatement node)
{
if (!FoundInitializeComponentMethod) {
if (!walkingInitializeComponentMethod) {
return false;
}
@ -176,7 +179,7 @@ namespace ICSharpCode.PythonBinding @@ -176,7 +179,7 @@ namespace ICSharpCode.PythonBinding
PropertyDescriptor propertyDescriptor = componentCreator.GetEventProperty(eventDescriptor);
propertyDescriptor.SetValue(currentComponent, eventHandlerName);
return false;
}
}
/// <summary>
/// Walks the binary expression which is the right hand side of an assignment statement.
@ -357,10 +360,6 @@ namespace ICSharpCode.PythonBinding @@ -357,10 +360,6 @@ namespace ICSharpCode.PythonBinding
return null;
}
bool FoundInitializeComponentMethod {
get { return component != null; }
}
/// <summary>
/// Returns true if the expression is of the form:
///

62
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/AssignmentAfterFormClassTests.cs

@ -0,0 +1,62 @@ @@ -0,0 +1,62 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Resources;
using ICSharpCode.Core;
using NUnit.Framework;
namespace PythonBinding.Tests.Designer
{
/// <summary>
/// Tests that only the InitializeComponents method is processed
/// when walking the AST.
/// </summary>
[TestFixture]
public class AssignmentAfterFormClassTests : LoadFormTestFixtureBase
{
public override void BeforeSetUpFixture()
{
var rm = new ResourceManager("PythonBinding.Tests.Strings", GetType().Assembly);
ResourceService.RegisterNeutralStrings(rm);
}
public override string PythonCode {
get {
return
"import clr\r\n" +
"clr.AddReference('System.Windows.Forms')\r\n" +
"clr.AddReference('System.Drawing')\r\n" +
"\r\n" +
"import System.Drawing\r\n" +
"import System.Windows.Forms\r\n" +
"\r\n" +
"from System.Drawing import *\r\n" +
"from System.Windows.Forms import *\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.SuspendLayout()\r\n" +
" # \r\n" +
" # MainForm\r\n" +
" # \r\n" +
" self.ClientSize = System.Drawing.Size(300, 400)\r\n" +
" self.Name = \"MainForm\"\r\n" +
" self.ResumeLayout(False)\r\n" +
"\r\n" +
"test = MainForm()\r\n" +
"Application.Run(test)\r\n" +
"\r\n";
}
}
[Test]
public void MainFormName()
{
Assert.AreEqual("MainForm", Form.Name);
}
}
}

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

@ -183,6 +183,7 @@ @@ -183,6 +183,7 @@
<Compile Include="Converter\VBStringConcatTestFixture.cs" />
<Compile Include="Converter\WhileLoopConversionTestFixture.cs" />
<Compile Include="Converter\XmlDocCommentConversionTestFixture.cs" />
<Compile Include="Designer\AssignmentAfterFormClassTests.cs" />
<Compile Include="Designer\CallBeginInitOnLoadTestFixture.cs" />
<Compile Include="Designer\ConvertCustomClassUsingTypeConverterTestFixture.cs" />
<Compile Include="Designer\CursorTypeResolutionTestFixture.cs" />

Loading…
Cancel
Save