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
{
43 [ComDefaultInterface (typeof (_SignatureHelper
))]
44 [ClassInterface (ClassInterfaceType
.None
)]
45 public sealed class SignatureHelper
: _SignatureHelper
{
46 internal enum SignatureHelperType
{
53 private ModuleBuilder module
; // can be null in 2.0
54 private Type
[] arguments
;
55 private SignatureHelperType type
;
56 private Type returnType
;
57 private CallingConventions callConv
;
58 private CallingConvention unmanagedCallConv
;
59 #pragma warning disable 649
60 private Type
[][] modreqs
;
61 private Type
[][] modopts
;
62 #pragma warning restore 649
64 internal SignatureHelper (ModuleBuilder module
, SignatureHelperType type
)
70 public static SignatureHelper
GetFieldSigHelper (Module mod
)
72 if (mod
!= null && !(mod
is ModuleBuilder
))
73 throw new ArgumentException ("ModuleBuilder is expected");
75 return new SignatureHelper ((ModuleBuilder
) mod
, SignatureHelperType
.HELPER_FIELD
);
78 public static SignatureHelper
GetLocalVarSigHelper (Module mod
)
80 if (mod
!= null && !(mod
is ModuleBuilder
))
81 throw new ArgumentException ("ModuleBuilder is expected");
83 return new SignatureHelper ((ModuleBuilder
) mod
, SignatureHelperType
.HELPER_LOCAL
);
86 public static SignatureHelper
GetLocalVarSigHelper ()
88 return new SignatureHelper (null, SignatureHelperType
.HELPER_LOCAL
);
91 public static SignatureHelper
GetMethodSigHelper (CallingConventions callingConvention
, Type returnType
)
93 return GetMethodSigHelper (null, callingConvention
, (CallingConvention
)0, returnType
, null);
96 public static SignatureHelper
GetMethodSigHelper (CallingConvention unmanagedCallingConvention
, Type returnType
)
98 return GetMethodSigHelper (null, CallingConventions
.Standard
, unmanagedCallingConvention
, returnType
, null);
101 public static SignatureHelper
GetMethodSigHelper (Module mod
, CallingConventions callingConvention
, Type returnType
)
103 return GetMethodSigHelper (mod
, callingConvention
, (CallingConvention
)0, returnType
, null);
106 public static SignatureHelper
GetMethodSigHelper (Module mod
, CallingConvention unmanagedCallConv
, Type returnType
)
108 return GetMethodSigHelper (mod
, CallingConventions
.Standard
, unmanagedCallConv
, returnType
, null);
111 public static SignatureHelper
GetMethodSigHelper (Module mod
, Type returnType
, Type
[] parameterTypes
)
113 return GetMethodSigHelper (mod
, CallingConventions
.Standard
, (CallingConvention
)0, returnType
, parameterTypes
);
115 [MonoTODO("Not implemented")]
116 public static SignatureHelper
GetPropertySigHelper (Module mod
, Type returnType
, Type
[] parameterTypes
)
118 throw new NotImplementedException ();
122 // Grows the given array, and returns the index where the element
125 static int AppendArray (ref Type
[] array
, Type t
)
128 Type
[] new_a
= new Type
[array
.Length
+ 1];
129 System
.Array
.Copy (array
, new_a
, array
.Length
);
130 new_a
[array
.Length
] = t
;
132 return array
.Length
-1;
134 array
= new Type
[1];
141 // Appends the given type array @t into the @array passed at
142 // position @pos. If there is no array, it gets created
144 // This allows adding data to a null array at position 5 for
145 // example, creating 4 empty slots before the slot where @t
149 static void AppendArrayAt (ref Type
[][] array
, Type
[] t
, int pos
)
151 int top
= Math
.Max (pos
, array
== null ? 0 : array
.Length
);
152 Type
[][] new_a
= new Type
[top
+1][];
154 System
.Array
.Copy (array
, new_a
, top
);
159 static void ValidateParameterModifiers (string name
, Type
[] parameter_modifiers
)
161 foreach (Type modifier
in parameter_modifiers
){
162 if (modifier
== null)
163 throw new ArgumentNullException (name
);
164 if (modifier
.IsArray
)
165 throw new ArgumentException (Locale
.GetText ("Array type not permitted"), name
);
166 if (modifier
.ContainsGenericParameters
)
167 throw new ArgumentException (Locale
.GetText ("Open Generic Type not permitted"), name
);
171 static void ValidateCustomModifier (int n
, Type
[][] custom_modifiers
, string name
)
173 if (custom_modifiers
== null)
176 if (custom_modifiers
.Length
!= n
)
177 throw new ArgumentException (
179 String
.Format ("Custom modifiers length `{0}' does not match the size of the arguments")));
181 foreach (Type
[] parameter_modifiers
in custom_modifiers
){
182 if (parameter_modifiers
== null)
185 ValidateParameterModifiers (name
, parameter_modifiers
);
189 static Exception
MissingFeature ()
191 throw new NotImplementedException ("Mono does not currently support setting modOpt/modReq through SignatureHelper");
194 [MonoTODO("Currently we ignore requiredCustomModifiers and optionalCustomModifiers")]
195 public void AddArguments (Type
[] arguments
, Type
[][] requiredCustomModifiers
, Type
[][] optionalCustomModifiers
)
197 if (arguments
== null)
198 throw new ArgumentNullException ("arguments");
201 if (requiredCustomModifiers
!= null || optionalCustomModifiers
!= null){
202 throw MissingFeature();
205 ValidateCustomModifier (arguments
.Length
, requiredCustomModifiers
, "requiredCustomModifiers");
206 ValidateCustomModifier (arguments
.Length
, optionalCustomModifiers
, "optionalCustomModifiers");
208 for (int i
= 0; i
< arguments
.Length
; i
++){
209 AddArgument (arguments
[i
],
210 requiredCustomModifiers
!= null ? requiredCustomModifiers
[i
] : null,
211 optionalCustomModifiers
!= null ? optionalCustomModifiers
[i
] : null);
215 [MonoTODO ("pinned is ignored")]
216 public void AddArgument (Type argument
, bool pinned
)
218 AddArgument (argument
);
221 public void AddArgument (Type argument
, Type
[] requiredCustomModifiers
, Type
[] optionalCustomModifiers
)
223 if (argument
== null)
224 throw new ArgumentNullException ("argument");
226 if (requiredCustomModifiers
!= null)
227 ValidateParameterModifiers ("requiredCustomModifiers", requiredCustomModifiers
);
228 if (optionalCustomModifiers
!= null)
229 ValidateParameterModifiers ("optionalCustomModifiers", optionalCustomModifiers
);
231 int p
= AppendArray (ref arguments
, argument
);
232 if (requiredCustomModifiers
!= null)
233 AppendArrayAt (ref modreqs
, requiredCustomModifiers
, p
);
234 if (optionalCustomModifiers
!= null)
235 AppendArrayAt (ref modopts
, optionalCustomModifiers
, p
);
238 [MonoTODO("Not implemented")]
239 public static SignatureHelper
GetPropertySigHelper (Module mod
, Type returnType
,
240 Type
[] requiredReturnTypeCustomModifiers
,
241 Type
[] optionalReturnTypeCustomModifiers
,
242 Type
[] parameterTypes
,
243 Type
[] [] requiredParameterTypeCustomModifiers
,
244 Type
[] [] optionalParameterTypeCustomModifiers
)
246 throw new NotImplementedException ();
249 public void AddArgument (Type clsArgument
)
251 if (clsArgument
== null)
252 throw new ArgumentNullException ("clsArgument");
254 AppendArray (ref arguments
, clsArgument
);
257 [MonoTODO("Not implemented")]
258 public void AddSentinel ()
260 throw new NotImplementedException ();
263 static bool CompareOK (Type
[][] one
, Type
[][] two
)
269 } else if (two
== null)
272 if (one
.Length
!= two
.Length
)
275 for (int i
= 0; i
< one
.Length
; i
++){
276 Type
[] tone
= one
[i
];
277 Type
[] ttwo
= two
[i
];
282 } else if (ttwo
== null)
285 if (tone
.Length
!= ttwo
.Length
)
288 for (int j
= 0; j
< tone
.Length
; j
++){
289 Type uone
= tone
[j
];
290 Type utwo
= ttwo
[j
];
296 } else if (utwo
== null)
299 if (!uone
.Equals (utwo
))
306 public override bool Equals (object obj
)
308 SignatureHelper other
= obj
as SignatureHelper
;
312 if (other
.module
!= module
||
313 other
.returnType
!= returnType
||
314 other
.callConv
!= callConv
||
315 other
.unmanagedCallConv
!= unmanagedCallConv
)
318 if (arguments
!= null){
319 if (other
.arguments
== null)
321 if (arguments
.Length
!= other
.arguments
.Length
)
324 for (int i
= 0; i
< arguments
.Length
; i
++)
325 if (!other
.arguments
[i
].Equals (arguments
[i
]))
327 } else if (other
.arguments
!= null)
330 return CompareOK (other
.modreqs
, modreqs
) && CompareOK (other
.modopts
, modopts
);
333 public override int GetHashCode ()
335 // Lame, but easy, and will work, and chances are
336 // you will only need a few of these.
340 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
341 internal extern byte[] get_signature_local ();
343 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
344 internal extern byte[] get_signature_field ();
346 public byte[] GetSignature ()
349 case SignatureHelperType
.HELPER_LOCAL
:
350 return get_signature_local ();
351 case SignatureHelperType
.HELPER_FIELD
:
352 return get_signature_field ();
354 throw new NotImplementedException ();
358 public override string ToString() {
359 return "SignatureHelper";
362 internal static SignatureHelper
GetMethodSigHelper (Module mod
, CallingConventions callingConvention
, CallingConvention unmanagedCallingConvention
, Type returnType
,
365 if (mod
!= null && !(mod
is ModuleBuilder
))
366 throw new ArgumentException ("ModuleBuilder is expected");
368 if (returnType
== null)
369 returnType
= typeof (void);
371 if (returnType
.IsUserType
)
372 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
373 if (parameters
!= null) {
374 for (int i
= 0; i
< parameters
.Length
; ++i
)
375 if (parameters
[i
].IsUserType
)
376 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
380 SignatureHelper helper
=
381 new SignatureHelper ((ModuleBuilder
)mod
, SignatureHelperType
.HELPER_METHOD
);
382 helper
.returnType
= returnType
;
383 helper
.callConv
= callingConvention
;
384 helper
.unmanagedCallConv
= unmanagedCallingConvention
;
386 if (parameters
!= null) {
387 helper
.arguments
= new Type
[parameters
.Length
];
388 for (int i
= 0; i
< parameters
.Length
; ++i
)
389 helper
.arguments
[i
] = parameters
[i
];
395 void _SignatureHelper
.GetIDsOfNames ([In
] ref Guid riid
, IntPtr rgszNames
, uint cNames
, uint lcid
, IntPtr rgDispId
)
397 throw new NotImplementedException ();
400 void _SignatureHelper
.GetTypeInfo (uint iTInfo
, uint lcid
, IntPtr ppTInfo
)
402 throw new NotImplementedException ();
405 void _SignatureHelper
.GetTypeInfoCount (out uint pcTInfo
)
407 throw new NotImplementedException ();
410 void _SignatureHelper
.Invoke (uint dispIdMember
, [In
] ref Guid riid
, uint lcid
, short wFlags
, IntPtr pDispParams
, IntPtr pVarResult
, IntPtr pExcepInfo
, IntPtr puArgErr
)
412 throw new NotImplementedException ();