Browse Source

Refactored the set property value code out of the PythonComponentWalker class.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4548 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Matt Ward 16 years ago
parent
commit
2e9a82b24d
  1. 110
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonComponentWalker.cs
  2. 76
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs
  3. 10
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs

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

@ -124,7 +124,7 @@ namespace ICSharpCode.PythonBinding
return false; return false;
} }
SetPropertyValue(fieldExpression, node.Value); fieldExpression.SetPropertyValue(componentCreator, node.Value);
return false; return false;
} }
@ -148,7 +148,7 @@ namespace ICSharpCode.PythonBinding
return false; return false;
} }
SetPropertyValue(fieldExpression, node.Name.ToString()); fieldExpression.SetPropertyValue(componentCreator, node.Name.ToString());
return false; return false;
} }
@ -170,10 +170,7 @@ namespace ICSharpCode.PythonBinding
MemberExpression eventHandlerExpression = node.Right as MemberExpression; MemberExpression eventHandlerExpression = node.Right as MemberExpression;
string eventHandlerName = eventHandlerExpression.Name.ToString(); string eventHandlerName = eventHandlerExpression.Name.ToString();
IComponent currentComponent = this.component; IComponent currentComponent = fieldExpression.GetObject(componentCreator) as IComponent;
if (field.VariableName.Length > 0) {
currentComponent = GetComponent(field.VariableName);
}
EventDescriptor eventDescriptor = TypeDescriptor.GetEvents(currentComponent).Find(eventName, false); EventDescriptor eventDescriptor = TypeDescriptor.GetEvents(currentComponent).Find(eventName, false);
PropertyDescriptor propertyDescriptor = componentCreator.GetEventProperty(eventDescriptor); PropertyDescriptor propertyDescriptor = componentCreator.GetEventProperty(eventDescriptor);
@ -187,7 +184,7 @@ namespace ICSharpCode.PythonBinding
void WalkAssignment(BinaryExpression binaryExpression) void WalkAssignment(BinaryExpression binaryExpression)
{ {
object value = deserializer.Deserialize(binaryExpression); object value = deserializer.Deserialize(binaryExpression);
SetPropertyValue(fieldExpression.MemberName, value); fieldExpression.SetPropertyValue(componentCreator, value);
} }
/// <summary> /// <summary>
@ -198,7 +195,7 @@ namespace ICSharpCode.PythonBinding
MemberExpression rhsMemberExpression = rhs as MemberExpression; MemberExpression rhsMemberExpression = rhs as MemberExpression;
if (rhsMemberExpression != null) { if (rhsMemberExpression != null) {
object propertyValue = GetPropertyValueFromAssignmentRhs(rhsMemberExpression); object propertyValue = GetPropertyValueFromAssignmentRhs(rhsMemberExpression);
SetPropertyValue(fieldExpression, propertyValue); fieldExpression.SetPropertyValue(componentCreator, propertyValue);
} else { } else {
walkingAssignment = true; walkingAssignment = true;
BinaryExpression binaryExpression = rhs as BinaryExpression; BinaryExpression binaryExpression = rhs as BinaryExpression;
@ -217,73 +214,6 @@ namespace ICSharpCode.PythonBinding
return name == "initializecomponent" || name == "initializecomponents"; return name == "initializecomponent" || name == "initializecomponents";
} }
/// <summary>
/// Checks the field expression to see if it references an class instance variable (e.g. self._treeView1)
/// or a variable that is local to the InitializeComponent method (e.g. treeNode1.BackColor)
/// </summary>
bool SetPropertyValue(PythonControlFieldExpression fieldExpression, object propertyValue)
{
if (fieldExpression.IsSelfReference) {
return SetPropertyValue(fieldExpression.GetObject(GetCurrentComponent()), fieldExpression.MemberName, propertyValue);
}
return SetPropertyValue(componentCreator.GetInstance(fieldExpression.VariableName), fieldExpression.MemberName, propertyValue);
}
/// <summary>
/// Sets the value of a property on the current control.
/// </summary>
bool SetPropertyValue(string name, object propertyValue)
{
return SetPropertyValue(GetCurrentComponent(), name, propertyValue);
}
/// <summary>
/// Returns true if the current component has a property with the specified name.
/// </summary>
bool HasPropertyValue(string name)
{
return GetPropertyDescriptor(GetCurrentComponent(), name) != null;
}
PropertyDescriptor GetPropertyDescriptor(object component, string name)
{
return TypeDescriptor.GetProperties(component).Find(name, true);
}
/// <summary>
/// Sets the value of a property on the component.
/// </summary>
bool SetPropertyValue(object component, string name, object propertyValue)
{
PropertyDescriptor property = GetPropertyDescriptor(component, name);
if (property != null) {
propertyValue = ConvertPropertyValue(property, propertyValue);
property.SetValue(component, propertyValue);
return true;
}
return false;
}
/// <summary>
/// Converts the value to the property's type if required.
/// </summary>
static object ConvertPropertyValue(PropertyDescriptor propertyDescriptor, object propertyValue)
{
if (!propertyDescriptor.PropertyType.IsAssignableFrom(propertyValue.GetType())) {
return propertyDescriptor.Converter.ConvertFrom(propertyValue);
}
return propertyValue;
}
/// <summary>
/// Looks for the component with the specified name in the objects that have been
/// created whilst processing the InitializeComponent method.
/// </summary>
IComponent GetComponent(string name)
{
return componentCreator.GetComponent(name);
}
/// <summary> /// <summary>
/// Adds a component to the list of created objects. /// Adds a component to the list of created objects.
/// </summary> /// </summary>
@ -295,14 +225,6 @@ namespace ICSharpCode.PythonBinding
componentCreator.Add(component, variableName); componentCreator.Add(component, variableName);
} }
} }
/// <summary>
/// Gets the current control being walked.
/// </summary>
object GetCurrentComponent()
{
return fieldExpression.GetObject(componentCreator);
}
/// <summary> /// <summary>
/// Gets the type for the control being walked. /// Gets the type for the control being walked.
@ -335,18 +257,18 @@ namespace ICSharpCode.PythonBinding
{ {
MemberExpression memberExpression = node.Target as MemberExpression; MemberExpression memberExpression = node.Target as MemberExpression;
if (memberExpression != null) { if (memberExpression != null) {
string name = GetInstanceName(fieldExpression); string name = fieldExpression.GetInstanceName(componentCreator);
object instance = CreateInstance(name, node); object instance = CreateInstance(name, node);
if (instance != null) { if (instance != null) {
if (!SetPropertyValue(fieldExpression, instance)) { if (!fieldExpression.SetPropertyValue(componentCreator, instance)) {
AddComponent(fieldExpression.MemberName, instance); AddComponent(fieldExpression.MemberName, instance);
} }
} else { } else {
object obj = deserializer.Deserialize(node); object obj = deserializer.Deserialize(node);
if (obj != null) { if (obj != null) {
SetPropertyValue(fieldExpression, obj); fieldExpression.SetPropertyValue(componentCreator, obj);
} else if (IsResource(memberExpression)) { } else if (IsResource(memberExpression)) {
SetPropertyValue(fieldExpression.MemberName, GetResource(node)); fieldExpression.SetPropertyValue(componentCreator, GetResource(node));
} else { } else {
throw new PythonComponentWalkerException(String.Format("Could not find type '{0}'.", PythonControlFieldExpression.GetMemberName(memberExpression))); throw new PythonComponentWalkerException(String.Format("Could not find type '{0}'.", PythonControlFieldExpression.GetMemberName(memberExpression)));
} }
@ -354,20 +276,6 @@ namespace ICSharpCode.PythonBinding
} }
} }
/// <summary>
/// Gets the name of the instance. If the name matches a property of the current component being created
/// then this method returns null.
/// </summary>
string GetInstanceName(PythonControlFieldExpression fieldExpression)
{
if (fieldExpression.IsSelfReference) {
if (!HasPropertyValue(fieldExpression.MemberName)) {
return PythonControlFieldExpression.GetVariableName(fieldExpression.MemberName);
}
}
return null;
}
/// <summary> /// <summary>
/// Walks a method call. Typical method calls are: /// Walks a method call. Typical method calls are:
/// ///

76
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonControlFieldExpression.cs

@ -176,7 +176,33 @@ namespace ICSharpCode.PythonBinding
} }
return names.ToArray(); return names.ToArray();
} }
/// <summary>
/// Returns true if the variable has a property with the specified name.
/// </summary>
public bool HasPropertyValue(IComponentCreator componentCreator, string name)
{
object component = GetObject(componentCreator);
if (component != null) {
return TypeDescriptor.GetProperties(component).Find(name, true) != null;
}
return false;
}
/// <summary>
/// Gets the name of the instance. If the name matches a property of the current component being created
/// then this method returns null.
/// </summary>
public string GetInstanceName(IComponentCreator componentCreator)
{
if (IsSelfReference) {
if (!HasPropertyValue(componentCreator, memberName)) {
return variableName;
}
}
return null;
}
/// <summary> /// <summary>
/// Gets the object that the field expression variable refers to. /// Gets the object that the field expression variable refers to.
/// </summary> /// </summary>
@ -195,7 +221,7 @@ namespace ICSharpCode.PythonBinding
/// <remarks>The object parameter must be equivalent to the object referred to /// <remarks>The object parameter must be equivalent to the object referred to
/// by the variable name in this PythonControlFieldExpression /// by the variable name in this PythonControlFieldExpression
/// (e.g. button1 in self._button1.FlatAppearance.BorderSize).</remarks> /// (e.g. button1 in self._button1.FlatAppearance.BorderSize).</remarks>
public object GetObject(object component) public object GetObjectForMemberName(object component)
{ {
string[] members = fullMemberName.Split('.'); string[] members = fullMemberName.Split('.');
int startIndex = GetMembersStartIndex(members); int startIndex = GetMembersStartIndex(members);
@ -209,8 +235,27 @@ namespace ICSharpCode.PythonBinding
currentComponent = propertyDescriptor.GetValue(currentComponent); currentComponent = propertyDescriptor.GetValue(currentComponent);
} }
return currentComponent; return currentComponent;
} }
/// <summary>
/// Sets the property value that is referenced by this field expression.
/// </summary>
/// <remarks>
/// Checks the field expression to see if it references an class instance variable (e.g. self._treeView1)
/// or a variable that is local to the InitializeComponent method (e.g. treeNode1.BackColor)
/// </remarks>
public bool SetPropertyValue(IComponentCreator componentCreator, object propertyValue)
{
object component = null;
if (IsSelfReference) {
component = GetObject(componentCreator);
component = GetObjectForMemberName(component);
} else {
component = componentCreator.GetInstance(variableName);
}
return SetPropertyValue(component, memberName, propertyValue);
}
/// <summary> /// <summary>
/// Gets the member object that matches the field member. /// Gets the member object that matches the field member.
/// ///
@ -340,5 +385,30 @@ namespace ICSharpCode.PythonBinding
} }
return 1; return 1;
} }
/// <summary>
/// Sets the value of a property on the component.
/// </summary>
static bool SetPropertyValue(object component, string name, object propertyValue)
{
PropertyDescriptor property = TypeDescriptor.GetProperties(component).Find(name, true);
if (property != null) {
propertyValue = ConvertPropertyValue(property, propertyValue);
property.SetValue(component, propertyValue);
return true;
}
return false;
}
/// <summary>
/// Converts the value to the property's type if required.
/// </summary>
static object ConvertPropertyValue(PropertyDescriptor propertyDescriptor, object propertyValue)
{
if (!propertyDescriptor.PropertyType.IsAssignableFrom(propertyValue.GetType())) {
return propertyDescriptor.Converter.ConvertFrom(propertyValue);
}
return propertyValue;
}
} }
} }

