PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/DICK.B1/IronPython/Runtime/Operations/CustomTypeDescHelpers.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 267 lines | 198 code | 45 blank | 24 comment | 38 complexity | ff3abd2049325baeb2a54e04391747ba MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if !SILVERLIGHT // ICustomTypeDescriptor
  16. using System;
  17. using System.Collections.Generic;
  18. using System.ComponentModel;
  19. using IronPython.Runtime.Types;
  20. using Microsoft.Scripting;
  21. using Microsoft.Scripting.Actions.Calls;
  22. namespace IronPython.Runtime.Operations {
  23. /// <summary>
  24. /// Helper class that all custom type descriptor implementations call for
  25. /// the bulk of their implementation.
  26. /// </summary>
  27. public static class CustomTypeDescHelpers {
  28. #region ICustomTypeDescriptor helper functions
  29. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "self")]
  30. public static AttributeCollection GetAttributes(object self) {
  31. return AttributeCollection.Empty;
  32. }
  33. public static string GetClassName(object self) {
  34. object cls;
  35. if (PythonOps.TryGetBoundAttr(DefaultContext.DefaultCLS, self, "__class__", out cls)) {
  36. return PythonOps.GetBoundAttr(DefaultContext.DefaultCLS, cls, "__name__").ToString();
  37. }
  38. return null;
  39. }
  40. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "self")]
  41. public static string GetComponentName(object self) {
  42. return null;
  43. }
  44. public static TypeConverter GetConverter(object self) {
  45. return new TypeConv(self);
  46. }
  47. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "self")]
  48. public static EventDescriptor GetDefaultEvent(object self) {
  49. return null;
  50. }
  51. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "self")]
  52. public static PropertyDescriptor GetDefaultProperty(object self) {
  53. return null;
  54. }
  55. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "self"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "editorBaseType")]
  56. public static object GetEditor(object self, Type editorBaseType) {
  57. return null;
  58. }
  59. public static EventDescriptorCollection GetEvents(object self, Attribute[] attributes) {
  60. if (attributes == null || attributes.Length == 0) return GetEvents(self);
  61. //!!! update when we support attributes on python types
  62. // you want things w/ attributes? we don't have attributes!
  63. return EventDescriptorCollection.Empty;
  64. }
  65. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "self")]
  66. public static EventDescriptorCollection GetEvents(object self) {
  67. return EventDescriptorCollection.Empty;
  68. }
  69. public static PropertyDescriptorCollection GetProperties(object self) {
  70. return new PropertyDescriptorCollection(GetPropertiesImpl(self, new Attribute[0]));
  71. }
  72. public static PropertyDescriptorCollection GetProperties(object self, Attribute[] attributes) {
  73. return new PropertyDescriptorCollection(GetPropertiesImpl(self, attributes));
  74. }
  75. static PropertyDescriptor[] GetPropertiesImpl(object self, Attribute[] attributes) {
  76. IList<object> attrNames = PythonOps.GetAttrNames(DefaultContext.DefaultCLS, self);
  77. List<PropertyDescriptor> descrs = new List<PropertyDescriptor>();
  78. if (attrNames != null) {
  79. foreach (object o in attrNames) {
  80. string s = o as string;
  81. if (s == null) continue;
  82. PythonTypeSlot attrSlot = null;
  83. object attrVal;
  84. if (self is OldInstance) {
  85. if (((OldInstance)self)._class.TryLookupSlot(s, out attrVal)) {
  86. attrSlot = attrVal as PythonTypeSlot;
  87. } else if (!((OldInstance)self).Dictionary.TryGetValue(s, out attrVal)) {
  88. attrVal = ObjectOps.__getattribute__(DefaultContext.DefaultCLS, self, s);
  89. }
  90. } else {
  91. PythonType dt = DynamicHelpers.GetPythonType(self);
  92. dt.TryResolveSlot(DefaultContext.DefaultCLS, s, out attrSlot);
  93. attrVal = ObjectOps.__getattribute__(DefaultContext.DefaultCLS, self, s);
  94. }
  95. Type attrType = (attrVal == null) ? typeof(NoneTypeOps) : attrVal.GetType();
  96. if ((attrSlot != null && ShouldIncludeProperty(attrSlot, attributes)) ||
  97. (attrSlot == null && ShouldIncludeInstanceMember(s, attributes))) {
  98. descrs.Add(new SuperDynamicObjectPropertyDescriptor(s, attrType, self.GetType()));
  99. }
  100. }
  101. }
  102. return descrs.ToArray();
  103. }
  104. private static bool ShouldIncludeInstanceMember(string memberName, Attribute[] attributes) {
  105. bool include = true;
  106. foreach (Attribute attr in attributes) {
  107. if (attr.GetType() == typeof(BrowsableAttribute)) {
  108. if (memberName.StartsWith("__") && memberName.EndsWith("__")) {
  109. include = false;
  110. }
  111. } else {
  112. // unknown attribute, Python doesn't support attributes, so we
  113. // say this doesn't have that attribute.
  114. include = false;
  115. }
  116. }
  117. return include;
  118. }
  119. private static bool ShouldIncludeProperty(PythonTypeSlot attrSlot, Attribute[] attributes) {
  120. bool include = true;
  121. foreach (Attribute attr in attributes) {
  122. ReflectedProperty rp;
  123. if ((rp = attrSlot as ReflectedProperty) != null && rp.Info != null) {
  124. include &= rp.Info.IsDefined(attr.GetType(), true);
  125. } else if (attr.GetType() == typeof(BrowsableAttribute)) {
  126. PythonTypeUserDescriptorSlot userSlot = attrSlot as PythonTypeUserDescriptorSlot;
  127. if (userSlot == null) {
  128. if (!(attrSlot is PythonProperty)) {
  129. include = false;
  130. }
  131. } else if (!(userSlot.Value is IPythonObject)) {
  132. include = false;
  133. }
  134. } else {
  135. // unknown attribute, Python doesn't support attributes, so we
  136. // say this doesn't have that attribute.
  137. include = false;
  138. }
  139. }
  140. return include;
  141. }
  142. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "pd")]
  143. public static object GetPropertyOwner(object self, PropertyDescriptor pd) {
  144. return self;
  145. }
  146. #endregion
  147. class SuperDynamicObjectPropertyDescriptor : PropertyDescriptor {
  148. string _name;
  149. Type _propertyType;
  150. Type _componentType;
  151. internal SuperDynamicObjectPropertyDescriptor(
  152. string name,
  153. Type propertyType,
  154. Type componentType)
  155. : base(name, null) {
  156. _name = name;
  157. _propertyType = propertyType;
  158. _componentType = componentType;
  159. }
  160. public override object GetValue(object component) {
  161. return PythonOps.GetBoundAttr(DefaultContext.DefaultCLS, component, _name);
  162. }
  163. public override void SetValue(object component, object value) {
  164. PythonOps.SetAttr(DefaultContext.DefaultCLS, component, _name, value);
  165. }
  166. public override bool CanResetValue(object component) {
  167. return true;
  168. }
  169. public override Type ComponentType {
  170. get { return _componentType; }
  171. }
  172. public override bool IsReadOnly {
  173. get { return false; }
  174. }
  175. public override Type PropertyType {
  176. get { return _propertyType; }
  177. }
  178. public override void ResetValue(object component) {
  179. PythonOps.DeleteAttr(DefaultContext.DefaultCLS, component, _name);
  180. }
  181. public override bool ShouldSerializeValue(object component) {
  182. object o;
  183. return PythonOps.TryGetBoundAttr(component, _name, out o);
  184. }
  185. }
  186. private class TypeConv : TypeConverter {
  187. object convObj;
  188. public TypeConv(object self) {
  189. convObj = self;
  190. }
  191. #region TypeConverter overrides
  192. public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
  193. object result;
  194. return Converter.TryConvert(convObj, destinationType, out result);
  195. }
  196. public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
  197. return Converter.CanConvertFrom(sourceType, convObj.GetType(), NarrowingLevel.All);
  198. }
  199. public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) {
  200. return Converter.Convert(value, convObj.GetType());
  201. }
  202. public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) {
  203. return Converter.Convert(convObj, destinationType);
  204. }
  205. public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) {
  206. return false;
  207. }
  208. public override bool GetPropertiesSupported(ITypeDescriptorContext context) {
  209. return false;
  210. }
  211. public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
  212. return false;
  213. }
  214. public override bool IsValid(ITypeDescriptorContext context, object value) {
  215. object result;
  216. return Converter.TryConvert(value, convObj.GetType(), out result);
  217. }
  218. #endregion
  219. }
  220. }
  221. }
  222. #endif