PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/IronPython_Main/Languages/IronPython/IronPython/Runtime/Types/ReflectedIndexer.cs

#
C# | 109 lines | 70 code | 17 blank | 22 comment | 2 complexity | dbed0cb1ffab5e8fe98cb0273c3742d3 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. 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 Apache License, Version 2.0, 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 Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System;
  16. using System.Diagnostics;
  17. using System.Reflection;
  18. using System.Runtime.CompilerServices;
  19. using IronPython.Runtime.Operations;
  20. using Microsoft.Scripting;
  21. using Microsoft.Scripting.Generation;
  22. using Microsoft.Scripting.Runtime;
  23. using Microsoft.Scripting.Utils;
  24. namespace IronPython.Runtime.Types {
  25. /// <summary>
  26. /// Provides access to non-default .NET indexers (aka properties w/ parameters).
  27. ///
  28. /// C# doesn't support these, but both COM and VB.NET do. The types dictionary
  29. /// gets populated w/a ReflectedGetterSetter indexer which is a descriptor. Getting
  30. /// the descriptor returns a bound indexer. The bound indexer supports indexing.
  31. /// We support multiple indexer parameters via expandable tuples.
  32. /// </summary>
  33. [PythonType("indexer#")]
  34. public sealed class ReflectedIndexer : ReflectedGetterSetter {
  35. private readonly object _instance;
  36. private readonly PropertyInfo/*!*/ _info;
  37. public ReflectedIndexer(PropertyInfo/*!*/ info, NameType nt, bool privateBinding)
  38. : base(new MethodInfo[] { info.GetGetMethod(privateBinding) }, new MethodInfo[] { info.GetSetMethod(privateBinding) }, nt) {
  39. Debug.Assert(info != null);
  40. _info = info;
  41. }
  42. public ReflectedIndexer(ReflectedIndexer from, object instance)
  43. : base(from) {
  44. _instance = instance;
  45. _info = from._info;
  46. }
  47. internal override bool TryGetValue(CodeContext context, object instance, PythonType owner, out object value) {
  48. value = new ReflectedIndexer(this, instance);
  49. return true;
  50. }
  51. internal override bool GetAlwaysSucceeds {
  52. get {
  53. return true;
  54. }
  55. }
  56. internal override Type DeclaringType {
  57. get { return _info.DeclaringType; }
  58. }
  59. public override PythonType PropertyType {
  60. [PythonHidden]
  61. get {
  62. return DynamicHelpers.GetPythonTypeFromType(_info.PropertyType);
  63. }
  64. }
  65. public override string __name__ {
  66. get { return _info.Name; }
  67. }
  68. #region Public APIs
  69. public bool SetValue(CodeContext context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object[], object>>> storage, object[] keys, object value) {
  70. return CallSetter(context, storage, _instance, keys, value);
  71. }
  72. public object GetValue(CodeContext context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object[], object>>> storage, object[] keys) {
  73. return CallGetter(context, storage, _instance, keys);
  74. }
  75. public new object __get__(CodeContext context, object instance, object owner) {
  76. object val;
  77. TryGetValue(context, instance, owner as PythonType, out val);
  78. return val;
  79. }
  80. public object this[SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object[], object>>> storage, params object[] key] {
  81. get {
  82. return GetValue(DefaultContext.Default, storage, key);
  83. }
  84. set {
  85. if (!SetValue(DefaultContext.Default, storage, key, value)) {
  86. throw PythonOps.AttributeErrorForReadonlyAttribute(DeclaringType.Name, __name__);
  87. }
  88. }
  89. }
  90. #endregion
  91. }
  92. }