10
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/PythonControlFieldExpressionTests.cs

@ -212,7 +212,7 @@ namespace PythonBinding.Tests.Designer
AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._button1.Size = System.Drawing.Size(10, 10)"); AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._button1.Size = System.Drawing.Size(10, 10)");
PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression);
Assert.AreEqual(button, field.GetObject(button)); Assert.AreEqual(button, field.GetObjectForMemberName(button));
} }
} }
@ -223,7 +223,7 @@ namespace PythonBinding.Tests.Designer
AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("_button1.Size = System.Drawing.Size(10, 10)"); AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("_button1.Size = System.Drawing.Size(10, 10)");
PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression);
Assert.AreEqual(button, field.GetObject(button)); Assert.AreEqual(button, field.GetObjectForMemberName(button));
} }
} }
@ -234,7 +234,7 @@ namespace PythonBinding.Tests.Designer
AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._button1.FlatAppearance.BorderSize = 3"); AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._button1.FlatAppearance.BorderSize = 3");
PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression);
Assert.AreEqual(button.FlatAppearance, field.GetObject(button)); Assert.AreEqual(button.FlatAppearance, field.GetObjectForMemberName(button));
} }
} }
@ -245,7 +245,7 @@ namespace PythonBinding.Tests.Designer
AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("_button1.FlatAppearance.BorderSize = 3"); AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("_button1.FlatAppearance.BorderSize = 3");
PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression);
Assert.AreEqual(button.FlatAppearance, field.GetObject(button)); Assert.AreEqual(button.FlatAppearance, field.GetObjectForMemberName(button));
} }
} }
@ -256,7 +256,7 @@ namespace PythonBinding.Tests.Designer
AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._button1.InvalidProperty.BorderSize = 3"); AssignmentStatement statement = PythonParserHelper.GetAssignmentStatement("self._button1.InvalidProperty.BorderSize = 3");
PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression); PythonControlFieldExpression field = PythonControlFieldExpression.Create(statement.Left[0] as MemberExpression);
Assert.IsNull(field.GetObject(button)); Assert.IsNull(field.GetObjectForMemberName(button));
} }
} }

Loading…
Cancel
Save