PageRenderTime 57ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/DICK.B1/IronPython/Runtime/Types/CustomAttributeTracker.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 221 lines | 166 code | 36 blank | 19 comment | 9 complexity | 850f98d73e2598d906cfe2f2159dc760 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 !CLR2
  16. using System.Linq.Expressions;
  17. #else
  18. using Microsoft.Scripting.Ast;
  19. #endif
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Diagnostics;
  23. using System.Dynamic;
  24. using System.Reflection;
  25. using Microsoft.Scripting;
  26. using Microsoft.Scripting.Actions;
  27. using Microsoft.Scripting.Actions.Calls;
  28. using IronPython.Runtime.Binding;
  29. using IronPython.Runtime.Operations;
  30. namespace IronPython.Runtime.Types {
  31. using Ast = Expression;
  32. using AstUtils = Microsoft.Scripting.Ast.Utils;
  33. public abstract class PythonCustomTracker : CustomTracker {
  34. public abstract PythonTypeSlot/*!*/ GetSlot();
  35. public override DynamicMetaObject GetValue(OverloadResolverFactory resolverFactory, ActionBinder binder, Type type) {
  36. return new DynamicMetaObject(AstUtils.Constant(GetSlot(), typeof(PythonTypeSlot)), BindingRestrictions.Empty);
  37. }
  38. public override MemberTracker BindToInstance(DynamicMetaObject instance) {
  39. return new BoundMemberTracker(this, instance);
  40. }
  41. public override DynamicMetaObject SetValue(OverloadResolverFactory resolverFactory, ActionBinder binder, Type type, DynamicMetaObject value) {
  42. return SetBoundValue(resolverFactory, binder, type, value, new DynamicMetaObject(AstUtils.Constant(null), BindingRestrictions.Empty));
  43. }
  44. protected override DynamicMetaObject GetBoundValue(OverloadResolverFactory factory, ActionBinder binder, Type type, DynamicMetaObject instance) {
  45. return new DynamicMetaObject(
  46. Ast.Call(
  47. typeof(PythonOps).GetMethod("SlotGetValue"),
  48. ((PythonOverloadResolverFactory)factory)._codeContext,
  49. AstUtils.Constant(GetSlot(), typeof(PythonTypeSlot)),
  50. AstUtils.Convert(
  51. instance.Expression,
  52. typeof(object)
  53. ),
  54. AstUtils.Constant(DynamicHelpers.GetPythonTypeFromType(type))
  55. ),
  56. BindingRestrictions.Empty
  57. );
  58. }
  59. protected override DynamicMetaObject SetBoundValue(OverloadResolverFactory factory, ActionBinder binder, Type type, DynamicMetaObject value, DynamicMetaObject instance) {
  60. return new DynamicMetaObject(
  61. Ast.Call(
  62. typeof(PythonOps).GetMethod("SlotSetValue"),
  63. ((PythonOverloadResolverFactory)factory)._codeContext,
  64. AstUtils.Constant(GetSlot(), typeof(PythonTypeSlot)),
  65. AstUtils.Convert(
  66. instance.Expression,
  67. typeof(object)
  68. ),
  69. AstUtils.Constant(DynamicHelpers.GetPythonTypeFromType(type)),
  70. value.Expression
  71. ),
  72. BindingRestrictions.Empty
  73. );
  74. }
  75. }
  76. /// <summary>
  77. /// Provides a CustomTracker which handles special fields which have custom
  78. /// behavior on get/set.
  79. /// </summary>
  80. class CustomAttributeTracker : PythonCustomTracker {
  81. private readonly PythonTypeSlot/*!*/ _slot;
  82. private readonly Type/*!*/ _declType;
  83. private readonly string/*!*/ _name;
  84. public CustomAttributeTracker(Type/*!*/ declaringType, string/*!*/ name, PythonTypeSlot/*!*/ slot) {
  85. Debug.Assert(slot != null);
  86. Debug.Assert(declaringType != null);
  87. Debug.Assert(name != null);
  88. _declType = declaringType;
  89. _name = name;
  90. _slot = slot;
  91. }
  92. public override DynamicMetaObject GetValue(OverloadResolverFactory factory, ActionBinder binder, Type type) {
  93. return GetBoundValue(factory, binder, type, new DynamicMetaObject(AstUtils.Constant(null), BindingRestrictions.Empty));
  94. }
  95. public override string Name {
  96. get { return _name; }
  97. }
  98. public override Type DeclaringType {
  99. get {
  100. return _declType;
  101. }
  102. }
  103. public override PythonTypeSlot/*!*/ GetSlot() {
  104. return _slot;
  105. }
  106. }
  107. class ClassMethodTracker : PythonCustomTracker {
  108. private MethodTracker/*!*/[]/*!*/ _trackers;
  109. public ClassMethodTracker(MemberGroup/*!*/ group) {
  110. List<MethodTracker> trackers = new List<MethodTracker>(group.Count);
  111. foreach (MethodTracker mt in group) {
  112. trackers.Add(mt);
  113. }
  114. _trackers = trackers.ToArray();
  115. }
  116. public override PythonTypeSlot GetSlot() {
  117. List<MethodBase> meths = new List<MethodBase>();
  118. foreach (MethodTracker mt in _trackers) {
  119. meths.Add(mt.Method);
  120. }
  121. return PythonTypeOps.GetFinalSlotForFunction(
  122. PythonTypeOps.GetBuiltinFunction(DeclaringType,
  123. Name,
  124. meths.ToArray()
  125. )
  126. );
  127. }
  128. public override DynamicMetaObject GetValue(OverloadResolverFactory factory, ActionBinder binder, Type type) {
  129. return GetBoundValue(factory, binder, type, new DynamicMetaObject(AstUtils.Constant(null), BindingRestrictions.Empty));
  130. }
  131. public override Type DeclaringType {
  132. get { return _trackers[0].DeclaringType; }
  133. }
  134. public override string Name {
  135. get { return _trackers[0].Name; }
  136. }
  137. }
  138. class OperatorTracker : PythonCustomTracker {
  139. private MethodTracker/*!*/[]/*!*/ _trackers;
  140. private bool _reversed;
  141. private string/*!*/ _name;
  142. private Type/*!*/ _declType;
  143. public OperatorTracker(Type/*!*/ declaringType, string/*!*/ name, bool reversed, params MethodTracker/*!*/[]/*!*/ members) {
  144. Debug.Assert(declaringType != null);
  145. Debug.Assert(members != null);
  146. Debug.Assert(name != null);
  147. Debug.Assert(members.Length > 0);
  148. _declType = declaringType;
  149. _reversed = reversed;
  150. _trackers = members;
  151. _name = name;
  152. }
  153. public override PythonTypeSlot/*!*/ GetSlot() {
  154. List<MethodBase> meths = new List<MethodBase>();
  155. foreach (MethodTracker mt in _trackers) {
  156. meths.Add(mt.Method);
  157. }
  158. MethodBase[] methods = meths.ToArray();
  159. FunctionType ft = (PythonTypeOps.GetMethodFunctionType(DeclaringType, methods) | FunctionType.Method) & (~FunctionType.Function);
  160. if (_reversed) {
  161. ft |= FunctionType.ReversedOperator;
  162. } else {
  163. ft &= ~FunctionType.ReversedOperator;
  164. }
  165. // check if this operator is only availble after importing CLR (e.g. __getitem__ on functions)
  166. foreach (MethodInfo mi in methods) {
  167. if (!mi.IsDefined(typeof(PythonHiddenAttribute), false)) {
  168. ft |= FunctionType.AlwaysVisible;
  169. break;
  170. }
  171. }
  172. return PythonTypeOps.GetFinalSlotForFunction(PythonTypeOps.GetBuiltinFunction(DeclaringType,
  173. Name,
  174. ft,
  175. meths.ToArray()
  176. ));
  177. }
  178. public override Type DeclaringType {
  179. get { return _declType; }
  180. }
  181. public override string Name {
  182. get { return _name; }
  183. }
  184. }
  185. }