2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / ComMethodDesc.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 // ComObject
19
20 using System.Diagnostics;
21 using System.Runtime.InteropServices.ComTypes;
22 using System.Text;
23 using System.Globalization;
24 using Marshal = System.Runtime.InteropServices.Marshal;
25
26 #if CODEPLEX_40
27 namespace System.Dynamic {
28 #else
29 namespace Microsoft.Scripting {
30 #endif
31
32     internal sealed class ComMethodDesc {
33         private readonly int _memid;  // this is the member id extracted from FUNCDESC.memid
34         private readonly string _name;
35         internal readonly INVOKEKIND InvokeKind;
36         private readonly int _paramCnt;
37
38         private ComMethodDesc(int dispId) {
39             _memid = dispId;
40         }
41
42         internal ComMethodDesc(string name, int dispId)
43             : this(dispId) {
44             // no ITypeInfo constructor
45             _name = name;
46         }
47
48         internal ComMethodDesc(string name, int dispId, INVOKEKIND invkind)
49             : this(name, dispId) {
50             InvokeKind = invkind;
51         }
52
53         internal ComMethodDesc(ITypeInfo typeInfo, FUNCDESC funcDesc)
54             : this(funcDesc.memid) {
55
56             InvokeKind = funcDesc.invkind;
57
58             int cNames;
59             string[] rgNames = new string[1 + funcDesc.cParams];
60             typeInfo.GetNames(_memid, rgNames, rgNames.Length, out cNames);
61             if (IsPropertyPut && rgNames[rgNames.Length - 1] == null) {
62                 rgNames[rgNames.Length - 1] = "value";
63                 cNames++;
64             }
65             Debug.Assert(cNames == rgNames.Length);
66             _name = rgNames[0];
67
68             _paramCnt = funcDesc.cParams;
69         }
70
71         public string Name {
72             get {
73                 Debug.Assert(_name != null);
74                 return _name;
75             }
76         }
77
78         public int DispId {
79             get { return _memid; }
80         }
81
82         public bool IsPropertyGet {
83             get {
84                 return (InvokeKind & INVOKEKIND.INVOKE_PROPERTYGET) != 0;
85             }
86         }
87
88         public bool IsDataMember {
89             get {
90                 //must be regular get
91                 if (!IsPropertyGet || DispId == ComDispIds.DISPID_NEWENUM) {
92                     return false;
93                 } 
94
95                 //must have no parameters
96                 return _paramCnt == 0;
97             }
98         }
99
100         public bool IsPropertyPut {
101             get {
102                 return (InvokeKind & (INVOKEKIND.INVOKE_PROPERTYPUT | INVOKEKIND.INVOKE_PROPERTYPUTREF)) != 0;
103             }
104         }
105
106         public bool IsPropertyPutRef {
107             get {
108                 return (InvokeKind & INVOKEKIND.INVOKE_PROPERTYPUTREF) != 0;
109             }
110         }
111
112         internal int ParamCount {
113             get {
114                 return _paramCnt;  
115             }
116         }
117     }
118 }
119
120 #endif