2009-07-22 Geoff Norton <gnorton@novell.com>
[mono-project.git] / mcs / class / corlib / System.Reflection.Emit / SignatureHelper.cs
blob5c6ee451e5220deeea91063dc0049250b0d75881
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.
26 // System.Reflection.Emit/SignatureHelper.cs
28 // Author:
29 // Paolo Molaro (lupus@ximian.com)
31 // (C) 2001 Ximian, Inc. http://www.ximian.com
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;
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
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 #pragma warning disable 649
62 private Type[][] modreqs;
63 private Type[][] modopts;
64 #pragma warning restore 649
66 internal SignatureHelper (ModuleBuilder module, SignatureHelperType type)
68 this.type = type;
69 this.module = module;
72 public static SignatureHelper GetFieldSigHelper (Module mod)
74 if (mod != null && !(mod is ModuleBuilder))
75 throw new ArgumentException ("ModuleBuilder is expected");
77 return new SignatureHelper ((ModuleBuilder) mod, SignatureHelperType.HELPER_FIELD);
80 public static SignatureHelper GetLocalVarSigHelper (Module mod)
82 if (mod != null && !(mod is ModuleBuilder))
83 throw new ArgumentException ("ModuleBuilder is expected");
85 return new SignatureHelper ((ModuleBuilder) mod, SignatureHelperType.HELPER_LOCAL);
88 #if NET_2_0
89 public static SignatureHelper GetLocalVarSigHelper ()
91 return new SignatureHelper (null, SignatureHelperType.HELPER_LOCAL);
94 public static SignatureHelper GetMethodSigHelper (CallingConventions callingConvention, Type returnType)
96 return GetMethodSigHelper (null, callingConvention, (CallingConvention)0, returnType, null);
99 public static SignatureHelper GetMethodSigHelper (CallingConvention unmanagedCallingConvention, Type returnType)
101 return GetMethodSigHelper (null, CallingConventions.Standard, unmanagedCallingConvention, returnType, null);
103 #endif
105 public static SignatureHelper GetMethodSigHelper (Module mod, CallingConventions callingConvention, Type returnType)
107 return GetMethodSigHelper (mod, callingConvention, (CallingConvention)0, returnType, null);
110 public static SignatureHelper GetMethodSigHelper (Module mod, CallingConvention unmanagedCallConv, Type returnType)
112 return GetMethodSigHelper (mod, CallingConventions.Standard, unmanagedCallConv, returnType, null);
115 public static SignatureHelper GetMethodSigHelper (Module mod, Type returnType, Type[] parameterTypes)
117 return GetMethodSigHelper (mod, CallingConventions.Standard, (CallingConvention)0, returnType, parameterTypes);
119 [MonoTODO("Not implemented")]
120 public static SignatureHelper GetPropertySigHelper (Module mod, Type returnType, Type[] parameterTypes)
122 throw new NotImplementedException ();
126 // Grows the given array, and returns the index where the element
127 // was added
129 static int AppendArray (ref Type [] array, Type t)
131 if (array != null) {
132 Type[] new_a = new Type [array.Length + 1];
133 System.Array.Copy (array, new_a, array.Length);
134 new_a [array.Length] = t;
135 array = new_a;
136 return array.Length-1;
137 } else {
138 array = new Type [1];
139 array [0] = t;
140 return 0;
144 #if NET_2_0
146 // Appends the given type array @t into the @array passed at
147 // position @pos. If there is no array, it gets created
149 // This allows adding data to a null array at position 5 for
150 // example, creating 4 empty slots before the slot where @t
151 // is stored.
154 static void AppendArrayAt (ref Type [][] array, Type [] t, int pos)
156 int top = Math.Max (pos, array == null ? 0 : array.Length);
157 Type[][] new_a = new Type [top+1][];
158 if (array != null)
159 System.Array.Copy (array, new_a, top);
160 new_a [pos] = t;
161 array = new_a;
164 static void ValidateParameterModifiers (string name, Type [] parameter_modifiers)
166 foreach (Type modifier in parameter_modifiers){
167 if (modifier == null)
168 throw new ArgumentNullException (name);
169 if (modifier.IsArray)
170 throw new ArgumentException (Locale.GetText ("Array type not permitted"), name);
171 if (modifier.ContainsGenericParameters)
172 throw new ArgumentException (Locale.GetText ("Open Generic Type not permitted"), name);
176 static void ValidateCustomModifier (int n, Type [][] custom_modifiers, string name)
178 if (custom_modifiers == null)
179 return;
181 if (custom_modifiers.Length != n)
182 throw new ArgumentException (
183 Locale.GetText (
184 String.Format ("Custom modifiers length `{0}' does not match the size of the arguments")));
186 foreach (Type [] parameter_modifiers in custom_modifiers){
187 if (parameter_modifiers == null)
188 continue;
190 ValidateParameterModifiers (name, parameter_modifiers);
194 static Exception MissingFeature ()
196 throw new NotImplementedException ("Mono does not currently support setting modOpt/modReq through SignatureHelper");
199 [MonoTODO("Currently we ignore requiredCustomModifiers and optionalCustomModifiers")]
200 public void AddArguments (Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
202 if (arguments == null)
203 throw new ArgumentNullException ("arguments");
205 // For now
206 if (requiredCustomModifiers != null || optionalCustomModifiers != null){
207 throw MissingFeature();
210 ValidateCustomModifier (arguments.Length, requiredCustomModifiers, "requiredCustomModifiers");
211 ValidateCustomModifier (arguments.Length, optionalCustomModifiers, "optionalCustomModifiers");
213 for (int i = 0; i < arguments.Length; i++){
214 AddArgument (arguments [i],
215 requiredCustomModifiers != null ? requiredCustomModifiers [i] : null,
216 optionalCustomModifiers != null ? optionalCustomModifiers [i] : null);
220 [MonoTODO ("pinned is ignored")]
221 public void AddArgument (Type argument, bool pinned)
223 AddArgument (argument);
226 public void AddArgument (Type argument, Type [] requiredCustomModifiers, Type [] optionalCustomModifiers)
228 if (argument == null)
229 throw new ArgumentNullException ("argument");
231 if (requiredCustomModifiers != null)
232 ValidateParameterModifiers ("requiredCustomModifiers", requiredCustomModifiers);
233 if (optionalCustomModifiers != null)
234 ValidateParameterModifiers ("optionalCustomModifiers", optionalCustomModifiers);
236 int p = AppendArray (ref arguments, argument);
237 if (requiredCustomModifiers != null)
238 AppendArrayAt (ref modreqs, requiredCustomModifiers, p);
239 if (optionalCustomModifiers != null)
240 AppendArrayAt (ref modopts, optionalCustomModifiers, p);
243 [MonoTODO("Not implemented")]
244 public static SignatureHelper GetPropertySigHelper (Module mod, Type returnType,
245 Type [] requiredReturnTypeCustomModifiers,
246 Type [] optionalReturnTypeCustomModifiers,
247 Type [] parameterTypes,
248 Type [] [] requiredParameterTypeCustomModifiers,
249 Type [] [] optionalParameterTypeCustomModifiers)
251 throw new NotImplementedException ();
253 #endif
255 public void AddArgument (Type clsArgument)
257 if (clsArgument == null)
258 throw new ArgumentNullException ("clsArgument");
260 AppendArray (ref arguments, clsArgument);
263 [MonoTODO("Not implemented")]
264 public void AddSentinel ()
266 throw new NotImplementedException ();
269 static bool CompareOK (Type [][] one, Type [][] two)
271 if (one == null){
272 if (two == null)
273 return true;
274 return false;
275 } else if (two == null)
276 return false;
278 if (one.Length != two.Length)
279 return false;
281 for (int i = 0; i < one.Length; i++){
282 Type [] tone = one [i];
283 Type [] ttwo = two [i];
285 if (tone == null){
286 if (ttwo == null)
287 continue;
288 } else if (ttwo == null)
289 return false;
291 if (tone.Length != ttwo.Length)
292 return false;
294 for (int j = 0; j < tone.Length; j++){
295 Type uone = tone [j];
296 Type utwo = ttwo [j];
298 if (uone == null){
299 if (utwo == null)
300 continue;
301 return false;
302 } else if (utwo == null)
303 return false;
305 if (!uone.Equals (utwo))
306 return false;
309 return true;
312 public override bool Equals (object obj)
314 SignatureHelper other = obj as SignatureHelper;
315 if (other == null)
316 return false;
318 if (other.module != module ||
319 other.returnType != returnType ||
320 other.callConv != callConv ||
321 other.unmanagedCallConv != unmanagedCallConv)
322 return false;
324 if (arguments != null){
325 if (other.arguments == null)
326 return false;
327 if (arguments.Length != other.arguments.Length)
328 return false;
330 for (int i = 0; i < arguments.Length; i++)
331 if (!other.arguments [i].Equals (arguments [i]))
332 return false;
333 } else if (other.arguments != null)
334 return false;
336 return CompareOK (other.modreqs, modreqs) && CompareOK (other.modopts, modopts);
339 public override int GetHashCode ()
341 // Lame, but easy, and will work, and chances are
342 // you will only need a few of these.
343 return 0;
346 [MethodImplAttribute(MethodImplOptions.InternalCall)]
347 internal extern byte[] get_signature_local ();
349 [MethodImplAttribute(MethodImplOptions.InternalCall)]
350 internal extern byte[] get_signature_field ();
352 public byte[] GetSignature ()
354 switch (type) {
355 case SignatureHelperType.HELPER_LOCAL:
356 return get_signature_local ();
357 case SignatureHelperType.HELPER_FIELD:
358 return get_signature_field ();
359 default:
360 throw new NotImplementedException ();
364 public override string ToString() {
365 return "SignatureHelper";
368 internal static SignatureHelper GetMethodSigHelper (Module mod, CallingConventions callingConvention, CallingConvention unmanagedCallingConvention, Type returnType,
369 Type [] parameters)
371 if (mod != null && !(mod is ModuleBuilder))
372 throw new ArgumentException ("ModuleBuilder is expected");
374 if (returnType == null)
375 returnType = typeof (void);
377 if (returnType.IsUserType)
378 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
379 if (parameters != null) {
380 for (int i = 0; i < parameters.Length; ++i)
381 if (parameters [i].IsUserType)
382 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
386 SignatureHelper helper =
387 new SignatureHelper ((ModuleBuilder)mod, SignatureHelperType.HELPER_METHOD);
388 helper.returnType = returnType;
389 helper.callConv = callingConvention;
390 helper.unmanagedCallConv = unmanagedCallingConvention;
392 if (parameters != null) {
393 helper.arguments = new Type [parameters.Length];
394 for (int i = 0; i < parameters.Length; ++i)
395 helper.arguments [i] = parameters [i];
398 return helper;
401 void _SignatureHelper.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
403 throw new NotImplementedException ();
406 void _SignatureHelper.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
408 throw new NotImplementedException ();
411 void _SignatureHelper.GetTypeInfoCount (out uint pcTInfo)
413 throw new NotImplementedException ();
416 void _SignatureHelper.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
418 throw new NotImplementedException ();