CodeDomSerializerBase.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940
  1. //
  2. // System.ComponentModel.Design.Serialization.CodeDomSerializerBase
  3. //
  4. // Authors:
  5. // Ivan N. Zlatev (contact i-nZ.net)
  6. //
  7. // (C) 2007 Ivan N. Zlatev
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. #if NET_2_0
  29. using System;
  30. using System.Collections;
  31. using System.Reflection;
  32. using System.ComponentModel;
  33. using System.ComponentModel.Design;
  34. using System.CodeDom;
  35. namespace System.ComponentModel.Design.Serialization
  36. {
  37. [EditorBrowsable (EditorBrowsableState.Never)]
  38. public abstract class CodeDomSerializerBase
  39. {
  40. private string _deserializationErrorTrace = null;
  41. private string _deserializationError = null;
  42. internal CodeDomSerializerBase ()
  43. {
  44. }
  45. private class ExpressionTable : Hashtable // just so that we have a specific type to append to the context stack
  46. {
  47. }
  48. protected CodeExpression SerializeToExpression (IDesignerSerializationManager manager, object instance)
  49. {
  50. if (manager == null)
  51. throw new ArgumentNullException ("manager");
  52. CodeExpression expression = null;
  53. if (instance != null)
  54. expression = this.GetExpression (manager, instance); // 1 - IDesignerSerializationManager.GetExpression
  55. if (expression == null) {
  56. CodeDomSerializer serializer = this.GetSerializer (manager, instance); // 2 - manager.GetSerializer().Serialize()
  57. if (serializer != null) {
  58. object serialized = serializer.Serialize (manager, instance);
  59. expression = serialized as CodeExpression; // 3 - CodeStatement or CodeStatementCollection
  60. if (expression == null) {
  61. CodeStatement statement = serialized as CodeStatement;
  62. CodeStatementCollection statements = serialized as CodeStatementCollection;
  63. if (statement != null || statements != null) {
  64. CodeStatementCollection contextStatements = null;
  65. StatementContext context = manager.Context[typeof (StatementContext)] as StatementContext;
  66. if (context != null && instance != null)
  67. contextStatements = context.StatementCollection[instance];
  68. if (contextStatements == null)
  69. contextStatements = manager.Context[typeof (CodeStatementCollection)] as CodeStatementCollection;
  70. if (contextStatements != null) {
  71. if (statements != null)
  72. contextStatements.AddRange (statements);
  73. else
  74. contextStatements.Add (statement);
  75. }
  76. }
  77. }
  78. if (expression == null && instance != null)
  79. expression = this.GetExpression (manager, instance); // 4
  80. }
  81. }
  82. return expression;
  83. }
  84. protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, object instance)
  85. {
  86. DesignerSerializerAttribute attrInstance, attrType;
  87. attrType = attrInstance = null;
  88. CodeDomSerializer serializer = null;
  89. if (instance == null)
  90. serializer = this.GetSerializer (manager, null);
  91. else {
  92. AttributeCollection attributes = TypeDescriptor.GetAttributes (instance);
  93. foreach (Attribute a in attributes) {
  94. DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute;
  95. if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) {
  96. attrInstance = designerAttr;
  97. break;
  98. }
  99. }
  100. attributes = TypeDescriptor.GetAttributes (instance.GetType ());
  101. foreach (Attribute a in attributes) {
  102. DesignerSerializerAttribute designerAttr = a as DesignerSerializerAttribute;
  103. if (designerAttr != null && manager.GetType (designerAttr.SerializerBaseTypeName) == typeof (CodeDomSerializer)) {
  104. attrType = designerAttr;
  105. break;
  106. }
  107. }
  108. // if there is metadata modification in the instance then create the specified serializer instead of the one
  109. // in the Type.
  110. if (attrType != null && attrInstance != null && attrType.SerializerTypeName != attrInstance.SerializerTypeName)
  111. serializer = Activator.CreateInstance (manager.GetType (attrInstance.SerializerTypeName)) as CodeDomSerializer;
  112. else
  113. serializer = this.GetSerializer (manager, instance.GetType ());
  114. }
  115. return serializer;
  116. }
  117. protected CodeDomSerializer GetSerializer (IDesignerSerializationManager manager, Type instanceType)
  118. {
  119. return manager.GetSerializer (instanceType, typeof (CodeDomSerializer)) as CodeDomSerializer;
  120. }
  121. protected CodeExpression GetExpression (IDesignerSerializationManager manager, object instance)
  122. {
  123. if (manager == null)
  124. throw new ArgumentNullException ("manager");
  125. if (instance == null)
  126. throw new ArgumentNullException ("instance");
  127. CodeExpression expression = null;
  128. ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable;
  129. if (expressions != null) // 1st try: ExpressionTable
  130. expression = expressions [instance] as CodeExpression;
  131. if (expression == null) { // 2nd try: RootContext
  132. RootContext context = manager.Context[typeof (RootContext)] as RootContext;
  133. if (context != null && context.Value == instance)
  134. expression = context.Expression;
  135. }
  136. if (expression == null) { // 3rd try: IReferenceService (instnace.property.property.property
  137. string name = manager.GetName (instance);
  138. if (name == null || name.IndexOf (".") == -1) {
  139. IReferenceService service = manager.GetService (typeof (IReferenceService)) as IReferenceService;
  140. if (service != null) {
  141. name = service.GetName (instance);
  142. if (name != null && name.IndexOf (".") != -1) {
  143. string[] parts = name.Split (new char[] { ',' });
  144. instance = manager.GetInstance (parts[0]);
  145. if (instance != null) {
  146. expression = SerializeToExpression (manager, instance);
  147. if (expression != null) {
  148. for (int i=1; i < parts.Length; i++)
  149. expression = new CodePropertyReferenceExpression (expression, parts[i]);
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. return expression;
  157. }
  158. protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression)
  159. {
  160. SetExpression (manager, instance, expression, false);
  161. }
  162. // XXX: isPreset - what does this do when set?
  163. //
  164. protected void SetExpression (IDesignerSerializationManager manager, object instance, CodeExpression expression, bool isPreset)
  165. {
  166. if (manager == null)
  167. throw new ArgumentNullException ("manager");
  168. if (instance == null)
  169. throw new ArgumentNullException ("instance");
  170. if (expression == null)
  171. throw new ArgumentNullException ("expression");
  172. ExpressionTable expressions = manager.Context[typeof (ExpressionTable)] as ExpressionTable;
  173. if (expressions == null) {
  174. expressions = new ExpressionTable ();
  175. manager.Context.Append (expressions);
  176. }
  177. expressions[instance] = expression;
  178. }
  179. protected bool IsSerialized (IDesignerSerializationManager manager, object value)
  180. {
  181. return this.IsSerialized (manager, value, false);
  182. }
  183. // XXX: What should honorPreset do?
  184. protected bool IsSerialized (IDesignerSerializationManager manager, object instance, bool honorPreset)
  185. {
  186. if (instance == null)
  187. throw new ArgumentNullException ("instance");
  188. if (manager == null)
  189. throw new ArgumentNullException ("manager");
  190. if (this.GetExpression (manager, instance) != null)
  191. return true;
  192. else
  193. return false;
  194. }
  195. protected CodeExpression SerializeCreationExpression (IDesignerSerializationManager manager, object value, out bool isComplete)
  196. {
  197. if (value == null)
  198. throw new ArgumentNullException ("value");
  199. if (manager == null)
  200. throw new ArgumentNullException ("manager");
  201. CodeExpression expression = null;
  202. TypeConverter converter = TypeDescriptor.GetConverter (value);
  203. if (converter != null && converter.CanConvertTo (typeof (InstanceDescriptor))) {
  204. InstanceDescriptor descriptor = converter.ConvertTo (value, typeof (InstanceDescriptor)) as InstanceDescriptor;
  205. isComplete = descriptor.IsComplete;
  206. if (descriptor != null || descriptor.MemberInfo != null)
  207. expression = this.SerializeInstanceDescriptor (manager, descriptor);
  208. else
  209. ReportError (manager, "Unable to serialize to InstanceDescriptor",
  210. "Value Type: " + value.GetType ().Name + System.Environment.NewLine +
  211. "Value (ToString): " + value.ToString ());
  212. } else {
  213. expression = new CodeObjectCreateExpression (value.GetType ().FullName, new CodeExpression[0]);
  214. isComplete = false;
  215. }
  216. return expression;
  217. }
  218. private CodeExpression SerializeInstanceDescriptor (IDesignerSerializationManager manager, InstanceDescriptor descriptor)
  219. {
  220. CodeExpression expression = null;
  221. MemberInfo member = descriptor.MemberInfo;
  222. CodeExpression target = new CodeTypeReferenceExpression (member.DeclaringType);
  223. if (member is PropertyInfo) {
  224. expression = new CodePropertyReferenceExpression (target, member.Name);
  225. } else if (member is FieldInfo) {
  226. expression = new CodeFieldReferenceExpression (target, member.Name);
  227. } else if (member is MethodInfo) {
  228. CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression (target, member.Name);
  229. manager.Context.Push (new ExpressionContext (methodInvoke, methodInvoke.GetType (), null, null));
  230. if (descriptor.Arguments != null && descriptor.Arguments.Count > 0)
  231. methodInvoke.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments));
  232. manager.Context.Pop ();
  233. expression = methodInvoke;
  234. } else if (member is ConstructorInfo) {
  235. CodeObjectCreateExpression createExpr = new CodeObjectCreateExpression (member.DeclaringType);
  236. manager.Context.Push (new ExpressionContext (createExpr, createExpr.GetType (), null, null));
  237. if (descriptor.Arguments != null && descriptor.Arguments.Count > 0)
  238. createExpr.Parameters.AddRange (SerializeParameters (manager, descriptor.Arguments));
  239. manager.Context.Pop ();
  240. expression = createExpr;
  241. }
  242. return expression;
  243. }
  244. private CodeExpression[] SerializeParameters (IDesignerSerializationManager manager, ICollection parameters)
  245. {
  246. CodeExpression[] expressions = null;
  247. if (parameters != null && parameters.Count > 0) {
  248. expressions = new CodeExpression[parameters.Count];
  249. int i = 0;
  250. foreach (object parameter in parameters) {
  251. expressions[i] = this.SerializeToExpression (manager, parameter);
  252. i++;
  253. }
  254. }
  255. return expressions;
  256. }
  257. protected void SerializeEvent (IDesignerSerializationManager manager, CodeStatementCollection statements,
  258. object value, EventDescriptor descriptor)
  259. {
  260. if (descriptor == null)
  261. throw new ArgumentNullException ("descriptor");
  262. if (value == null)
  263. throw new ArgumentNullException ("value");
  264. if (statements == null)
  265. throw new ArgumentNullException ("statements");
  266. if (manager == null)
  267. throw new ArgumentNullException ("manager");
  268. MemberCodeDomSerializer serializer = manager.GetSerializer (descriptor.GetType (), typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer;
  269. if (serializer != null && serializer.ShouldSerialize (manager, value, descriptor))
  270. serializer.Serialize (manager, value, descriptor, statements);
  271. }
  272. protected void SerializeEvents (IDesignerSerializationManager manager, CodeStatementCollection statements,
  273. object value, params Attribute[] filter)
  274. {
  275. if (filter == null)
  276. throw new ArgumentNullException ("filter");
  277. if (value == null)
  278. throw new ArgumentNullException ("value");
  279. if (statements == null)
  280. throw new ArgumentNullException ("statements");
  281. if (manager == null)
  282. throw new ArgumentNullException ("manager");
  283. EventDescriptorCollection events = TypeDescriptor.GetEvents (value, filter);
  284. foreach (EventDescriptor e in events)
  285. this.SerializeEvent (manager, statements, value, e);
  286. }
  287. protected void SerializeProperty (IDesignerSerializationManager manager, CodeStatementCollection statements, object value, PropertyDescriptor propertyToSerialize)
  288. {
  289. if (propertyToSerialize == null)
  290. throw new ArgumentNullException ("propertyToSerialize");
  291. if (value == null)
  292. throw new ArgumentNullException ("value");
  293. if (statements == null)
  294. throw new ArgumentNullException ("statements");
  295. if (manager == null)
  296. throw new ArgumentNullException ("manager");
  297. MemberCodeDomSerializer serializer = manager.GetSerializer (propertyToSerialize.GetType (), typeof (MemberCodeDomSerializer)) as MemberCodeDomSerializer;
  298. if (serializer != null && serializer.ShouldSerialize (manager, value, propertyToSerialize))
  299. serializer.Serialize (manager, value, propertyToSerialize, statements);
  300. }
  301. protected void SerializeProperties (IDesignerSerializationManager manager, CodeStatementCollection statements,
  302. object value, Attribute[] filter)
  303. {
  304. if (filter == null)
  305. throw new ArgumentNullException ("filter");
  306. if (value == null)
  307. throw new ArgumentNullException ("value");
  308. if (statements == null)
  309. throw new ArgumentNullException ("statements");
  310. if (manager == null)
  311. throw new ArgumentNullException ("manager");
  312. PropertyDescriptorCollection properties = TypeDescriptor.GetProperties (value, filter);
  313. foreach (PropertyDescriptor property in properties)
  314. this.SerializeProperty (manager, statements, value, property);
  315. }
  316. protected virtual object DeserializeInstance (IDesignerSerializationManager manager, Type type,
  317. object[] parameters, string name, bool addToContainer)
  318. {
  319. if (type == null)
  320. throw new ArgumentNullException ("type");
  321. if (manager == null)
  322. throw new ArgumentNullException ("manager");
  323. return manager.CreateInstance (type, parameters, name, addToContainer);
  324. }
  325. protected string GetUniqueName (IDesignerSerializationManager manager, object instance)
  326. {
  327. if (instance == null)
  328. throw new ArgumentNullException ("instance");
  329. if (manager == null)
  330. throw new ArgumentNullException ("manager");
  331. string name = manager.GetName (instance);
  332. if (name == null) {
  333. INameCreationService service = manager.GetService (typeof (INameCreationService)) as INameCreationService;
  334. name = service.CreateName (null, instance.GetType ());
  335. if (name == null)
  336. name = instance.GetType ().Name.ToLower ();
  337. manager.SetName (instance, name);
  338. }
  339. return name;
  340. }
  341. protected object DeserializeExpression (IDesignerSerializationManager manager, string name, CodeExpression expression)
  342. {
  343. if (expression == null)
  344. throw new ArgumentNullException ("expression");
  345. if (manager == null)
  346. throw new ArgumentNullException ("manager");
  347. object deserialized = null;
  348. // CodeThisReferenceExpression
  349. //
  350. CodeThisReferenceExpression thisExpr = expression as CodeThisReferenceExpression;
  351. if (thisExpr != null) {
  352. RootContext context = manager.Context[typeof (RootContext)] as RootContext;
  353. if (context != null) {
  354. deserialized = context.Value;
  355. } else {
  356. IDesignerHost host = manager.GetService (typeof (IDesignerHost)) as IDesignerHost;
  357. if (host != null)
  358. deserialized = host.RootComponent;
  359. }
  360. }
  361. // CodeVariableReferenceExpression
  362. //
  363. CodeVariableReferenceExpression varRef = expression as CodeVariableReferenceExpression;
  364. if (deserialized == null && varRef != null) {
  365. deserialized = manager.GetInstance (varRef.VariableName);
  366. if (deserialized == null)
  367. _deserializationError = "Cannot find the value of the variable " + varRef.VariableName + "";
  368. }
  369. // CodeFieldReferenceExpression
  370. //
  371. CodeFieldReferenceExpression fieldRef = expression as CodeFieldReferenceExpression;
  372. if (deserialized == null && fieldRef != null) {
  373. deserialized = manager.GetInstance (fieldRef.FieldName);
  374. if (deserialized == null)
  375. _deserializationError = "Cannot find the value of the field " + fieldRef.FieldName + "";
  376. }
  377. // CodePrimitiveExpression
  378. //
  379. CodePrimitiveExpression primitiveExp = expression as CodePrimitiveExpression;
  380. if (deserialized == null && primitiveExp != null)
  381. deserialized = primitiveExp.Value;
  382. // CodePropertyReferenceExpression
  383. //
  384. CodePropertyReferenceExpression propRef = expression as CodePropertyReferenceExpression;
  385. if (deserialized == null && propRef != null) {
  386. object target = DeserializeExpression (manager, null, propRef.TargetObject);
  387. if (target != null) {
  388. bool found = false;
  389. if (target is Type) {
  390. PropertyInfo property = ((Type)target).GetProperty (propRef.PropertyName,
  391. BindingFlags.GetProperty |
  392. BindingFlags.Public | BindingFlags.Static);
  393. if (property != null) {
  394. deserialized = property.GetValue (null, null);
  395. found = true;
  396. }
  397. // NRefactory seems to produce PropertyReferences to reference some fields and enums
  398. //
  399. FieldInfo field = ((Type)target).GetField (propRef.PropertyName,
  400. BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
  401. if (field != null) {
  402. deserialized = field.GetValue (null);
  403. found = true;
  404. }
  405. } else {
  406. PropertyDescriptor property = TypeDescriptor.GetProperties (target)[propRef.PropertyName];
  407. if (property != null) {
  408. deserialized = property.GetValue (target);
  409. found = true;
  410. }
  411. FieldInfo field = target.GetType().GetField (propRef.PropertyName,
  412. BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
  413. if (field != null) {
  414. deserialized = field.GetValue (null);
  415. found = true;
  416. }
  417. }
  418. if (!found) {
  419. _deserializationError = "No property " + propRef.PropertyName + " found in type " +
  420. (target is Type ? ((Type)target).Name : target.GetType ().Name);
  421. _deserializationErrorTrace = "Property Name: " + propRef.PropertyName + System.Environment.NewLine +
  422. "Property is: " + (target is Type ? "static" : "instance") + System.Environment.NewLine +
  423. "Property Holder Type: " + (target is Type ? ((Type)target).Name : target.GetType ().Name) + System.Environment.NewLine +
  424. "Property Holder Expression Type: " + propRef.TargetObject.GetType ().Name + System.Environment.NewLine;
  425. }
  426. }
  427. }
  428. // CodeObjectCreateExpression
  429. //
  430. CodeObjectCreateExpression createExpr = expression as CodeObjectCreateExpression;
  431. if (deserialized == null && createExpr != null) {
  432. Type type = manager.GetType (createExpr.CreateType.BaseType);
  433. if (type == null) {
  434. _deserializationError = "Unable to find the type " + createExpr.CreateType.BaseType;
  435. } else {
  436. object[] arguments = new object[createExpr.Parameters.Count];
  437. for (int i=0; i < createExpr.Parameters.Count; i++) {
  438. arguments[i] = this.DeserializeExpression (manager, null, createExpr.Parameters[i]);
  439. if (_deserializationError != null) {
  440. _deserializationErrorTrace = "Type to create: " + createExpr.CreateType.BaseType + System.Environment.NewLine +
  441. "Parameter Number: " + i.ToString () + System.Environment.NewLine +
  442. "Parameter Expression Type: " + createExpr.Parameters[i].GetType ().Name + System.Environment.NewLine +
  443. "Parameters Count: " + createExpr.Parameters.Count + System.Environment.NewLine +
  444. _deserializationErrorTrace;
  445. break;
  446. }
  447. }
  448. if (_deserializationError == null) {
  449. bool addToContainer = false;
  450. if (typeof(IComponent).IsAssignableFrom (type))
  451. addToContainer = true;
  452. deserialized = this.DeserializeInstance (manager, type, arguments, name, addToContainer);
  453. if (deserialized == null) {
  454. _deserializationError = "Unable to create an instance of type " + createExpr.CreateType.BaseType;
  455. _deserializationErrorTrace = "Type to create: " + createExpr.CreateType.BaseType + System.Environment.NewLine +
  456. "Name: " + name + System.Environment.NewLine +
  457. "addToContainer: " + addToContainer.ToString () + System.Environment.NewLine +
  458. "Parameters Count: " + createExpr.Parameters.Count + System.Environment.NewLine;
  459. for (int i=0; i < arguments.Length; i++) {
  460. _deserializationErrorTrace += "Parameter Number: " + i.ToString () + System.Environment.NewLine +
  461. "Parameter Type: " + (arguments[i] == null ? "null" : arguments[i].GetType ().Name) +
  462. System.Environment.NewLine +
  463. "Parameter " + i.ToString () + " Value: " + arguments[i].ToString () + System.Environment.NewLine;
  464. }
  465. }
  466. }
  467. }
  468. }
  469. // CodeArrayCreateExpression
  470. //
  471. CodeArrayCreateExpression arrayCreateExpr = expression as CodeArrayCreateExpression;
  472. if (deserialized == null && arrayCreateExpr != null) {
  473. Type arrayType = manager.GetType (arrayCreateExpr.CreateType.BaseType);
  474. if (arrayType == null) {
  475. _deserializationError = "Unable to find the type " + arrayCreateExpr.CreateType.BaseType;
  476. } else {
  477. ArrayList initializers = new ArrayList ();
  478. Type elementType = arrayType.GetElementType ();
  479. deserialized = Array.CreateInstance (arrayType, arrayCreateExpr.Initializers.Count);
  480. for (int i = 0; i < arrayCreateExpr.Initializers.Count; i++) {
  481. object element = this.DeserializeExpression (manager, null, arrayCreateExpr.Initializers[i]);
  482. if (_deserializationError != null) {
  483. _deserializationErrorTrace = "Array Type: " + arrayType.Name + System.Environment.NewLine +
  484. "Array Element Type: " + elementType + System.Environment.NewLine +
  485. "Initializer Number: " + i.ToString () + System.Environment.NewLine +
  486. "Initializer Type: " + (element == null ? "null" : element.GetType ().Name) + System.Environment.NewLine +
  487. "Initialzer Value" + (element == null ? "null" : element.ToString ()) + System.Environment.NewLine +
  488. _deserializationErrorTrace;
  489. } else {
  490. if (arrayType.IsInstanceOfType (element)) {
  491. initializers.Add (element);
  492. } else {
  493. _deserializationError = "Array initializer of incompatible type detected.";
  494. _deserializationErrorTrace = "Array Type: " + arrayType.Name + System.Environment.NewLine +
  495. "Array Element Type: " + elementType + System.Environment.NewLine +
  496. "Initializer Type: " + (element == null ? "null" : element.GetType ().Name) + System.Environment.NewLine;
  497. }
  498. }
  499. }
  500. if (_deserializationError == null)
  501. initializers.CopyTo ((Array)deserialized, 0);
  502. else
  503. deserialized = null;
  504. }
  505. }
  506. // CodeMethodInvokeExpression
  507. //
  508. CodeMethodInvokeExpression methodExpr = expression as CodeMethodInvokeExpression;
  509. if (deserialized == null && methodExpr != null) {
  510. object target = this.DeserializeExpression (manager, null, methodExpr.Method.TargetObject);
  511. object[] parameters = new object[methodExpr.Parameters.Count];
  512. for (int i=0; i < methodExpr.Parameters.Count; i++) {
  513. parameters[i] = this.DeserializeExpression (manager, null, methodExpr.Parameters[i]);
  514. if (_deserializationError != null) {
  515. _deserializationErrorTrace =
  516. "Parameter Number: " + i.ToString () + System.Environment.NewLine +
  517. "Parameter Expression Type: " + methodExpr.Parameters[i].GetType ().Name + System.Environment.NewLine +
  518. _deserializationErrorTrace;
  519. break;
  520. }
  521. }
  522. if (_deserializationError == null) {
  523. MethodInfo method = null;
  524. if (target is Type) {
  525. method = GetExactMethod ((Type)target, methodExpr.Method.MethodName,
  526. BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
  527. parameters);
  528. } else {
  529. method = GetExactMethod (target.GetType(), methodExpr.Method.MethodName,
  530. BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
  531. parameters);
  532. }
  533. if (method != null) {
  534. deserialized = method.Invoke (target, parameters);
  535. } else {
  536. _deserializationError = "Unable to find a matching method " + methodExpr.Method.MethodName + " in type " +
  537. (target is Type ? ((Type)target).Name : target.GetType ().Name);
  538. for (int i = 0; i < parameters.Length; i++) {
  539. _deserializationErrorTrace += "Parameter Number: " + i.ToString () + System.Environment.NewLine +
  540. "Parameter Type: " + (parameters[i] == null ? "null" : parameters[i].GetType ().Name) +
  541. System.Environment.NewLine +
  542. "Parameter " + i.ToString () + " Value: " + parameters[i].ToString () + System.Environment.NewLine;
  543. }
  544. }
  545. if (_deserializationError != null) {
  546. _deserializationErrorTrace =
  547. "Method Name: " + methodExpr.Method.MethodName + System.Environment.NewLine +
  548. "Method is: " + (target is Type ? "static" : "instance") + System.Environment.NewLine +
  549. "Method Holder Type: " + (target is Type ? ((Type)target).Name : target.GetType ().Name) + System.Environment.NewLine +
  550. "Parameters Count: " + methodExpr.Parameters.Count + System.Environment.NewLine +
  551. _deserializationErrorTrace;
  552. }
  553. }
  554. }
  555. // CodeTypeReferenceExpression
  556. //
  557. CodeTypeReferenceExpression typeRef = expression as CodeTypeReferenceExpression;
  558. if (deserialized == null && typeRef != null) {
  559. deserialized = manager.GetType (typeRef.Type.BaseType);
  560. if (deserialized == null)
  561. _deserializationError = "Unable to find the type " + typeRef.Type.BaseType;
  562. }
  563. // CodeCastExpression
  564. //
  565. CodeCastExpression castExpr = expression as CodeCastExpression;
  566. if (deserialized == null && castExpr != null) {
  567. Type targetType = manager.GetType (castExpr.TargetType.BaseType);
  568. if (targetType == null)
  569. _deserializationError = "Unable to find the type " + castExpr.TargetType.BaseType;
  570. object instance = DeserializeExpression (manager, null, castExpr.Expression);
  571. if (instance != null && targetType != null) {
  572. IConvertible convertible = instance as IConvertible;
  573. if (convertible != null) {
  574. try {
  575. instance = convertible.ToType (targetType, null);
  576. } catch {
  577. _deserializationError = "Unable to convert type " + instance.GetType ().Name +
  578. " to type " + castExpr.TargetType.BaseType;
  579. }
  580. } else {
  581. _deserializationError = "Unable to convert type " + instance.GetType ().Name +
  582. " to type " + castExpr.TargetType.BaseType;
  583. }
  584. deserialized = instance;
  585. }
  586. if (_deserializationError != null) {
  587. _deserializationErrorTrace = "Target Type: " + castExpr.TargetType.BaseType + System.Environment.NewLine +
  588. "Instance Type: " + (instance == null ? "null" : instance.GetType ().Name) + System.Environment.NewLine +
  589. "Instance Value: " + (instance == null ? "null" : instance.ToString()) + System.Environment.NewLine +
  590. "Instance is IConvertible: " + (instance is IConvertible).ToString() + System.Environment.NewLine +
  591. _deserializationErrorTrace;
  592. }
  593. }
  594. // CodeBinaryOperatorExpression
  595. //
  596. CodeBinaryOperatorExpression binOperator = expression as CodeBinaryOperatorExpression;
  597. if (deserialized == null && binOperator != null) {
  598. IConvertible left = null;
  599. IConvertible right = null;
  600. switch (binOperator.Operator) {
  601. case CodeBinaryOperatorType.BitwiseOr:
  602. left = DeserializeExpression (manager, null, binOperator.Left) as IConvertible;
  603. right = DeserializeExpression (manager, null, binOperator.Right) as IConvertible;
  604. if (left is Enum && right is Enum)
  605. deserialized = Enum.ToObject (left.GetType (), Convert.ToInt64 (left) | Convert.ToInt64 (right));
  606. else
  607. _deserializationError = "CodeBinaryOperatorType.BitwiseOr only supported for Enum types";
  608. break;
  609. default:
  610. _deserializationError = "Unsupported CodeBinaryOperatorType: " + binOperator.Operator.ToString ();
  611. break;
  612. }
  613. if (_deserializationError != null) {
  614. _deserializationErrorTrace = "BinaryOperator Type: " + binOperator.Operator.ToString() + System.Environment.NewLine +
  615. "Left Type: " + (left == null ? "null" : left.GetType().Name) + System.Environment.NewLine +
  616. "Left Value: " + (left == null ? "null" : left.ToString ()) + System.Environment.NewLine +
  617. "Left Expression Type: " + binOperator.Left.GetType ().Name + System.Environment.NewLine +
  618. "Right Type: " + (right == null ? "null" : right.GetType().Name) + System.Environment.NewLine +
  619. "Right Value: " + (right == null ? "null" : right.ToString ()) + System.Environment.NewLine +
  620. "Right Expression Type: " + binOperator.Right.GetType ().Name + System.Environment.NewLine +
  621. _deserializationErrorTrace;
  622. }
  623. }
  624. if (_deserializationError != null) {
  625. _deserializationErrorTrace = "* DeserializeExpression (" + expression.GetType().Name + ")"
  626. + System.Environment.NewLine + _deserializationErrorTrace;
  627. } else {
  628. if (deserialized == null && !(expression is CodePrimitiveExpression) && !(expression is CodeMethodInvokeExpression))
  629. _deserializationError = "Unsupported Expression Type: " + expression.GetType ().Name;
  630. }
  631. return deserialized;
  632. }
  633. // Searches for a method on type that matches argument types
  634. //
  635. private MethodInfo GetExactMethod (Type type, string methodName, BindingFlags flags, ICollection argsCollection)
  636. {
  637. object[] arguments = null;
  638. Type[] types = new Type[0];
  639. if (argsCollection != null) {
  640. arguments = new object[argsCollection.Count];
  641. types = new Type[argsCollection.Count];
  642. argsCollection.CopyTo (arguments, 0);
  643. for (int i=0; i < arguments.Length; i++) {
  644. if (arguments[i] == null)
  645. types[i] = null;
  646. else
  647. types[i] = arguments[i].GetType ();
  648. }
  649. }
  650. return type.GetMethod (methodName, flags, null, types, null);
  651. }
  652. protected void DeserializeStatement (IDesignerSerializationManager manager, CodeStatement statement)
  653. {
  654. if (statement == null)
  655. throw new ArgumentNullException ("statement");
  656. if (manager == null)
  657. throw new ArgumentNullException ("manager");
  658. _deserializationErrorTrace = null;
  659. _deserializationError = null;
  660. // CodeAssignStatement
  661. //
  662. CodeAssignStatement assignment = statement as CodeAssignStatement;
  663. if (assignment != null)
  664. DeserializeAssignmentStatement (manager, assignment);
  665. // CodeExpressionStatement
  666. //
  667. CodeExpressionStatement expression = statement as CodeExpressionStatement;
  668. if (expression != null)
  669. this.DeserializeExpression (manager, null, expression.Expression);
  670. // CodeAttachEventStatement
  671. //
  672. CodeAttachEventStatement attachStatement = statement as CodeAttachEventStatement;
  673. if (attachStatement != null) {
  674. string methodName = null;
  675. CodeObjectCreateExpression createExpr = attachStatement.Listener as CodeObjectCreateExpression;
  676. if (createExpr != null && createExpr.Parameters.Count == 1 ) { // += new EventType (method)
  677. CodeMethodReferenceExpression handlerRef = createExpr.Parameters[0] as CodeMethodReferenceExpression;
  678. if (handlerRef != null)
  679. methodName = handlerRef.MethodName;
  680. }
  681. CodeDelegateCreateExpression delegateCreateExpr = attachStatement.Listener as CodeDelegateCreateExpression;
  682. if (delegateCreateExpr != null)// += new EventType (method)
  683. methodName = delegateCreateExpr.MethodName;
  684. CodeMethodReferenceExpression methodRef = attachStatement.Listener as CodeMethodReferenceExpression;
  685. if (methodRef != null) // += method
  686. methodName = methodRef.MethodName;
  687. object component = DeserializeExpression (manager, null, attachStatement.Event.TargetObject);
  688. if (component != null && methodName != null) {
  689. EventDescriptor eventDescriptor = TypeDescriptor.GetEvents (component)[attachStatement.Event.EventName];
  690. if (eventDescriptor != null) {
  691. IEventBindingService service = manager.GetService (typeof (IEventBindingService)) as IEventBindingService;
  692. if (service != null)
  693. service.GetEventProperty (eventDescriptor).SetValue (component, methodName);
  694. else
  695. _deserializationError = "IEventBindingService missing.";
  696. } else {
  697. _deserializationError = "No event " + attachStatement.Event.EventName +
  698. " found in type " + component.GetType ().Name;
  699. }
  700. }
  701. if (_deserializationError != null) {
  702. _deserializationErrorTrace = "Method Name: " + methodName + System.Environment.NewLine +
  703. "Event Name: " + attachStatement.Event.EventName + System.Environment.NewLine +
  704. "Listener Expression Type: " + methodRef.GetType ().Name + System.Environment.NewLine +
  705. "Event Holder Type: " + component.GetType ().Name + System.Environment.NewLine +
  706. "Event Holder Expression Type: " + attachStatement.Event.TargetObject.GetType ().Name + System.Environment.NewLine;
  707. }
  708. }
  709. if (_deserializationErrorTrace != null) {
  710. _deserializationErrorTrace = "* DeserializeStatement (" + statement.GetType().Name + ")"
  711. + System.Environment.NewLine + _deserializationErrorTrace;
  712. ReportError (manager, _deserializationError, _deserializationErrorTrace);
  713. _deserializationErrorTrace = null;
  714. _deserializationError = null;
  715. }
  716. }
  717. private void DeserializeAssignmentStatement (IDesignerSerializationManager manager, CodeAssignStatement statement)
  718. {
  719. CodeExpression leftExpr = statement.Left;
  720. // Assign to a Property
  721. //
  722. CodePropertyReferenceExpression propRef = leftExpr as CodePropertyReferenceExpression;
  723. if (propRef != null) {
  724. object propertyHolder = DeserializeExpression (manager, null, propRef.TargetObject);
  725. object value = null;
  726. if (_deserializationError == null)
  727. value = DeserializeExpression (manager, null, statement.Right);
  728. if (_deserializationError == null && propertyHolder != null) {
  729. PropertyDescriptor property = TypeDescriptor.GetProperties (propertyHolder)[propRef.PropertyName];
  730. if (property != null) {
  731. property.SetValue (propertyHolder, value);
  732. } else {
  733. _deserializationError = "No property " + propRef.PropertyName + " found in type " + propertyHolder.GetType ().Name;
  734. _deserializationErrorTrace = "Property Name: " + propRef.PropertyName + System.Environment.NewLine +
  735. "Property Value: " + (value == null ? "null" : value.ToString()) + System.Environment.NewLine +
  736. "Property Type: " + propertyHolder.GetType ().Name + System.Environment.NewLine +
  737. "Property Holder Expression Type: " + propRef.TargetObject.GetType ().Name + System.Environment.NewLine;
  738. }
  739. }
  740. }
  741. // Assign to a Field
  742. //
  743. CodeFieldReferenceExpression fieldRef = leftExpr as CodeFieldReferenceExpression;
  744. if (fieldRef != null && fieldRef.FieldName != null) {
  745. // Note that if the Right expression is a CodeCreationExpression the component will be created in this call
  746. //
  747. object fieldHolder = DeserializeExpression (manager, null, fieldRef.TargetObject);
  748. object value = null;
  749. if (_deserializationError == null)
  750. value = DeserializeExpression (manager, fieldRef.FieldName, statement.Right);
  751. FieldInfo field = null;
  752. RootContext context = manager.Context[typeof (RootContext)] as RootContext;
  753. if (_deserializationError == null && fieldHolder != null) {
  754. if (fieldRef.TargetObject is CodeThisReferenceExpression && context != null && context.Value == fieldHolder) {
  755. // Do not deserialize the fields of the root component, because the root component type
  756. // is actually an instance of the its parent type, e.g: CustomControl : _UserControl_
  757. // and thus it doesn't contain the fields. The trick is that once DeserializeExpression
  758. // is called on a CodeObjectCreateExpression the component is created and is added to the name-instance
  759. // table.
  760. //
  761. } else {
  762. if (fieldHolder is Type) // static field
  763. field = ((Type)fieldHolder).GetField (fieldRef.FieldName,
  764. BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
  765. else // instance field
  766. field = fieldHolder.GetType().GetField (fieldRef.FieldName,
  767. BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
  768. if (field != null)
  769. field.SetValue (fieldHolder, value);
  770. else {
  771. _deserializationError = "No field " + fieldRef.FieldName + " found in type " + fieldHolder.GetType ().Name;
  772. _deserializationErrorTrace = "Field Name: " + fieldRef.FieldName + System.Environment.NewLine +
  773. "Field is: " + (fieldHolder is Type ? "static" : "instance") + System.Environment.NewLine +
  774. "Field Value: " + (value == null ? "null" : value.ToString()) + System.Environment.NewLine +
  775. "Field Holder Type: " + fieldHolder.GetType ().Name + System.Environment.NewLine +
  776. "Field Holder Expression Type: " + fieldRef.TargetObject.GetType ().Name + System.Environment.NewLine;
  777. }
  778. }
  779. }
  780. }
  781. if (_deserializationError != null) {
  782. _deserializationErrorTrace = "* DeserializeAssignStatement" + System.Environment.NewLine +
  783. "Left Expression Type: " + statement.Left.GetType().Name + System.Environment.NewLine +
  784. "Right Expression Type: " + statement.Right.GetType().Name + System.Environment.NewLine +
  785. _deserializationErrorTrace;
  786. }
  787. }
  788. internal void ReportError (IDesignerSerializationManager manager, string message)
  789. {
  790. this.ReportError (manager, message, "");
  791. }
  792. internal void ReportError (IDesignerSerializationManager manager, string message, string details)
  793. {
  794. try {
  795. throw new Exception (message);
  796. } catch (Exception e) {
  797. e.Data["Details"] = message + Environment.NewLine + Environment.NewLine + details;
  798. manager.ReportError (e);
  799. }
  800. }
  801. #region Resource Serialization - TODO
  802. protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value)
  803. {
  804. throw new NotImplementedException ();
  805. }
  806. protected CodeExpression SerializeToResourceExpression (IDesignerSerializationManager manager, object value, bool ensureInvariant)
  807. {
  808. throw new NotImplementedException ();
  809. }
  810. protected void SerializePropertiesToResources (IDesignerSerializationManager manager, CodeStatementCollection statements,
  811. object value, Attribute[] filter)
  812. {
  813. throw new NotImplementedException ();
  814. }
  815. protected void SerializeResource (IDesignerSerializationManager manager, string resourceName, object value)
  816. {
  817. throw new NotImplementedException ();
  818. }
  819. protected void SerializeResourceInvariant (IDesignerSerializationManager manager, string resourceName, object value)
  820. {
  821. throw new NotImplementedException ();
  822. }
  823. protected void DeserializePropertiesFromResources (IDesignerSerializationManager manager, object value, Attribute[] filter)
  824. {
  825. throw new NotImplementedException ();
  826. }
  827. #endregion
  828. }
  829. }
  830. #endif