diff options
author | Iain McCoy <iainmc@mono-cvs.ximian.com> | 2005-07-14 06:35:58 +0400 |
---|---|---|
committer | Iain McCoy <iainmc@mono-cvs.ximian.com> | 2005-07-14 06:35:58 +0400 |
commit | 532204c4337157aaf6b8bf97aee158e3e84db1d4 (patch) | |
tree | f059c8c907d0c3b450b393d71b96c4a0cd8e8c29 /mcs | |
parent | e149cbf0ecc932645c6e1dd30c7660513822b624 (diff) | |
parent | 6f907686f05ee683c25a97da9692321fb0761178 (diff) |
2005-07-14 Iain McCoy <iain@mccoy.id.au>
* demo/test.xaml: added first test of complex objects as property values
* demo/TestVocab/ConsoleReader.cs,
demo/TestVocab/ConsoleVars.cs: more functionality that will provide
uses for more complicated xaml code.
* xamlc.cs: much more useful error reporting.
* demo/TestVocab/ConsoleWriter.cs,
demo/TestVocab/ConsoleValue.cs,
demo/Makefile: Added ConsoleValue class to allow testing of more
complicated property scenarios
* demo/TestVocab/ConsoleVars.cs,
demo/TestVocab/ConsoleReader.cs: classes to put in more complicated
test
* Mono.Windows.Serialization/XamlParser.cs,
Mono.Windows.Serialization/XamlWriter.cs,
Mono.Windows.Serialization/CodeWriter.cs: Initial support for
creating complex objects as values of properties
* Mono.Windows.Serialization/XamlParser.cs: fixed bug in the code
detecting that the file's contents must be finished, where it forbade
whitespace after the XAML code
svn path=/trunk/mcs/; revision=47291
Diffstat (limited to 'mcs')
-rw-r--r-- | mcs/class/PresentationFramework/ChangeLog | 13 | ||||
-rw-r--r-- | mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs | 67 | ||||
-rw-r--r-- | mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs | 9 | ||||
-rw-r--r-- | mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs | 46 | ||||
-rw-r--r-- | mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs | 2 | ||||
-rw-r--r-- | mcs/tools/xamlc/ChangeLog | 22 | ||||
-rw-r--r-- | mcs/tools/xamlc/demo/Makefile | 2 | ||||
-rw-r--r-- | mcs/tools/xamlc/demo/TestVocab/ConsoleApp.cs | 3 | ||||
-rw-r--r-- | mcs/tools/xamlc/demo/TestVocab/ConsoleReader.cs | 24 | ||||
-rw-r--r-- | mcs/tools/xamlc/demo/TestVocab/ConsoleValue.cs | 75 | ||||
-rw-r--r-- | mcs/tools/xamlc/demo/TestVocab/ConsoleVars.cs | 13 | ||||
-rw-r--r-- | mcs/tools/xamlc/demo/TestVocab/ConsoleWriter.cs | 6 | ||||
-rw-r--r-- | mcs/tools/xamlc/demo/test.xaml | 14 | ||||
-rw-r--r-- | mcs/tools/xamlc/xamlc.cs | 12 |
14 files changed, 291 insertions, 17 deletions
diff --git a/mcs/class/PresentationFramework/ChangeLog b/mcs/class/PresentationFramework/ChangeLog index f456ff7d706..b439335ffe7 100644 --- a/mcs/class/PresentationFramework/ChangeLog +++ b/mcs/class/PresentationFramework/ChangeLog @@ -1,3 +1,16 @@ +2005-07-14 Iain McCoy <iain@mccoy.id.au> + + * Mono.Windows.Serialization/XamlParser.cs, + Mono.Windows.Serialization/XamlWriter.cs, + Mono.Windows.Serialization/CodeWriter.cs: Initial support for + creating complex objects as values of properties + +2005-07-13 Iain McCoy <iain@mccoy.id.au> + + * Mono.Windows.Serialization/XamlParser.cs: fixed bug in the code + detecting that the file's contents must be finished, where it forbade + whitespace after the XAML code + 2005-07-11 Iain McCoy <iain@mccoy.id.au> * Makefile, diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs index 5a39087f192..204e2cc94fe 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/CodeWriter.cs @@ -234,6 +234,7 @@ namespace Mono.Windows.Serialization { "GetConverter"), new CodeTypeOfExpression(propertyType)); } + // top of stack is reference to a property public void CreatePropertyText(string text, Type propertyType) { @@ -257,6 +258,72 @@ namespace Mono.Windows.Serialization { constructor.Statements.Add(assignment); } + + public void CreatePropertyObject(Type type, string varName) + { + bool isDefaultName; + if (varName == null) { + isDefaultName = true; + varName = Char.ToLower(type.Name[0]) + type.Name.Substring(1); + // make sure something sensible happens when class + // names start with a lowercase letter + if (varName == type.Name) + varName = "_" + varName; + } else { + isDefaultName = false; + } + + if (!nameClashes.ContainsKey(varName)) + nameClashes[varName] = 0; + else { + nameClashes[varName] = 1 + (int)nameClashes[varName]; + varName += (int)nameClashes[varName]; + } + + + if (isDefaultName) { + CodeVariableDeclarationStatement declaration = + new CodeVariableDeclarationStatement(type, + varName, + new CodeObjectCreateExpression(type)); + constructor.Statements.Add(declaration); + } else { + CodeMemberField declaration = new CodeMemberField(type, varName); + declaration.InitExpression = new CodeObjectCreateExpression(type); + this.type.Members.Add(declaration); + } + CodeVariableReferenceExpression varRef = new CodeVariableReferenceExpression(varName); + + objects.Add(type); + objects.Add(varRef); + + } + + public void EndPropertyObject(Type sourceType) + { + CodeExpression varRef = (CodeExpression)objects[objects.Count - 1]; + objects.RemoveAt(objects.Count - 1); + Type destType = (Type)objects[objects.Count - 1]; + objects.RemoveAt(objects.Count - 1); + + + CodeExpression expr; + if (destType == sourceType) + expr = varRef; + else + expr = new CodeCastExpression( + new CodeTypeReference(destType), + new CodeMethodInvokeExpression( + fetchConverter(sourceType), + "ConvertTo", + varRef, + new CodeTypeOfExpression(destType))); + CodeAssignStatement assignment = new CodeAssignStatement( + (CodeExpression)objects[objects.Count - 1], + expr); + constructor.Statements.Add(assignment); + + } public void EndObject() { diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs index e4a13f8a56f..f024812150b 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs @@ -103,6 +103,15 @@ namespace Mono.Windows.Serialization { p.SetValue(o, text, null); } + public void CreatePropertyObject(Type type, string name) + { + throw new NotImplementedException(); + } + public void EndPropertyObject(Type sourceType) + { + throw new NotImplementedException(); + } + // top of stack is reference to an attached property public void CreateDependencyPropertyText(string text, Type propertyType) { diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs index 39bdcf45349..10524cfdcb2 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlParser.cs @@ -76,7 +76,7 @@ namespace Mono.Windows.Serialization { public void Parse() { while (reader.Read()) { - if (begun && currentState == null) + if (begun && currentState == null && reader.NodeType != XmlNodeType.Whitespace) throw new Exception("Too far: " + reader.NodeType + ", " + reader.Name); if (currentState != null && currentState.type == CurrentType.Code) { @@ -103,7 +103,8 @@ namespace Mono.Windows.Serialization { parseText(); break; case XmlNodeType.Whitespace: - // skip whitespace + case XmlNodeType.Comment: + // skip whitespace and comments break; default: Console.Out.WriteLine("Unknown element type " + reader.NodeType); @@ -244,7 +245,13 @@ namespace Mono.Windows.Serialization { string name = reader.GetAttribute("Name", XAML_NAMESPACE); if (name == null) name = reader.GetAttribute("Name", reader.NamespaceURI); - addChild(parent, name); + + if (currentState.type == CurrentType.Object) + addChild(parent, name); + else if (currentState.type == CurrentType.Property) + addPropertyChild(parent, name); + else + throw new NotImplementedException(); } if (reader.MoveToFirstAttribute()) { @@ -270,10 +277,11 @@ namespace Mono.Windows.Serialization { void createTopLevel(string parentName, string className) { Type t = Type.GetType(parentName); + + writer.CreateTopLevel(t, className); currentState = new ParserState(); currentState.type = CurrentType.Object; currentState.obj = t; - writer.CreateTopLevel(t, className); } void addChild(Type type, string objectName) @@ -284,6 +292,18 @@ namespace Mono.Windows.Serialization { currentState.type = CurrentType.Object; currentState.obj = type; } + + void addPropertyChild(Type type, string objectName) + { +// writer.CreatePropertyObject(type, objectName); + writer.CreatePropertyObject(((PropertyInfo)currentState.obj).PropertyType, objectName); + + oldStates.Add(currentState); + currentState = new ParserState(); + currentState.type = CurrentType.Object; + currentState.obj = type; + } + void parseLocalPropertyAttribute() @@ -367,14 +387,22 @@ namespace Mono.Windows.Serialization { void parseEndElement() { - if (currentState.type == CurrentType.Code) + if (currentState.type == CurrentType.Code) { writer.CreateCode((string)currentState.obj); - else if (currentState.type == CurrentType.Object) - writer.EndObject(); - else if (currentState.type == CurrentType.Property) + } else if (currentState.type == CurrentType.Object) { + ParserState prev = null; + if (oldStates.Count > 1) + prev = (ParserState)oldStates[oldStates.Count - 1]; + + if (prev != null && prev.type == CurrentType.Property) + writer.EndPropertyObject((Type)currentState.obj); + else + writer.EndObject(); + } else if (currentState.type == CurrentType.Property) { writer.EndProperty(); - else if (currentState.type == CurrentType.DependencyProperty) + } else if (currentState.type == CurrentType.DependencyProperty) { writer.EndDependencyProperty(); + } pop(); } diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs index ba760e0b3de..5de3c224985 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/XamlWriter.cs @@ -40,6 +40,8 @@ namespace Mono.Windows.Serialization { void CreateProperty(PropertyInfo property); void CreatePropertyText(string text, Type propertyType); void CreatePropertyDelegate(string functionName, Type propertyType); + void CreatePropertyObject(Type destType, string name); + void EndPropertyObject(Type sourceType); void EndProperty(); diff --git a/mcs/tools/xamlc/ChangeLog b/mcs/tools/xamlc/ChangeLog index 365f5a6da92..c339007d811 100644 --- a/mcs/tools/xamlc/ChangeLog +++ b/mcs/tools/xamlc/ChangeLog @@ -1,3 +1,25 @@ +2005-07-14 Iain McCoy <iain@mccoy.id.au> + + * demo/test.xaml: added first test of complex objects as property values + + +2005-07-13 Iain McCoy <iain@mccoy.id.au> + + * demo/TestVocab/ConsoleReader.cs, + demo/TestVocab/ConsoleVars.cs: more functionality that will provide + uses for more complicated xaml code. + * xamlc.cs: much more useful error reporting. + +2005-07-08 Iain McCoy <iain@mccoy.id.au> + + * demo/TestVocab/ConsoleWriter.cs, + demo/TestVocab/ConsoleValue.cs, + demo/Makefile: Added ConsoleValue class to allow testing of more + complicated property scenarios + * demo/TestVocab/ConsoleVars.cs, + demo/TestVocab/ConsoleReader.cs: classes to put in more complicated + test + 2005-07-08 Iain McCoy <iain@mccoy.id.au> * demo/runtimetest.xaml diff --git a/mcs/tools/xamlc/demo/Makefile b/mcs/tools/xamlc/demo/Makefile index 2d0591ced3d..89ac4bd7329 100644 --- a/mcs/tools/xamlc/demo/Makefile +++ b/mcs/tools/xamlc/demo/Makefile @@ -1,7 +1,7 @@ thisdir = tools/xaml/demo include ../../../build/rules.make -SOURCES=TestVocab/ConsoleApp.cs TestVocab/ConsoleWriter.cs TestVocab/IConsoleAction.cs +SOURCES=TestVocab/ConsoleApp.cs TestVocab/ConsoleWriter.cs TestVocab/ConsoleReader.cs TestVocab/IConsoleAction.cs TestVocab/ConsoleValue.cs TestVocab/ConsoleVars.cs run: make clean diff --git a/mcs/tools/xamlc/demo/TestVocab/ConsoleApp.cs b/mcs/tools/xamlc/demo/TestVocab/ConsoleApp.cs index 168b7d85c3e..62412218c2c 100644 --- a/mcs/tools/xamlc/demo/TestVocab/ConsoleApp.cs +++ b/mcs/tools/xamlc/demo/TestVocab/ConsoleApp.cs @@ -12,7 +12,8 @@ namespace Xaml.TestVocab.Console { public void AddText(string Text) { - actions.Add(new ConsoleWriter(Text)); + actions.Add(new ConsoleWriter( + new ConsoleValueString(Text))); } public void AddChild(object Value) diff --git a/mcs/tools/xamlc/demo/TestVocab/ConsoleReader.cs b/mcs/tools/xamlc/demo/TestVocab/ConsoleReader.cs new file mode 100644 index 00000000000..89da77e616d --- /dev/null +++ b/mcs/tools/xamlc/demo/TestVocab/ConsoleReader.cs @@ -0,0 +1,24 @@ +using System.Windows; + +namespace Xaml.TestVocab.Console { + public class ConsoleReader : DependencyObject, IConsoleAction { + private string variable; + private ConsoleWriter prompt; + + public string Variable { + get { return variable; } + set { variable = value; } + } + + public ConsoleWriter Prompt { + get { return prompt; } + set { prompt = value; } + } + + public void Run() { + prompt.Run(); + string s = System.Console.ReadLine(); + ConsoleVars.Set(variable, s); + } + } +} diff --git a/mcs/tools/xamlc/demo/TestVocab/ConsoleValue.cs b/mcs/tools/xamlc/demo/TestVocab/ConsoleValue.cs new file mode 100644 index 00000000000..18bedb7a029 --- /dev/null +++ b/mcs/tools/xamlc/demo/TestVocab/ConsoleValue.cs @@ -0,0 +1,75 @@ +using System; +using System.Globalization; +using System.ComponentModel; + + +namespace Xaml.TestVocab.Console { + + [TypeConverter(typeof(ConsoleValueConverter))] + public abstract class ConsoleValue { + public abstract string Value { get; } + } + + public class ConsoleValueConverter : TypeConverter { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type t) + { + return (t == typeof(ConsoleValue)); + } + public override bool CanConvertTo(ITypeDescriptorContext context, Type t) + { + return (t == typeof(string)); + } + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object o) + { + if (o is string) + return new ConsoleValueString((string)o); + else + throw new NotSupportedException(); + } + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, Object o, Type destinationType) + { + if (destinationType != typeof(string)) + throw new NotSupportedException(); + if (o is ConsoleValue) + return ((ConsoleValue)o).Value; + else + throw new NotSupportedException(); + } + } + + + + public class ConsoleValueString : ConsoleValue { + string val; + public ConsoleValueString(string val) + { + this.val = val; + } + + public override string Value { + get { return val; } + } + } + + public class ConsoleValueVar : ConsoleValue { + string var; + public ConsoleValueVar() + { + } + + public ConsoleValueVar(string var) + { + this.var = var; + } + + public override string Value { + get { return ConsoleVars.Get(var); } + } + + public string Variable { + get { return var; } + set { var = value; } + } + } + +} diff --git a/mcs/tools/xamlc/demo/TestVocab/ConsoleVars.cs b/mcs/tools/xamlc/demo/TestVocab/ConsoleVars.cs new file mode 100644 index 00000000000..26b04aca41a --- /dev/null +++ b/mcs/tools/xamlc/demo/TestVocab/ConsoleVars.cs @@ -0,0 +1,13 @@ +using System.Collections; + +namespace Xaml.TestVocab.Console { + public class ConsoleVars { + private static Hashtable storage = new Hashtable(); + public static void Set(string name, string o) { + storage[name] = o; + } + public static string Get(string name) { + return (string)storage[name]; + } + } +} diff --git a/mcs/tools/xamlc/demo/TestVocab/ConsoleWriter.cs b/mcs/tools/xamlc/demo/TestVocab/ConsoleWriter.cs index ad636e08ad3..9d2e9d63dcf 100644 --- a/mcs/tools/xamlc/demo/TestVocab/ConsoleWriter.cs +++ b/mcs/tools/xamlc/demo/TestVocab/ConsoleWriter.cs @@ -14,9 +14,9 @@ namespace Xaml.TestVocab.Console { text = ""; } - public ConsoleWriter(string text) + public ConsoleWriter(ConsoleValue text) { - this.text = text; + this.text = text.Value; } public string Text { @@ -35,7 +35,7 @@ namespace Xaml.TestVocab.Console { public void AddChild(Object o) { - throw new NotImplementedException(); + this.text += ((ConsoleValue)o).Value; } diff --git a/mcs/tools/xamlc/demo/test.xaml b/mcs/tools/xamlc/demo/test.xaml index 27119fc94a8..ddefc829a06 100644 --- a/mcs/tools/xamlc/demo/test.xaml +++ b/mcs/tools/xamlc/demo/test.xaml @@ -1,4 +1,4 @@ -<?Mapping ClrNamespace="Xaml.TestVocab.Console" Assembly="TestVocab" XmlNamespace="console" ?> +<?Mapping ClrNamespace="Xaml.TestVocab.Console" Assembly="TestVocab.dll" XmlNamespace="console" ?> <ConsoleApp xmlns="console" xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005" @@ -7,6 +7,18 @@ <ConsoleWriter>IT BEGINS!</ConsoleWriter> <ConsoleWriter x:Name="_greeter" Text="Hello World" /> <ConsoleWriter Text="I'm surrounded!" Filter="stringFilter" /> + <ConsoleReader Variable="thingo"> + <ConsoleReader.Prompt> + <ConsoleWriter>What should I say?</ConsoleWriter> + </ConsoleReader.Prompt> + </ConsoleReader> +<!-- + <ConsoleWriter> + <ConsoleWriter.Text> + <ConsoleValueVar Variable="thingo" /> + </ConsoleWriter.Text> + </ConsoleWriter> +--> <ConsoleWriter> <ConsoleApp.Repetitions>3</ConsoleApp.Repetitions> <ConsoleWriter.Text>Goodbye.</ConsoleWriter.Text> diff --git a/mcs/tools/xamlc/xamlc.cs b/mcs/tools/xamlc/xamlc.cs index 2759f32c642..5983ddf47eb 100644 --- a/mcs/tools/xamlc/xamlc.cs +++ b/mcs/tools/xamlc/xamlc.cs @@ -28,6 +28,7 @@ using System; using System.IO; +using System.Xml; using System.CodeDom; using System.CodeDom.Compiler; using Mono.GetOptions; @@ -55,10 +56,17 @@ class Driver { options.OutputFile = input + ".out"; } ICodeGenerator generator = (new Microsoft.CSharp.CSharpCodeProvider()).CreateGenerator(); + XmlTextReader xr = new XmlTextReader(input); TextWriter tw = new StreamWriter(options.OutputFile); CodeWriter cw = new CodeWriter(generator, tw, options.Partial); - XamlParser r = new XamlParser(input, cw); - r.Parse(); + XamlParser r = new XamlParser(xr, cw); + try { + r.Parse(); + } + catch (Exception ex) { + Console.WriteLine("Line " + xr.LineNumber + ", Column " + xr.LinePosition); + throw ex; + } } public static void Main(string[] args) { |