PageRenderTime 12ms CodeModel.GetById 1ms app.highlight 7ms RepoModel.GetById 1ms 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
  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
 16using System;
 17using System.Diagnostics;
 18using System.Reflection;
 19using System.Runtime.CompilerServices;
 20using IronPython.Runtime.Operations;
 21using Microsoft.Scripting;
 22using Microsoft.Scripting.Generation;
 23using Microsoft.Scripting.Runtime;
 24using Microsoft.Scripting.Utils;
 25
 26namespace IronPython.Runtime.Types {
 27    /// <summary>
 28    /// Provides access to non-default .NET indexers (aka properties w/ parameters).
 29    /// 
 30    /// C# doesn't support these, but both COM and VB.NET do.  The types dictionary
 31    /// gets populated w/a ReflectedGetterSetter indexer which is a descriptor.  Getting
 32    /// the descriptor returns a bound indexer.  The bound indexer supports indexing.
 33    /// We support multiple indexer parameters via expandable tuples.
 34    /// </summary>
 35    [PythonType("indexer#")]
 36    public sealed class ReflectedIndexer : ReflectedGetterSetter {
 37        private readonly object _instance;
 38        private readonly PropertyInfo/*!*/ _info;
 39
 40        public ReflectedIndexer(PropertyInfo/*!*/ info, NameType nt, bool privateBinding)
 41            : base(new MethodInfo[] { info.GetGetMethod(privateBinding) }, new MethodInfo[] { info.GetSetMethod(privateBinding) }, nt) {
 42            Debug.Assert(info != null);
 43            
 44            _info = info;
 45        }
 46
 47        public ReflectedIndexer(ReflectedIndexer from, object instance)
 48            : base(from) {
 49            _instance = instance;
 50            _info = from._info;
 51        }
 52
 53        internal override bool TryGetValue(CodeContext context, object instance, PythonType owner, out object value) {
 54            value = new ReflectedIndexer(this, instance);
 55            return true;
 56        }
 57
 58        internal override bool GetAlwaysSucceeds {
 59            get {
 60                return true;
 61            }
 62        }
 63
 64        internal override Type DeclaringType {
 65            get { return _info.DeclaringType; }
 66        }
 67
 68        public override PythonType PropertyType {
 69            [PythonHidden]
 70            get {
 71                return DynamicHelpers.GetPythonTypeFromType(_info.PropertyType);
 72            }
 73        }
 74
 75        public override string __name__ {
 76            get { return _info.Name; }
 77        }
 78
 79        #region Public APIs
 80
 81        public bool SetValue(CodeContext context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object[], object>>> storage, object[] keys, object value) {
 82            return CallSetter(context, storage, _instance, keys, value);
 83        }
 84
 85        public object GetValue(CodeContext context, SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object[], object>>> storage, object[] keys) {
 86            return CallGetter(context, storage, _instance, keys);
 87        }
 88
 89        public new object __get__(CodeContext context, object instance, object owner) {
 90            object val;
 91            TryGetValue(context, instance, owner as PythonType, out val);
 92            return val;
 93        }
 94
 95        public object this[SiteLocalStorage<CallSite<Func<CallSite, CodeContext, object, object[], object>>> storage, params object[] key] {
 96            get {
 97                return GetValue(DefaultContext.Default, storage, key);
 98            }
 99            set {
100                if (!SetValue(DefaultContext.Default, storage, key, value)) {
101                    throw PythonOps.AttributeErrorForReadonlyAttribute(DeclaringType.Name, __name__);
102                }
103            }
104        }
105
106        #endregion
107    }
108
109}