/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Scripting.Actions; namespace System.Dynamic { public class DynamicObject : IDynamicObject { public virtual object GetMember(GetMemberAction info) { throw new MissingMemberException("Dynamic", info.Name); } public virtual void SetMember(SetMemberAction info, object value) { throw new MissingMemberException("Dynamic", info.Name); } public virtual object Invoke(InvokeAction info, object[] arguments) { throw new NotImplementedException("Invoke"); } public virtual object InvokeMember(CallAction info, object[] arguments) { throw new NotImplementedException("InvokeMember"); } public MetaObject GetMetaObject(Expression parameter) { return new DynamicMetaObject(this, parameter); } class DynamicMetaObject : MetaObject { public DynamicMetaObject(DynamicObject v, Expression e) : base(e, Restrictions.Empty, v) { } public override MetaObject GetMember(GetMemberAction info, MetaObject[] args) { var x = this.Expression; var test = Expression.TypeIs(x, typeof(DynamicObject)); var target = Expression.Call( Expression.Convert(x, typeof(DynamicObject)), typeof(DynamicObject).GetMethod("GetMember"), Expression.Constant(info)); return new MetaObject(target, Restrictions.ExpressionRestriction(test)); } public override MetaObject SetMember(SetMemberAction info, MetaObject[] args) { var x = this.Expression; var y = args[1].Expression; var test = Expression.TypeIs(x, typeof(DynamicObject)); var target = Expression.Call( Expression.Convert(x, typeof(DynamicObject)), typeof(DynamicObject).GetMethod("SetMember"), Expression.Constant(info), Expression.ConvertHelper(y, typeof(object))); return new MetaObject(target, Restrictions.ExpressionRestriction(test)); } public override MetaObject Invoke(InvokeAction action, MetaObject[] args) { var x = this.Expression; var test = Expression.TypeIs(x, typeof(DynamicObject)); var inits = new Expression[args.Length - 1]; for (int i = 0; i < inits.Length; i++) { inits[i] = Expression.ConvertHelper(args[i + 1].Expression, typeof(object)); } var argsArray = Expression.NewArrayHelper(typeof(object), inits); var target = Expression.Call( Expression.Convert(x, typeof(DynamicObject)), typeof(DynamicObject).GetMethod("Invoke"), Expression.Constant(action), argsArray); return new MetaObject(target, Restrictions.ExpressionRestriction(test)); } public override MetaObject Call(CallAction action, MetaObject[] args) { var x = this.Expression; var test = Expression.TypeIs(x, typeof(DynamicObject)); var inits = new Expression[args.Length - 1]; for (int i = 0; i < inits.Length; i++) { inits[i] = Expression.ConvertHelper(args[i + 1].Expression, typeof(object)); } var argsArray = Expression.NewArrayHelper(typeof(object), inits); var target = Expression.Call( Expression.Convert(x, typeof(DynamicObject)), typeof(DynamicObject).GetMethod("InvokeMember"), Expression.Constant(action), argsArray); return new MetaObject(target, Restrictions.ExpressionRestriction(test)); } } } }