2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / ComMetaObject.cs
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 using System; using Microsoft;
16
17
18 #if !SILVERLIGHT
19
20 #if CODEPLEX_40
21 using System.Linq.Expressions;
22 using System.Dynamic;
23 using System.Dynamic.Utils;
24 #else
25 using Microsoft.Linq.Expressions;
26 using Microsoft.Scripting;
27 using Microsoft.Scripting.Utils;
28 #endif
29 using System.Collections.Generic;
30
31 #if CODEPLEX_40
32 namespace System.Dynamic {
33 #else
34 namespace Microsoft.Scripting {
35 #endif
36
37     // Note: we only need to support the operations used by ComBinder
38     internal class ComMetaObject : DynamicMetaObject {
39         internal ComMetaObject(Expression expression, BindingRestrictions restrictions, object arg)
40             : base(expression, restrictions, arg) {
41         }
42
43         public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) {
44             ContractUtils.RequiresNotNull(binder, "binder");
45             return binder.Defer(args.AddFirst(WrapSelf()));
46         }
47
48         public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args) {
49             ContractUtils.RequiresNotNull(binder, "binder");
50             return binder.Defer(args.AddFirst(WrapSelf()));
51         }
52
53         public override DynamicMetaObject BindGetMember(GetMemberBinder binder) {
54             ContractUtils.RequiresNotNull(binder, "binder");
55             return binder.Defer(WrapSelf());
56         }
57
58         public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value) {
59             ContractUtils.RequiresNotNull(binder, "binder");
60             return binder.Defer(WrapSelf(), value);
61         }
62
63         public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes) {
64             ContractUtils.RequiresNotNull(binder, "binder");
65             return binder.Defer(WrapSelf(), indexes);
66         }
67
68         public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) {
69             ContractUtils.RequiresNotNull(binder, "binder");
70             return binder.Defer(WrapSelf(), indexes.AddLast(value));
71         }
72
73         private DynamicMetaObject WrapSelf() {
74             return new DynamicMetaObject(
75                 ComObject.RcwToComObject(Expression),
76                 BindingRestrictions.GetExpressionRestriction(
77                     Expression.Call(
78                         typeof(ComObject).GetMethod("IsComObject", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic),
79                         Helpers.Convert(Expression, typeof(object))
80                     )
81                 )
82             );
83         }
84     }
85 }
86
87 #endif