diff options
Diffstat (limited to 'mcs/class/PresentationFramework')
5 files changed, 163 insertions, 72 deletions
diff --git a/mcs/class/PresentationFramework/ChangeLog b/mcs/class/PresentationFramework/ChangeLog index 32fee625ed5..645b2b023df 100644 --- a/mcs/class/PresentationFramework/ChangeLog +++ b/mcs/class/PresentationFramework/ChangeLog @@ -1,3 +1,15 @@ +2005-07-05 Iain McCoy <iain@mccoy.id.au> + + * Mono.Windows.Serialization/XamlParser.cs, + Mono.Windows.Serialization/XamlWriter.cs, + Mono.Windows.Serialization/CodeWriter.cs: add support for delegate + properties and for events + * Mono.Windows.Serialization/XamlParser.cs, + Mono.Windows.Serialization/XamlWriter.cs, + Mono.Windows.Serialization/CodeWriter.cs, + Mono.Windows.Serialization/Mapper.cs: tighten up types so that Type + and PropertyInfo are passed instead of strings + 2005-07-03 Iain McCoy <iain@mccoy.id.au> * Mono.Windows.Serialization/XamlParser.cs: added support for Code diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs index 7e2db10bc28..7f52ea08a13 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs @@ -27,6 +27,7 @@ // using System; +using System.Reflection; using System.IO; using System.Collections; using System.CodeDom; @@ -53,9 +54,8 @@ namespace Mono.Windows.Serialization { // pushes: a CodeVariableReferenceExpression to the present // instance - public void CreateTopLevel(string parentName, string className) + public void CreateTopLevel(Type parent, string className) { - Type parent = Type.GetType(parentName); int endNamespaceName = className.LastIndexOf("."); string clrNamespace; if (endNamespaceName < 0) @@ -77,9 +77,8 @@ namespace Mono.Windows.Serialization { // bottom of stack holds CodeVariableReferenceExpression // pushes a reference to the new current type - public void CreateObject(string typeName) + public void CreateObject(Type type) { - Type type = Type.GetType(typeName); string varName = Char.ToLower(type.Name[0]) + type.Name.Substring(1); // make sure something sensible happens when class // names start with a lowercase letter @@ -109,37 +108,46 @@ namespace Mono.Windows.Serialization { // top of stack is a reference to an object // pushes a reference to the property - public void CreateProperty(string propertyName) + public void CreateProperty(PropertyInfo property) { CodePropertyReferenceExpression prop = new CodePropertyReferenceExpression( (CodeExpression)objects[objects.Count - 1], - propertyName); + property.Name); objects.Add(prop); } // top of stack is a reference to an object + // pushes a reference to the event + public void CreateEvent(EventInfo evt) + { + CodeEventReferenceExpression expr = new CodeEventReferenceExpression( + (CodeExpression)objects[objects.Count - 1], + evt.Name); + objects.Add(expr); + } + + // top of stack is a reference to an object // pushes the name of the instance to attach to, the name of // the property, and a reference to an object - public void CreateAttachedProperty(string attachedTo, string propertyName, string typeName) + public void CreateAttachedProperty(Type attachedTo, string propertyName, Type propertyType) { - Type t = Type.GetType(typeName); - Type typeAttachedTo = Type.GetType(attachedTo); - - string name = "temp"; - if (tempIndex != 0) - name += tempIndex; - CodeVariableDeclarationStatement decl = new CodeVariableDeclarationStatement(t, name); + string varName = "temp"; + if (tempIndex != 0) { + varName += tempIndex; + tempIndex += 1; + } + CodeVariableDeclarationStatement decl = new CodeVariableDeclarationStatement(propertyType, varName); constructor.Statements.Add(decl); CodeMethodInvokeExpression call = new CodeMethodInvokeExpression( - new CodeTypeReferenceExpression(typeAttachedTo), + new CodeTypeReferenceExpression(attachedTo), "Set" + propertyName, (CodeExpression)objects[objects.Count - 1], - new CodeVariableReferenceExpression(name)); + new CodeVariableReferenceExpression(varName)); objects.Add(call); - objects.Add(new CodeVariableReferenceExpression(name)); + objects.Add(new CodeVariableReferenceExpression(varName)); } // pops 2 items: the name of the property, and the object to attach to @@ -162,20 +170,47 @@ namespace Mono.Windows.Serialization { constructor.Statements.Add(call); } + // top of stack is reference to an event + public void CreateEventDelegate(string functionName, Type eventDelegateType) + { + CodeExpression expr = new CodeObjectCreateExpression( + eventDelegateType, + new CodeMethodReferenceExpression( + new CodeThisReferenceExpression(), + functionName)); + CodeAttachEventStatement attach = new CodeAttachEventStatement( + (CodeEventReferenceExpression)objects[objects.Count - 1], + expr); + constructor.Statements.Add(attach); + + } // top of stack is reference to a property - public void CreatePropertyText(string text, string converter) + public void CreatePropertyDelegate(string functionName, Type propertyType) { - CreateAttachedPropertyText(text, converter); + CodeExpression expr = new CodeObjectCreateExpression( + propertyType, + new CodeMethodReferenceExpression( + new CodeThisReferenceExpression(), + functionName)); + CodeAssignStatement assignment = new CodeAssignStatement( + (CodeExpression)objects[objects.Count - 1], + expr); + constructor.Statements.Add(assignment); } - public void CreateAttachedPropertyText(string text, string converter) + // top of stack is reference to a property + public void CreatePropertyText(string text, Type propertyType, Type converterType) + { + CreateAttachedPropertyText(text, propertyType, converterType); + } + // top of stack is reference to an attached property + public void CreateAttachedPropertyText(string text, Type propertyType, Type converterType) { CodeExpression expr = new CodePrimitiveExpression(text); - if (converter != null) { - Type t = Type.GetType(converter); + if (converterType != null) { expr = new CodeCastExpression( - new CodeTypeReference(typeof(int)), + new CodeTypeReference(propertyType), new CodeMethodInvokeExpression( - new CodeObjectCreateExpression(t), + new CodeObjectCreateExpression(converterType), "ConvertFromString", expr)); } @@ -195,6 +230,11 @@ namespace Mono.Windows.Serialization { { objects.RemoveAt(objects.Count - 1); } + + public void EndEvent() + { + objects.RemoveAt(objects.Count - 1); + } public void Finish() { diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/Mapping.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/Mapping.cs index 07d9d6eb02b..256fafd13b0 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/Mapping.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/Mapping.cs @@ -42,7 +42,7 @@ namespace Mono.Windows.Serialization { mappings[mapping.XmlNamespace] = mapping; } - public string Resolve(string clrNamespace, string classname) + public Type Resolve(string clrNamespace, string classname) { return ((Mapping)mappings[clrNamespace]).Resolve(classname); } @@ -116,14 +116,14 @@ namespace Mono.Windows.Serialization { get { return xmlNamespace; } } - public string Resolve(string className) + public Type Resolve(string className) { Assembly assembly = Assembly.Load(assemblyName); Type type = assembly.GetType(clrNamespace + "." + className); if (type == null) { throw new MappingException(className, XmlNamespace); } else { - return type.AssemblyQualifiedName; + return type; } } } diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs index 6939bcc8236..a1a9dd62962 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs @@ -140,6 +140,8 @@ namespace Mono.Windows.Serialization { // the given type bool isNameOfAncestorClass(string name, Type t) { + if (name == "object") + return true; while (t.BaseType != null) { if (t.Name == name) return true; @@ -162,14 +164,16 @@ namespace Mono.Windows.Serialization { writer.CreateElementText(reader.Value); } else if (currentState.type == CurrentType.AttachedProperty) { DependencyProperty dp = (DependencyProperty)currentState.obj; - writer.CreateAttachedPropertyText(reader.Value, getTypeConverter(dp.PropertyType)); + writer.CreateAttachedPropertyText(reader.Value, dp.PropertyType, + getTypeConverter(dp.PropertyType)); } else { PropertyInfo prop = (PropertyInfo)currentState.obj; - writer.CreatePropertyText(reader.Value, getTypeConverter(prop.PropertyType)); + writer.CreatePropertyText(reader.Value, prop.PropertyType, + getTypeConverter(prop.PropertyType)); } } - string getTypeConverter(Type fromType) + Type getTypeConverter(Type fromType) { // TODO: this business setting assembly is frankly // grotesque. It should just be something along the @@ -188,9 +192,8 @@ namespace Mono.Windows.Serialization { return null; string converterName = "System.ComponentModel." + fromType.Name + "Converter,System.dll"; Type converter = assembly.GetType(converterName); - return converter.AssemblyQualifiedName; - // TODO: catch NullReferenceException and do something - // cool + return converter; + // TODO: check if converter == null and do something cool } @@ -199,6 +202,7 @@ namespace Mono.Windows.Serialization { // preconditions: currentState.Type == Object Type currentType = (Type)currentState.obj; PropertyInfo prop = currentType.GetProperty(propertyName); + if (prop == null) { Console.WriteLine("Property " + propertyName + " not found on " + currentType.Name); return; @@ -210,7 +214,7 @@ namespace Mono.Windows.Serialization { currentState.type = CurrentType.Property; currentState.obj = prop; - writer.CreateProperty(propertyName); + writer.CreateProperty(prop); if (reader.HasAttributes) { Console.WriteLine("Property node should not have attributes"); @@ -247,24 +251,23 @@ namespace Mono.Windows.Serialization { currentState.obj = dp; currentState.type = CurrentType.AttachedProperty; - writer.CreateAttachedProperty(typeAttachedTo.AssemblyQualifiedName, - propertyName, - dp.PropertyType.AssemblyQualifiedName); + writer.CreateAttachedProperty(typeAttachedTo, propertyName, dp.PropertyType); } void parseObjectElement() { - string parentName, objectName = null; + Type parent; + string objectName = null; bool isEmpty = reader.IsEmptyElement; - parentName = mapper.Resolve(reader.NamespaceURI, reader.Name); + parent = mapper.Resolve(reader.NamespaceURI, reader.Name); objectName = reader.GetAttribute("Class", XAML_NAMESPACE); - if (Type.GetType(parentName).GetInterface("System.Windows.Serialization.IAddChild") == null) + if (parent.GetInterface("System.Windows.Serialization.IAddChild") == null) {} //TODO: throw exception if (currentState == null) { - createTopLevel(parentName, objectName); + createTopLevel(parent.AssemblyQualifiedName, objectName); } else { - addChild(parentName); + addChild(parent); } if (reader.MoveToFirstAttribute()) { @@ -281,28 +284,70 @@ namespace Mono.Windows.Serialization { } - if (isEmpty) + if (isEmpty) { writer.EndObject(); + pop(); + } + } + + void createTopLevel(string parentName, string objectName) + { + Type t = Type.GetType(parentName); + currentState = new ParserState(); + currentState.type = CurrentType.Object; + currentState.obj = t; + if (objectName == null) { + objectName = "derived" + t.Name; + } + writer.CreateTopLevel(t, objectName); } + + void addChild(Type type) + { + writer.CreateObject(type); + oldStates.Add(currentState); + currentState = new ParserState(); + currentState.type = CurrentType.Object; + currentState.obj = type; + } + void parseLocalPropertyAttribute() { string propertyName = reader.LocalName; Type currentType = (Type)currentState.obj; PropertyInfo prop = currentType.GetProperty(propertyName); + if (parsedAsEventProperty(currentType, propertyName)) + return; if (prop == null) { Console.WriteLine("Property " + propertyName + " not found on " + currentType.Name); return; // TODO: throw exception } - writer.CreateProperty(propertyName); - writer.CreatePropertyText(reader.Value, getTypeConverter(prop.PropertyType)); + writer.CreateProperty(prop); - parseEndElement(); + if (prop.PropertyType.IsSubclassOf(typeof(Delegate))) + writer.CreatePropertyDelegate(reader.Value, prop.PropertyType); + else + writer.CreatePropertyText(reader.Value, prop.PropertyType, getTypeConverter(prop.PropertyType)); + + writer.EndProperty(); + } + + bool parsedAsEventProperty(Type currentType, string eventName) + { + EventInfo evt = currentType.GetEvent(eventName); + if (evt == null) + return false; + writer.CreateEvent(evt); + writer.CreateEventDelegate(reader.Value, evt.EventHandlerType); + writer.EndEvent(); + return true; } + void parseContextPropertyAttribute() { throw new NotImplementedException("parseContextPropertyAttribute"); @@ -319,7 +364,11 @@ namespace Mono.Windows.Serialization { else if (currentState.type == CurrentType.AttachedProperty) writer.EndAttachedProperty(); + pop(); + } + void pop() + { if (oldStates.Count == 0) { currentState = null; writer.Finish(); @@ -328,27 +377,8 @@ namespace Mono.Windows.Serialization { int lastIndex = oldStates.Count - 1; currentState = (ParserState)oldStates[lastIndex]; oldStates.RemoveAt(lastIndex); - } - void createTopLevel(string parentName, string objectName) - { - Type t = Type.GetType(parentName); - currentState = new ParserState(); - currentState.type = CurrentType.Object; - currentState.obj = t; - if (objectName == null) { - objectName = "derived" + t.Name; - } - writer.CreateTopLevel(parentName, objectName); } - void addChild(string className) - { - writer.CreateObject(className); - oldStates.Add(currentState); - currentState = new ParserState(); - currentState.type = CurrentType.Object; - currentState.obj = Type.GetType(className); - } } } diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs index a4c956a4e8f..9efbc9b5011 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs @@ -26,20 +26,29 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Reflection; + namespace Mono.Windows.Serialization { public interface XamlWriter { - void CreateTopLevel(string parentName, string className); + void CreateTopLevel(Type parent, string className); - void CreateObject(string typeName); + void CreateObject(Type type); void CreateElementText(string text); void EndObject(); - void CreateProperty(string propertyName); - void CreatePropertyText(string text, string converter); + void CreateProperty(PropertyInfo property); + void CreatePropertyText(string text, Type propertyType, Type converterType); + void CreatePropertyDelegate(string functionName, Type propertyType); void EndProperty(); - - void CreateAttachedProperty(string attachedTo, string propertyName, string typeName); - void CreateAttachedPropertyText(string text, string converter); + + + void CreateEvent(EventInfo evt); + void CreateEventDelegate(string functionName, Type eventDelegateType); + void EndEvent(); + + void CreateAttachedProperty(Type attachedTo, string propertyName, Type propertyType); + void CreateAttachedPropertyText(string text, Type propertyType, Type converterType); void EndAttachedProperty(); void CreateCode(string code); |