/* * Copyright © 2011, Petro Protsyk, Denys Vuika * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using Microsoft.CSharp.RuntimeBinder; namespace Scripting.SSharp.Runtime { /// /// Provides creation and caching mechanisms for dynamic object members. /// internal static class CallSiteCache { private static readonly CSharpArgumentInfo[] GetterArgumentInfo = new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }; private static readonly CSharpArgumentInfo[] SetterArgumentInfo = new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }; private static readonly Dictionary>> GettersCache = new Dictionary>>(); private static readonly Dictionary>> SettersCache = new Dictionary>>(); private static CallSite> CreateGetter(string propertyName) { var getter = CallSite>.Create( Binder.GetMember(CSharpBinderFlags.None, propertyName, typeof(CallSiteCache), GetterArgumentInfo)); return getter; } private static CallSite> CreateSetter(string propertyName) { var setter = CallSite>.Create( Binder.SetMember(CSharpBinderFlags.None, propertyName, typeof(CallSiteCache), SetterArgumentInfo)); return setter; } //getter.Target.Invoke(getter, obj); public static CallSite> GetOrCreatePropertyGetter(string propertyName) { if (string.IsNullOrWhiteSpace(propertyName)) throw new ArgumentNullException("propertyName"); CallSite> getter; if (GettersCache.TryGetValue(propertyName, out getter)) return getter; getter = CreateGetter(propertyName); GettersCache.Add(propertyName, getter); return getter; } // site.Target(site, o, value); public static CallSite> GetOrCreatePropertySetter(string propertyName) { if (string.IsNullOrWhiteSpace(propertyName)) throw new ArgumentNullException("propertyName"); CallSite> setter; if (SettersCache.TryGetValue(propertyName, out setter)) return setter; setter = CreateSetter(propertyName); SettersCache.Add(propertyName, setter); return setter; } } }