3 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
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
29 // Paolo Molaro (lupus@ximian.com)
31 // (C) 2001 Ximian, Inc. http://www.ximian.com
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
{
44 [ComDefaultInterface (typeof (_SignatureHelper
))]
46 [ClassInterface (ClassInterfaceType
.None
)]
47 public sealed class SignatureHelper
: _SignatureHelper
{
48 internal enum SignatureHelperType
{
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
)
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
);
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);
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
129 static int AppendArray (ref Type
[] array
, Type t
)
132 Type
[] new_a
= new Type
[array
.Length
+ 1];
133 System
.Array
.Copy (array
, new_a
, array
.Length
);
134 new_a
[array
.Length
] = t
;
136 return array
.Length
-1;
138 array
= new Type
[1];
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
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][];
159 System
.Array
.Copy (array
, new_a
, top
);
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)
181 if (custom_modifiers
.Length
!= n
)
182 throw new ArgumentException (
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)
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");
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 ();
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
)
275 } else if (two
== null)
278 if (one
.Length
!= two
.Length
)
281 for (int i
= 0; i
< one
.Length
; i
++){
282 Type
[] tone
= one
[i
];
283 Type
[] ttwo
= two
[i
];
288 } else if (ttwo
== null)
291 if (tone
.Length
!= ttwo
.Length
)
294 for (int j
= 0; j
< tone
.Length
; j
++){
295 Type uone
= tone
[j
];
296 Type utwo
= ttwo
[j
];
302 } else if (utwo
== null)
305 if (!uone
.Equals (utwo
))
312 public override bool Equals (object obj
)
314 SignatureHelper other
= obj
as SignatureHelper
;
318 if (other
.module
!= module
||
319 other
.returnType
!= returnType
||
320 other
.callConv
!= callConv
||
321 other
.unmanagedCallConv
!= unmanagedCallConv
)
324 if (arguments
!= null){
325 if (other
.arguments
== null)
327 if (arguments
.Length
!= other
.arguments
.Length
)
330 for (int i
= 0; i
< arguments
.Length
; i
++)
331 if (!other
.arguments
[i
].Equals (arguments
[i
]))
333 } else if (other
.arguments
!= null)
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.
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 ()
355 case SignatureHelperType
.HELPER_LOCAL
:
356 return get_signature_local ();
357 case SignatureHelperType
.HELPER_FIELD
:
358 return get_signature_field ();
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
,
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
];
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 ();