2007-11-17 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / corlib / System.Reflection.Emit / SignatureHelper.cs
1
2 //
3 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining
6 // a copy of this software and associated documentation files (the
7 // "Software"), to deal in the Software without restriction, including
8 // without limitation the rights to use, copy, modify, merge, publish,
9 // distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so, subject to
11 // the following conditions:
12 // 
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 // 
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //
24
25 //
26 // System.Reflection.Emit/SignatureHelper.cs
27 //
28 // Author:
29 //   Paolo Molaro (lupus@ximian.com)
30 //
31 // (C) 2001 Ximian, Inc.  http://www.ximian.com
32 //
33
34 using System;
35 using System.Reflection;
36 using System.Reflection.Emit;
37 using System.Globalization;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40
41 namespace System.Reflection.Emit {
42 #if NET_2_0
43         [ComVisible (true)]
44         [ComDefaultInterface (typeof (_SignatureHelper))]
45 #endif
46         [ClassInterface (ClassInterfaceType.None)]
47         public sealed class SignatureHelper : _SignatureHelper {
48                 internal enum SignatureHelperType {
49                         HELPER_FIELD,
50                         HELPER_LOCAL,
51                         HELPER_METHOD,
52                         HELPER_PROPERTY
53                 }
54
55                 private ModuleBuilder module; // can be null in 2.0
56                 private Type[] arguments;
57                 private SignatureHelperType type;
58                 private Type returnType;
59                 private CallingConventions callConv;
60                 private CallingConvention unmanagedCallConv;
61
62                 internal SignatureHelper (ModuleBuilder module, SignatureHelperType type)
63                 {
64                         this.type = type;
65                         this.module = module;
66                 }
67
68                 public static SignatureHelper GetFieldSigHelper (Module mod)
69                 {
70                         if (mod != null && !(mod is ModuleBuilder))
71                                 throw new ArgumentException ("ModuleBuilder is expected");
72
73                         return new SignatureHelper ((ModuleBuilder) mod, SignatureHelperType.HELPER_FIELD);
74                 }
75
76                 public static SignatureHelper GetLocalVarSigHelper (Module mod)
77                 {
78                         if (mod != null && !(mod is ModuleBuilder))
79                                 throw new ArgumentException ("ModuleBuilder is expected");
80
81                         return new SignatureHelper ((ModuleBuilder) mod, SignatureHelperType.HELPER_LOCAL);
82                 }
83
84 #if NET_2_0
85                 public static SignatureHelper GetLocalVarSigHelper ()
86                 {
87                         return new SignatureHelper (null, SignatureHelperType.HELPER_LOCAL);
88                 }
89
90                 public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
91                 {
92                         return GetMethodSigHelper (null, callingConvention, (CallingConvention)0, returnType, null);
93                 }
94
95                 public static SignatureHelper GetMethodSigHelper (CallingConvention unmanagedCallingConvention,
96                                                                   Type returnType)
97                 {
98                         return GetMethodSigHelper (null, CallingConventions.Standard, unmanagedCallingConvention, returnType, null);
99                 }
100 #endif
101
102                 public static SignatureHelper GetMethodSigHelper( Module mod, CallingConventions callingConvention, Type returnType)
103                 {
104                         return GetMethodSigHelper (mod, callingConvention, (CallingConvention)0, returnType, null);
105                 }
106
107                 public static SignatureHelper GetMethodSigHelper( Module mod, CallingConvention unmanagedCallingConvention, Type returnType)
108                 {
109                         return GetMethodSigHelper (mod, CallingConventions.Standard, unmanagedCallingConvention, returnType, null);
110                 }
111
112                 public static SignatureHelper GetMethodSigHelper( Module mod, Type returnType, Type[] parameterTypes)
113                 {
114                         return GetMethodSigHelper (mod, CallingConventions.Standard, 
115                                                                            (CallingConvention)0, returnType, 
116                                                                            parameterTypes);
117                 }
118                 [MonoTODO("Not implemented")]
119                 public static SignatureHelper GetPropertySigHelper( Module mod, Type returnType, Type[] parameterTypes)
120                 {
121                         throw new NotImplementedException ();
122                 }
123
124 #if NET_2_0
125
126                 static void ValidateCustomModifier (int n, Type [][] custom_modifiers, string name)
127                 {
128                         if (custom_modifiers == null)
129                                 return;
130
131                         if (custom_modifiers.Length != n)
132                                 throw new ArgumentException (
133                                      Locale.GetText (
134                                         String.Format ("Custom modifiers length `{0}' does not match the size of the arguments")));
135                         
136                         for (int i = 0; i < n; i++)
137                         foreach (Type [] parameter_modifiers in custom_modifiers){
138                                 if (parameter_modifiers == null)
139                                         continue;
140                                 
141                                 foreach (Type modififier in parameter_modifiers){
142                                         if (modififier == null)
143                                                 throw new ArgumentNullException (name);
144                                         if (modififier.IsArray)
145                                                 throw new ArgumentException (Locale.GetText ("Array type not permitted"), name);
146                                         if (modififier.ContainsGenericParameters)
147                                                 throw new ArgumentException (Locale.GetText ("Open Generic Type not permitted"), name);
148                                 }
149                         }
150                 }
151
152                 static Exception MissingFeature ()
153                 {
154                         throw new NotImplementedException ("Mono does not currently support setting modOpt/modReq through SignatureHelper");
155                 }
156
157                 [MonoTODO("Currently we ignore requiredCustomModifiers and optionalCustomModifiers")]
158                 public void AddArguments (Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
159                 {
160                         if (arguments == null)
161                                 throw new ArgumentNullException ("arguments");
162
163                         // For now
164                         if (requiredCustomModifiers != null || optionalCustomModifiers != null){
165                                 throw MissingFeature();
166                         }
167                         
168                         ValidateCustomModifier (arguments.Length, requiredCustomModifiers, "requiredCustomModifiers");
169                         ValidateCustomModifier (arguments.Length, optionalCustomModifiers, "optionalCustomModifiers");
170                         
171                         foreach (Type t in arguments){
172                                 AddArgument (t);
173                         }
174                 }
175
176                 [MonoTODO("Not implemented")]
177                 public static SignatureHelper GetPropertySigHelper (Module mod, Type returnType,
178                                                                     Type [] requiredReturnTypeCustomModifiers,
179                                                                     Type [] optionalReturnTypeCustomModifiers,
180                                                                     Type [] parameterTypes,
181                                                                     Type [] [] requiredParameterTypeCustomModifiers,
182                                                                     Type [] [] optionalParameterTypeCustomModifiers)
183                 {
184                         throw new NotImplementedException ();
185                 }
186 #endif
187
188                 public void AddArgument (Type clsArgument)
189                 {
190                         if (arguments != null) {
191                                 Type[] new_a = new Type [arguments.Length + 1];
192                                 System.Array.Copy (arguments, new_a, arguments.Length);
193                                 new_a [arguments.Length] = clsArgument;
194                                 arguments = new_a;
195                         } else {
196                                 arguments = new Type [1];
197                                 arguments [0] = clsArgument;
198                         }
199                 }
200
201 #if NET_2_0
202                 [MonoTODO ("pinned is ignored")]
203                 public void AddArgument (Type argument, bool pinned)
204                 {
205                         AddArgument (argument);
206                 }
207
208                 [MonoTODO ("not implemented")]
209                 public void AddArgument (Type argument, Type [] requiredCustomModifiers, Type [] optionalCustomModifiers)
210                 {
211                         throw new NotImplementedException ();
212                 }
213 #endif
214
215                 [MonoTODO("Not implemented")]
216                 public void AddSentinel ()
217                 {
218                         throw new NotImplementedException ();
219                 }
220
221                 [MonoTODO("Not implemented")]
222                 public override bool Equals (object obj)
223                 {
224                         throw new NotImplementedException ();
225                 }
226
227                 [MonoTODO("Not implemented")]
228                 public override int GetHashCode ()
229                 {
230                         throw new NotImplementedException ();
231                 }
232
233                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
234                 internal extern byte[] get_signature_local ();
235
236                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
237                 internal extern byte[] get_signature_field ();
238
239                 public byte[] GetSignature ()
240                 {
241                         switch (type) {
242                         case SignatureHelperType.HELPER_LOCAL:
243                                 return get_signature_local ();
244                         case SignatureHelperType.HELPER_FIELD:
245                                 return get_signature_field ();
246                         default:
247                                 throw new NotImplementedException ();
248                         }
249                 }
250
251                 public override string ToString() {
252                         return "SignatureHelper";
253                 }
254
255                 internal static SignatureHelper GetMethodSigHelper( Module mod, CallingConventions callConv, CallingConvention unmanagedCallConv, Type returnType,
256                                                                                                                    Type [] parameters)
257                 {
258                         if (mod != null && !(mod is ModuleBuilder))
259                                 throw new ArgumentException ("ModuleBuilder is expected");
260
261                         SignatureHelper helper = 
262                                 new SignatureHelper ((ModuleBuilder)mod, SignatureHelperType.HELPER_METHOD);
263                         helper.returnType = returnType;
264                         helper.callConv = callConv;
265                         helper.unmanagedCallConv = unmanagedCallConv;
266
267                         if (parameters != null) {
268                                 helper.arguments = new Type [parameters.Length];
269                                 for (int i = 0; i < parameters.Length; ++i)
270                                         helper.arguments [i] = parameters [i];
271                         }
272
273                         return helper;
274                 }
275
276                 void _SignatureHelper.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
277                 {
278                         throw new NotImplementedException ();
279                 }
280
281                 void _SignatureHelper.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
282                 {
283                         throw new NotImplementedException ();
284                 }
285
286                 void _SignatureHelper.GetTypeInfoCount (out uint pcTInfo)
287                 {
288                         throw new NotImplementedException ();
289                 }
290
291                 void _SignatureHelper.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
292                 {
293                         throw new NotImplementedException ();
294                 }
295         }
296 }
297