2 // System.ComponentModel.Design.Serialization.CodeDomSerializerBase
5 // Ivan N. Zlatev (contact i-nZ.net)
7 // (C) 2007 Ivan N. Zlatev
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
34 using System.Reflection;
35 using System.ComponentModel;
36 using System.ComponentModel.Design;
40 namespace System.ComponentModel.Design.Serialization
42 [EditorBrowsable (EditorBrowsableState.Never)]
43 public abstract class CodeDomSerializerBase
46 private string _deserializationErrorTrace = null;
47 private string _deserializationError = null;
49 internal CodeDomSerializerBase ()
53 private class ExpressionTable : Hashtable // just so that we have a specific type to append to the context stack
57 protected CodeExpression SerializeToExpression (IDesignerSerializationManager manager, object instance)
60 throw new ArgumentNullException ("manager");
62 CodeExpression expression = null;
64 expression = this.GetExpression (manager, instance); // 1 - IDesignerSerializationManager.GetExpression
65 if (expression == null) {
66 CodeDomSerializer serializer = this.GetSerializer (manager, instance); // 2 - manager.GetSerializer().Serialize()
67 if (serializer != null) {
68 object serialized = serializer.Serialize (manager, instance);
69 expression = serialized as CodeExpression; // 3 - CodeStatement or CodeStatementCollection
70 if (expression == null) {
71 CodeStatement statement = serialized as CodeStatement;
72 CodeStatementCollection statements = serialized as CodeStatementCollection;
74 if (statement != null || statements != null) {
75 CodeStatementCollection contextStatements = null;
77 StatementContext context = manager.Context[typeof (StatementContext)] as StatementContext;
78 if (context != null && instance != null)
79 contextStatements = context.StatementCollection[instance];
81 if (contextStatements == null)
82 contextStatements = manager.Context[typeof (CodeStatementCollection)] as CodeStatementCollection;
84 if (contextStatements != null) {
85 if (statements != null)
86 contextStatements.AddRange (statements);
88 contextStatements.Add (statement);
92 if (expression == null && instance != null)
93 expression = this.GetExpression (manager, instance); // 4
99 protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, object instance)
101 DesignerSerializerAttribute attrInstance, attrType;
102 attrType = attrInstance = null;
104 CodeDomSerializer serializer = null;
105 if (instance == null)
106 serializer = this.GetSerializer (manager, null);
108 AttributeCollection attributes = TypeDescriptor.GetAttributes (instance);
109 foreach (Attribute a in attributes) {
110 DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute;
111 if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) {
112 attrInstance = designerAttr;
117 attributes = TypeDescriptor.GetAttributes (instance.GetType ());
118 foreach (Attribute a in attributes) {
119 DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute;
120 if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) {
121 attrType = designerAttr;
126 // if there is metadata modification in the instance then create the specified serializer instead of the one
128 if (attrType != null && attrInstance != null && attrType.SerializerTypeName != attrInstance.SerializerTypeName)
129 serializer = Activator.CreateInstance (manager.GetType (attrInstance.SerializerTypeName)) as CodeDomSerializer;
131 serializer = this.GetSerializer (manager, instance.GetType ());
137 protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, Type instanceType)
139 return manager.GetSerializer (instanceType, typeof (CodeDomSerializer)) as CodeDomSerializer;
142 protected CodeExpression GetExpression (IDesignerSerializationManager manager, object instance)
145 throw new ArgumentNullException ("manager");
146 if (instance == null)
147 throw new ArgumentNullException ("instance");
149 CodeExpression expression = null;
151 ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable;
152 if (expressions != null) // 1st try: ExpressionTable
153 expression = expressions [instance] as CodeExpression;
155 if (expression == null) { // 2nd try: RootContext
156 RootContext context = manager.Context[typeof (RootContext)] as RootContext;
157 if (context != null && context.Value == instance)
158 expression = context.Expression;
161 if (expression == null) { // 3rd try: IReferenceService (instnace.property.property.property
162 string name = manager.GetName (instance);
163 if (name == null || name.IndexOf (".") == -1) {
164 IReferenceService service = manager.GetService (typeof (IReferenceService)) as IReferenceService;
165 if (service != null) {
166 name = service.GetName (instance);
167 if (name != null && name.IndexOf (".") != -1) {
168 string[] parts = name.Split (new char[] { ',' });
169 instance = manager.GetInstance (parts[0]);
170 if (instance != null) {
171 expression = SerializeToExpression (manager, instance);
172 if (expression != null) {
173 for (int i=1; i < parts.Length; i++)
174 expression = new CodePropertyReferenceExpression (expression, parts[i]);
184 protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression)
186 SetExpression (manager, instance, expression, false);
189 // XXX: isPreset - what does this do when set?
191 protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression, bool isPreset)
194 throw new ArgumentNullException ("manager");
195 if (instance == null)
196 throw new ArgumentNullException ("instance");
197 if (expression == null)
198 throw new ArgumentNullException ("expression");
200 ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable;
201 if (expressions == null) {
202 expressions = new ExpressionTable ();
203 manager.Context.Append (expressions);
206 expressions[instance] = expression;
209 protected bool IsSerialized (IDesignerSerializationManager manager, object value)
211 return this.IsSerialized (manager, value, false);
214 // XXX: What should honorPreset do?
215 protected bool IsSerialized (IDesignerSerializationManager manager, object instance, bool honorPreset)
217 if (instance == null)
218 throw new ArgumentNullException ("instance");
220 throw new ArgumentNullException ("manager");
222 if (this.GetExpression (manager, instance) != null)
228 protected CodeExpression SerializeCreationExpression (IDesignerSerializationManager manager, object value, out bool isComplete)
231 throw new ArgumentNullException ("value");
233 throw new ArgumentNullException ("manager");
235 CodeExpression expression = null;
237 TypeConverter converter = TypeDescriptor.GetConverter (value);
238 if (converter != null && converter.CanConvertTo (typeof (InstanceDescriptor))) {
239 InstanceDescriptor descriptor = converter.ConvertTo (value, typeof (InstanceDescriptor)) as InstanceDescriptor;
240 isComplete = descriptor.IsComplete;
241 if (descriptor != null || descriptor.MemberInfo != null)
242 expression = this.SerializeInstanceDescriptor (manager, descriptor);
244 ReportError (manager, "Unable to serialize to InstanceDescriptor",
245 "Value Type: " + value.GetType ().Name + System.Environment.NewLine +
246 "Value (ToString): " + value.ToString ());
248 expression = new CodeObjectCreateExpression (value.GetType ().FullName, new CodeExpression[0]);
254 private CodeExpression SerializeInstanceDescriptor (IDesignerSerializationManager manager, InstanceDescriptor descriptor)
256 CodeExpression expression = null;
257 MemberInfo member = descriptor.MemberInfo;
258 CodeExpression target = new CodeTypeReferenceExpression (member.DeclaringType);
260 if (member is PropertyInfo) {
261 expression = new CodePropertyReferenceExpression (target, member.Name);
262 } else if (member is FieldInfo) {
263 expression = new CodeFieldReferenceExpression (target, member.Name);
264 } else if (member is MethodInfo) {
265 CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression (target, member.Name);
266 manager.Context.Push (new ExpressionContext (methodInvoke, methodInvoke.GetType (), null, null));
267 if (descriptor.Arguments != null && descriptor.Arguments.Count > 0)
268 methodInvoke.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments));
269 manager.Context.Pop ();
270 expression = methodInvoke;
271 } else if (member is ConstructorInfo) {
272 CodeObjectCreateExpression createExpr = new CodeObjectCreateExpression (member.DeclaringType);
273 manager.Context.Push (new ExpressionContext (createExpr, createExpr.GetType (), null, null));
274 if (descriptor.Arguments != null && descriptor.Arguments.Count > 0)
275 createExpr.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments));
276 manager.Context.Pop ();
277 expression = createExpr;
283 private CodeExpression[] SerializeParameters (IDesignerSerializationManager manager, ICollection parameters)
285 CodeExpression[] expressions = null;
287 if (parameters != null && parameters.Count > 0) {
288 expressions = new CodeExpression[parameters.Count];
290 foreach (object parameter in parameters) {
291 expressions[i] = this.SerializeToExpression (manager, parameter);
299 protected void SerializeEvent (IDesignerSerializationManager manager, CodeStatementCollection statements,
300 object value, EventDescriptor descriptor)
302 if (descriptor == null)
303 throw new ArgumentNullException ("descriptor");
305 throw new ArgumentNullException ("value");
306 if (statements == null)
307 throw new ArgumentNullException ("statements");
309 throw new ArgumentNullException ("manager");
311 MemberCodeDomSerializer serializer = manager.GetSerializer (descriptor.GetType (), typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer;
312 if (serializer != null && serializer.ShouldSerialize (manager, value, descriptor))
313 serializer.Serialize (manager, value, descriptor, statements);
316 protected void SerializeEvents (IDesignerSerializationManager manager, CodeStatementCollection statements,
317 object value, params Attribute[] filter)
320 throw new ArgumentNullException ("filter");
322 throw new ArgumentNullException ("value");
323 if (statements == null)
324 throw new ArgumentNullException ("statements");
326 throw new ArgumentNullException ("manager");
328 EventDescriptorCollection events = TypeDescriptor.GetEvents (value, filter);
329 foreach (EventDescriptor e in events)
330 this.SerializeEvent (manager, statements, value, e);
333 protected void SerializeProperty (IDesignerSerializationManager manager, CodeStatementCollection statements, object value, PropertyDescriptor propertyToSerialize)
335 if (propertyToSerialize == null)
336 throw new ArgumentNullException ("propertyToSerialize");
338 throw new ArgumentNullException ("value");
339 if (statements == null)
340 throw new ArgumentNullException ("statements");
342 throw new ArgumentNullException ("manager");
344 MemberCodeDomSerializer serializer = manager.GetSerializer (propertyToSerialize.GetType (), typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer;
345 if (serializer != null && serializer.ShouldSerialize (manager, value, propertyToSerialize))
346 serializer.Serialize (manager, value, propertyToSerialize, statements);
349 protected void SerializeProperties (IDesignerSerializationManager manager, CodeStatementCollection statements,
350 object value, Attribute[] filter)
353 throw new ArgumentNullException ("filter");
355 throw new ArgumentNullException ("value");
356 if (statements == null)
357 throw new ArgumentNullException ("statements");
359 throw new ArgumentNullException ("manager");
361 PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (value, filter);
362 foreach (PropertyDescriptor property in properties)
363 this.SerializeProperty (manager, statements, value, property);
366 protected virtual object DeserializeInstance (IDesignerSerializationManager manager, Type type,
367 object[] parameters, string name, bool addToContainer)
370 throw new ArgumentNullException ("type");
372 throw new ArgumentNullException ("manager");
374 return manager.CreateInstance (type, parameters, name, addToContainer);
377 protected string GetUniqueName (IDesignerSerializationManager manager, object instance)
379 if (instance == null)
380 throw new ArgumentNullException ("instance");
382 throw new ArgumentNullException ("manager");
384 string name = manager.GetName (instance);
386 INameCreationService service = manager.GetService (typeof (INameCreationService)) as INameCreationService;
387 name = service.CreateName (null, instance.GetType ());
389 name = instance.GetType ().Name.ToLower ();
390 manager.SetName (instance, name);
395 protected object DeserializeExpression (IDesignerSerializationManager manager, string name, CodeExpression expression)
397 if (expression == null)
398 throw new ArgumentNullException ("expression");
400 throw new ArgumentNullException ("manager");
402 object deserialized = null;
404 // CodeThisReferenceExpression
406 CodeThisReferenceExpression thisExpr = expression as CodeThisReferenceExpression;
407 if (thisExpr != null) {
408 RootContext context = manager.Context[typeof (RootContext)] as RootContext;
409 if (context != null) {
410 deserialized = context.Value;
412 IDesignerHost host = manager.GetService (typeof (IDesignerHost)) as IDesignerHost;
414 deserialized = host.RootComponent;
418 // CodeVariableReferenceExpression
420 CodeVariableReferenceExpression varRef = expression as CodeVariableReferenceExpression;
421 if (deserialized == null && varRef != null) {
422 deserialized = manager.GetInstance (varRef.VariableName);
423 if (deserialized == null)
424 _deserializationError = "Cannot find the value of the variable " + varRef.VariableName + "";
427 // CodeFieldReferenceExpression
429 CodeFieldReferenceExpression fieldRef = expression as CodeFieldReferenceExpression;
430 if (deserialized == null && fieldRef != null) {
431 deserialized = manager.GetInstance (fieldRef.FieldName);
432 if (deserialized == null)
433 _deserializationError = "Cannot find the value of the field " + fieldRef.FieldName + "";
437 // CodePrimitiveExpression
439 CodePrimitiveExpression primitiveExp = expression as CodePrimitiveExpression;
440 if (deserialized == null && primitiveExp != null)
441 deserialized = primitiveExp.Value;
443 // CodePropertyReferenceExpression
445 CodePropertyReferenceExpression propRef = expression as CodePropertyReferenceExpression;
446 if (deserialized == null && propRef != null) {
447 object target = DeserializeExpression (manager, null, propRef.TargetObject);
448 if (target != null) {
450 if (target is Type) {
451 PropertyInfo property = ((Type)target).GetProperty (propRef.PropertyName,
452 BindingFlags.GetProperty |
453 BindingFlags.Public | BindingFlags.Static);
454 if (property != null) {
455 deserialized = property.GetValue (null, null);
459 // NRefactory seems to produce PropertyReferences to reference some fields and enums
461 FieldInfo field = ((Type)target).GetField (propRef.PropertyName,
462 BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
464 deserialized = field.GetValue (null);
468 PropertyDescriptor property = TypeDescriptor.GetProperties (target)[propRef.PropertyName];
469 if (property != null) {
470 deserialized = property.GetValue (target);
474 FieldInfo field = target.GetType().GetField (propRef.PropertyName,
475 BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
477 deserialized = field.GetValue (null);
483 _deserializationError = "No property " + propRef.PropertyName + " found in type " +
484 (target is Type ? ((Type)target).Name : target.GetType ().Name);
485 _deserializationErrorTrace = "Property Name: " + propRef.PropertyName + System.Environment.NewLine +
486 "Property is: " + (target is Type ? "static" : "instance") + System.Environment.NewLine +
487 "Property Holder Type: " + (target is Type ? ((Type)target).Name : target.GetType ().Name) + System.Environment.NewLine +
488 "Property Holder Expression Type: " + propRef.TargetObject.GetType ().Name + System.Environment.NewLine;
493 // CodeObjectCreateExpression
495 CodeObjectCreateExpression createExpr = expression as CodeObjectCreateExpression;
496 if (deserialized == null && createExpr != null) {
497 Type type = manager.GetType (createExpr.CreateType.BaseType);
499 _deserializationError = "Unable to find the type " + createExpr.CreateType.BaseType;
501 object[] arguments = new object[createExpr.Parameters.Count];
502 for (int i=0; i < createExpr.Parameters.Count; i++) {
503 arguments[i] = this.DeserializeExpression (manager, null, createExpr.Parameters[i]);
504 if (_deserializationError != null) {
505 _deserializationErrorTrace = "Type to create: " + createExpr.CreateType.BaseType + System.Environment.NewLine +
506 "Parameter Number: " + i.ToString () + System.Environment.NewLine +
507 "Parameter Expression Type: " + createExpr.Parameters[i].GetType ().Name + System.Environment.NewLine +
508 "Parameters Count: " + createExpr.Parameters.Count + System.Environment.NewLine +
509 _deserializationErrorTrace;
513 if (_deserializationError == null) {
514 bool addToContainer = false;
515 if (typeof(IComponent).IsAssignableFrom (type))
516 addToContainer = true;
517 deserialized = this.DeserializeInstance (manager, type, arguments, name, addToContainer);
518 if (deserialized == null) {
519 _deserializationError = "Unable to create an instance of type " + createExpr.CreateType.BaseType;
520 _deserializationErrorTrace = "Type to create: " + createExpr.CreateType.BaseType + System.Environment.NewLine +
521 "Name: " + name + System.Environment.NewLine +
522 "addToContainer: " + addToContainer.ToString () + System.Environment.NewLine +
523 "Parameters Count: " + createExpr.Parameters.Count + System.Environment.NewLine;
525 for (int i=0; i < arguments.Length; i++) {
526 _deserializationErrorTrace += "Parameter Number: " + i.ToString () + System.Environment.NewLine +
527 "Parameter Type: " + (arguments[i] == null ? "null" : arguments[i].GetType ().Name) +
528 System.Environment.NewLine +
529 "Parameter " + i.ToString () + " Value: " + arguments[i].ToString () + System.Environment.NewLine;
536 // CodeArrayCreateExpression
538 CodeArrayCreateExpression arrayCreateExpr = expression as CodeArrayCreateExpression;
539 if (deserialized == null && arrayCreateExpr != null) {
540 Type arrayType = manager.GetType (arrayCreateExpr.CreateType.BaseType);
541 if (arrayType == null) {
542 _deserializationError = "Unable to find the type " + arrayCreateExpr.CreateType.BaseType;
544 ArrayList initializers = new ArrayList ();
545 Type elementType = arrayType.GetElementType ();
546 deserialized = Array.CreateInstance (arrayType, arrayCreateExpr.Initializers.Count);
547 for (int i = 0; i < arrayCreateExpr.Initializers.Count; i++) {
548 object element = this.DeserializeExpression (manager, null, arrayCreateExpr.Initializers[i]);
549 if (_deserializationError != null) {
550 _deserializationErrorTrace = "Array Type: " + arrayType.Name + System.Environment.NewLine +
551 "Array Element Type: " + elementType + System.Environment.NewLine +
552 "Initializer Number: " + i.ToString () + System.Environment.NewLine +
553 "Initializer Type: " + (element == null ? "null" : element.GetType ().Name) + System.Environment.NewLine +
554 "Initialzer Value" + (element == null ? "null" : element.ToString ()) + System.Environment.NewLine +
555 _deserializationErrorTrace;
557 if (arrayType.IsInstanceOfType (element)) {
558 initializers.Add (element);
560 _deserializationError = "Array initializer of incompatible type detected.";
561 _deserializationErrorTrace = "Array Type: " + arrayType.Name + System.Environment.NewLine +
562 "Array Element Type: " + elementType + System.Environment.NewLine +
563 "Initializer Type: " + (element == null ? "null" : element.GetType ().Name) + System.Environment.NewLine;
567 if (_deserializationError == null)
568 initializers.CopyTo ((Array)deserialized, 0);
574 // CodeMethodInvokeExpression
576 CodeMethodInvokeExpression methodExpr = expression as CodeMethodInvokeExpression;
577 if (deserialized == null && methodExpr != null) {
578 object target = this.DeserializeExpression (manager, null, methodExpr.Method.TargetObject);
579 object[] parameters = new object[methodExpr.Parameters.Count];
580 for (int i=0; i < methodExpr.Parameters.Count; i++) {
581 parameters[i] = this.DeserializeExpression (manager, null, methodExpr.Parameters[i]);
582 if (_deserializationError != null) {
583 _deserializationErrorTrace =
584 "Parameter Number: " + i.ToString () + System.Environment.NewLine +
585 "Parameter Expression Type: " + methodExpr.Parameters[i].GetType ().Name + System.Environment.NewLine +
586 _deserializationErrorTrace;
591 if (_deserializationError == null) {
592 MethodInfo method = null;
593 if (target is Type) {
594 method = GetExactMethod ((Type)target, methodExpr.Method.MethodName,
595 BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
598 method = GetExactMethod (target.GetType(), methodExpr.Method.MethodName,
599 BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
603 if (method != null) {
604 deserialized = method.Invoke (target, parameters);
606 _deserializationError = "Unable to find a matching method " + methodExpr.Method.MethodName + " in type " +
607 (target is Type ? ((Type)target).Name : target.GetType ().Name);
608 for (int i = 0; i < parameters.Length; i++) {
609 _deserializationErrorTrace += "Parameter Number: " + i.ToString () + System.Environment.NewLine +
610 "Parameter Type: " + (parameters[i] == null ? "null" : parameters[i].GetType ().Name) +
611 System.Environment.NewLine +
612 "Parameter " + i.ToString () + " Value: " + parameters[i].ToString () + System.Environment.NewLine;
616 if (_deserializationError != null) {
617 _deserializationErrorTrace =
618 "Method Name: " + methodExpr.Method.MethodName + System.Environment.NewLine +
619 "Method is: " + (target is Type ? "static" : "instance") + System.Environment.NewLine +
620 "Method Holder Type: " + (target is Type ? ((Type)target).Name : target.GetType ().Name) + System.Environment.NewLine +
621 "Parameters Count: " + methodExpr.Parameters.Count + System.Environment.NewLine +
622 _deserializationErrorTrace;
627 // CodeTypeReferenceExpression
629 CodeTypeReferenceExpression typeRef = expression as CodeTypeReferenceExpression;
630 if (deserialized == null && typeRef != null) {
631 deserialized = manager.GetType (typeRef.Type.BaseType);
632 if (deserialized == null)
633 _deserializationError = "Unable to find the type " + typeRef.Type.BaseType;
636 // CodeCastExpression
638 CodeCastExpression castExpr = expression as CodeCastExpression;
639 if (deserialized == null && castExpr != null) {
640 Type targetType = manager.GetType (castExpr.TargetType.BaseType);
641 if (targetType == null)
642 _deserializationError = "Unable to find the type " + castExpr.TargetType.BaseType;
644 object instance = DeserializeExpression (manager, null, castExpr.Expression);
645 if (instance != null && targetType != null) {
646 IConvertible convertible = instance as IConvertible;
647 if (convertible != null) {
649 instance = convertible.ToType (targetType, null);
651 _deserializationError = "Unable to convert type " + instance.GetType ().Name +
652 " to type " + castExpr.TargetType.BaseType;
655 _deserializationError = "Unable to convert type " + instance.GetType ().Name +
656 " to type " + castExpr.TargetType.BaseType;
659 deserialized = instance;
661 if (_deserializationError != null) {
662 _deserializationErrorTrace = "Target Type: " + castExpr.TargetType.BaseType + System.Environment.NewLine +
663 "Instance Type: " + (instance == null ? "null" : instance.GetType ().Name) + System.Environment.NewLine +
664 "Instance Value: " + (instance == null ? "null" : instance.ToString()) + System.Environment.NewLine +
665 "Instance is IConvertible: " + (instance is IConvertible).ToString() + System.Environment.NewLine +
666 _deserializationErrorTrace;
671 // CodeBinaryOperatorExpression
673 CodeBinaryOperatorExpression binOperator = expression as CodeBinaryOperatorExpression;
674 if (deserialized == null && binOperator != null) {
675 IConvertible left = null;
676 IConvertible right = null;
677 switch (binOperator.Operator) {
678 case CodeBinaryOperatorType.BitwiseOr:
679 left = DeserializeExpression (manager, null, binOperator.Left) as IConvertible;
680 right = DeserializeExpression (manager, null, binOperator.Right) as IConvertible;
681 if (left is Enum && right is Enum)
682 deserialized = Enum.ToObject (left.GetType (), Convert.ToInt64 (left) | Convert.ToInt64 (right));
684 _deserializationError = "CodeBinaryOperatorType.BitwiseOr only supported for Enum types";
687 _deserializationError = "Unsupported CodeBinaryOperatorType: " + binOperator.Operator.ToString ();
691 if (_deserializationError != null) {
692 _deserializationErrorTrace = "BinaryOperator Type: " + binOperator.Operator.ToString() + System.Environment.NewLine +
693 "Left Type: " + (left == null ? "null" : left.GetType().Name) + System.Environment.NewLine +
694 "Left Value: " + (left == null ? "null" : left.ToString ()) + System.Environment.NewLine +
695 "Left Expression Type: " + binOperator.Left.GetType ().Name + System.Environment.NewLine +
696 "Right Type: " + (right == null ? "null" : right.GetType().Name) + System.Environment.NewLine +
697 "Right Value: " + (right == null ? "null" : right.ToString ()) + System.Environment.NewLine +
698 "Right Expression Type: " + binOperator.Right.GetType ().Name + System.Environment.NewLine +
699 _deserializationErrorTrace;
704 if (_deserializationError != null) {
705 _deserializationErrorTrace = "* DeserializeExpression (" + expression.GetType().Name + ")"
706 + System.Environment.NewLine + _deserializationErrorTrace;
708 if (deserialized == null && !(expression is CodePrimitiveExpression) && !(expression is CodeMethodInvokeExpression))
709 _deserializationError = "Unsupported Expression Type: " + expression.GetType ().Name;
715 // Searches for a method on type that matches argument types
717 private MethodInfo GetExactMethod (Type type, string methodName, BindingFlags flags, ICollection argsCollection)
719 object[] arguments = null;
720 Type[] types = new Type[0];
722 if (argsCollection != null) {
723 arguments = new object[argsCollection.Count];
724 types = new Type[argsCollection.Count];
725 argsCollection.CopyTo (arguments, 0);
727 for (int i=0; i < arguments.Length; i++) {
728 if (arguments[i] == null)
731 types[i] = arguments[i].GetType ();
735 return type.GetMethod (methodName, flags, null, types, null);
738 protected void DeserializeStatement (IDesignerSerializationManager manager, CodeStatement statement)
740 if (statement == null)
741 throw new ArgumentNullException ("statement");
743 throw new ArgumentNullException ("manager");
745 _deserializationErrorTrace = null;
746 _deserializationError = null;
748 // CodeAssignStatement
750 CodeAssignStatement assignment = statement as CodeAssignStatement;
751 if (assignment != null)
752 DeserializeAssignmentStatement (manager, assignment);
754 // CodeExpressionStatement
756 CodeExpressionStatement expression = statement as CodeExpressionStatement;
757 if (expression != null)
758 this.DeserializeExpression (manager, null, expression.Expression);
760 // CodeAttachEventStatement
762 CodeAttachEventStatement attachStatement = statement as CodeAttachEventStatement;
763 if (attachStatement != null) {
764 string methodName = null;
766 CodeObjectCreateExpression createExpr = attachStatement.Listener as CodeObjectCreateExpression;
767 if (createExpr != null && createExpr.Parameters.Count == 1 ) { // += new EventType (method)
768 CodeMethodReferenceExpression handlerRef = createExpr.Parameters[0] as CodeMethodReferenceExpression;
769 if (handlerRef != null)
770 methodName = handlerRef.MethodName;
773 CodeDelegateCreateExpression delegateCreateExpr = attachStatement.Listener as CodeDelegateCreateExpression;
774 if (delegateCreateExpr != null)// += new EventType (method)
775 methodName = delegateCreateExpr.MethodName;
777 CodeMethodReferenceExpression methodRef = attachStatement.Listener as CodeMethodReferenceExpression;
778 if (methodRef != null) // += method
779 methodName = methodRef.MethodName;
781 object component = DeserializeExpression (manager, null, attachStatement.Event.TargetObject);
782 if (component != null && methodName != null) {
783 EventDescriptor eventDescriptor = TypeDescriptor.GetEvents (component)[attachStatement.Event.EventName];
784 if (eventDescriptor != null) {
785 IEventBindingService service = manager.GetService (typeof (IEventBindingService)) as IEventBindingService;
787 service.GetEventProperty (eventDescriptor).SetValue (component, methodName);
789 _deserializationError = "IEventBindingService missing.";
791 _deserializationError = "No event " + attachStatement.Event.EventName +
792 " found in type " + component.GetType ().Name;
796 if (_deserializationError != null) {
797 _deserializationErrorTrace = "Method Name: " + methodName + System.Environment.NewLine +
798 "Event Name: " + attachStatement.Event.EventName + System.Environment.NewLine +
799 "Listener Expression Type: " + methodRef.GetType ().Name + System.Environment.NewLine +
800 "Event Holder Type: " + component.GetType ().Name + System.Environment.NewLine +
801 "Event Holder Expression Type: " + attachStatement.Event.TargetObject.GetType ().Name + System.Environment.NewLine;
805 if (_deserializationErrorTrace != null) {
806 _deserializationErrorTrace = "* DeserializeStatement (" + statement.GetType().Name + ")"
807 + System.Environment.NewLine + _deserializationErrorTrace;
808 ReportError (manager, _deserializationError, _deserializationErrorTrace);
809 _deserializationErrorTrace = null;
810 _deserializationError = null;
814 private void DeserializeAssignmentStatement (IDesignerSerializationManager manager, CodeAssignStatement statement)
816 CodeExpression leftExpr = statement.Left;
818 // Assign to a Property
820 CodePropertyReferenceExpression propRef = leftExpr as CodePropertyReferenceExpression;
821 if (propRef != null) {
822 object propertyHolder = DeserializeExpression (manager, null, propRef.TargetObject);
824 if (_deserializationError == null)
825 value = DeserializeExpression (manager, null, statement.Right);
827 if (_deserializationError == null && propertyHolder != null) {
828 PropertyDescriptor property = TypeDescriptor.GetProperties (propertyHolder)[propRef.PropertyName];
829 if (property != null) {
830 property.SetValue (propertyHolder, value);
832 _deserializationError = "No property " + propRef.PropertyName + " found in type " + propertyHolder.GetType ().Name;
833 _deserializationErrorTrace = "Property Name: " + propRef.PropertyName + System.Environment.NewLine +
834 "Property Value: " + (value == null ? "null" : value.ToString()) + System.Environment.NewLine +
835 "Property Type: " + propertyHolder.GetType ().Name + System.Environment.NewLine +
836 "Property Holder Expression Type: " + propRef.TargetObject.GetType ().Name + System.Environment.NewLine;
843 CodeFieldReferenceExpression fieldRef = leftExpr as CodeFieldReferenceExpression;
844 if (fieldRef != null && fieldRef.FieldName != null) {
845 // Note that if the Right expression is a CodeCreationExpression the component will be created in this call
847 object fieldHolder = DeserializeExpression (manager, null, fieldRef.TargetObject);
849 if (_deserializationError == null)
850 value = DeserializeExpression (manager, fieldRef.FieldName, statement.Right);
851 FieldInfo field = null;
853 RootContext context = manager.Context[typeof (RootContext)] as RootContext;
854 if (_deserializationError == null && fieldHolder != null) {
855 if (fieldRef.TargetObject is CodeThisReferenceExpression && context != null && context.Value == fieldHolder) {
856 // Do not deserialize the fields of the root component, because the root component type
857 // is actually an instance of the its parent type, e.g: CustomControl : _UserControl_
858 // and thus it doesn't contain the fields. The trick is that once DeserializeExpression
859 // is called on a CodeObjectCreateExpression the component is created and is added to the name-instance
863 if (fieldHolder is Type) // static field
864 field = ((Type)fieldHolder).GetField (fieldRef.FieldName,
865 BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
866 else // instance field
867 field = fieldHolder.GetType().GetField (fieldRef.FieldName,
868 BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
870 field.SetValue (fieldHolder, value);
872 _deserializationError = "No field " + fieldRef.FieldName + " found in type " + fieldHolder.GetType ().Name;
873 _deserializationErrorTrace = "Field Name: " + fieldRef.FieldName + System.Environment.NewLine +
874 "Field is: " + (fieldHolder is Type ? "static" : "instance") + System.Environment.NewLine +
875 "Field Value: " + (value == null ? "null" : value.ToString()) + System.Environment.NewLine +
876 "Field Holder Type: " + fieldHolder.GetType ().Name + System.Environment.NewLine +
877 "Field Holder Expression Type: " + fieldRef.TargetObject.GetType ().Name + System.Environment.NewLine;
883 if (_deserializationError != null) {
884 _deserializationErrorTrace = "* DeserializeAssignStatement" + System.Environment.NewLine +
885 "Left Expression Type: " + statement.Left.GetType().Name + System.Environment.NewLine +
886 "Right Expression Type: " + statement.Right.GetType().Name + System.Environment.NewLine +
887 _deserializationErrorTrace;
891 internal void ReportError (IDesignerSerializationManager manager, string message)
893 this.ReportError (manager, message, "");
896 internal void ReportError (IDesignerSerializationManager manager, string message, string details)
899 throw new Exception (message);
900 } catch (Exception e) {
901 e.Data["Details"] = message + Environment.NewLine + Environment.NewLine + details;
902 manager.ReportError (e);
906 #region Resource Serialization - TODO
907 protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value)
909 throw new NotImplementedException ();
912 protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value, bool ensureInvariant)
914 throw new NotImplementedException ();
917 protected void SerializePropertiesToResources (IDesignerSerializationManager manager, CodeStatementCollection statements,
918 object value, Attribute[] filter)
920 throw new NotImplementedException ();
923 protected void SerializeResource (IDesignerSerializationManager manager, string resourceName, object value)
925 throw new NotImplementedException ();
928 protected void SerializeResourceInvariant (IDesignerSerializationManager manager, string resourceName, object value)
930 throw new NotImplementedException ();
933 protected void DeserializePropertiesFromResources (IDesignerSerializationManager manager, object value, Attribute[] filter)
935 throw new NotImplementedException ();