2 // System.Reflection.Emit.ConstructorBuilder.cs
5 // Paolo Molaro (lupus@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Reflection
;
35 using System
.Reflection
.Emit
;
36 using System
.Globalization
;
37 using System
.Security
;
38 using System
.Security
.Permissions
;
39 using System
.Runtime
.InteropServices
;
40 using System
.Diagnostics
.SymbolStore
;
42 namespace System
.Reflection
.Emit
{
45 [ComDefaultInterface (typeof (_ConstructorBuilder
))]
46 [ClassInterface (ClassInterfaceType
.None
)]
47 public sealed class ConstructorBuilder
: ConstructorInfo
, _ConstructorBuilder
{
49 #pragma warning disable 169, 414
50 private RuntimeMethodHandle mhandle
;
51 private ILGenerator ilgen
;
52 internal Type
[] parameters
;
53 private MethodAttributes attrs
;
54 private MethodImplAttributes iattrs
;
55 private int table_idx
;
56 private CallingConventions call_conv
;
57 private TypeBuilder type
;
58 internal ParameterBuilder
[] pinfo
;
59 private CustomAttributeBuilder
[] cattrs
;
60 private bool init_locals
= true;
61 private Type
[][] paramModReq
;
62 private Type
[][] paramModOpt
;
63 private RefEmitPermissionSet
[] permissions
;
64 #pragma warning restore 169, 414
66 internal ConstructorBuilder (TypeBuilder tb
, MethodAttributes attributes
, CallingConventions callingConvention
, Type
[] parameterTypes
, Type
[][] paramModReq
, Type
[][] paramModOpt
)
68 attrs
= attributes
| MethodAttributes
.SpecialName
| MethodAttributes
.RTSpecialName
;
69 call_conv
= callingConvention
;
70 if (parameterTypes
!= null) {
71 for (int i
= 0; i
< parameterTypes
.Length
; ++i
)
72 if (parameterTypes
[i
] == null)
73 throw new ArgumentException ("Elements of the parameterTypes array cannot be null", "parameterTypes");
75 this.parameters
= new Type
[parameterTypes
.Length
];
76 System
.Array
.Copy (parameterTypes
, this.parameters
, parameterTypes
.Length
);
79 this.paramModReq
= paramModReq
;
80 this.paramModOpt
= paramModOpt
;
81 table_idx
= get_next_table_index (this, 0x06, true);
83 ((ModuleBuilder
) tb
.Module
).RegisterToken (this, GetToken ().Token
);
87 public override CallingConventions CallingConvention
{
93 public bool InitLocals
{
102 internal TypeBuilder TypeBuilder
{
108 public override MethodImplAttributes
GetMethodImplementationFlags ()
113 public override ParameterInfo
[] GetParameters ()
115 if (!type
.is_created
&& !IsCompilerContext
)
116 throw not_created ();
118 return GetParametersInternal ();
121 internal ParameterInfo
[] GetParametersInternal ()
123 if (parameters
== null)
124 return new ParameterInfo
[0];
126 ParameterInfo
[] retval
= new ParameterInfo
[parameters
.Length
];
127 for (int i
= 0; i
< parameters
.Length
; i
++)
128 retval
[i
] = new ParameterInfo (pinfo
== null ? null
129 : pinfo
[i
+ 1], parameters
[i
], this, i
+ 1);
134 internal override int GetParameterCount ()
136 if (parameters
== null)
139 return parameters
.Length
;
142 public override Object
Invoke (Object obj
, BindingFlags invokeAttr
, Binder binder
, Object
[] parameters
, CultureInfo culture
)
144 throw not_supported ();
147 public override object Invoke (BindingFlags invokeAttr
, Binder binder
, object[] parameters
, CultureInfo culture
)
149 throw not_supported ();
152 public override RuntimeMethodHandle MethodHandle
{
154 throw not_supported ();
158 public override MethodAttributes Attributes
{
164 public override Type ReflectedType
{
170 public override Type DeclaringType
{
179 public Type ReturnType
{
185 public override string Name
{
187 return (attrs
& MethodAttributes
.Static
) != 0 ? ConstructorInfo
.TypeConstructorName
: ConstructorInfo
.ConstructorName
;
191 public string Signature
{
193 return "constructor signature";
197 public void AddDeclarativeSecurity (SecurityAction action
, PermissionSet pset
)
201 throw new ArgumentNullException ("pset");
202 if ((action
== SecurityAction
.RequestMinimum
) ||
203 (action
== SecurityAction
.RequestOptional
) ||
204 (action
== SecurityAction
.RequestRefuse
))
205 throw new ArgumentOutOfRangeException ("action", "Request* values are not permitted");
209 if (permissions
!= null) {
210 /* Check duplicate actions */
211 foreach (RefEmitPermissionSet
set in permissions
)
212 if (set.action
== action
)
213 throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction.");
215 RefEmitPermissionSet
[] new_array
= new RefEmitPermissionSet
[permissions
.Length
+ 1];
216 permissions
.CopyTo (new_array
, 0);
217 permissions
= new_array
;
220 permissions
= new RefEmitPermissionSet
[1];
222 permissions
[permissions
.Length
- 1] = new RefEmitPermissionSet (action
, pset
.ToXml ().ToString ());
223 attrs
|= MethodAttributes
.HasSecurity
;
227 public ParameterBuilder
DefineParameter (int iSequence
, ParameterAttributes attributes
, string strParamName
)
229 if (iSequence
< 1 || iSequence
> GetParameterCount ())
230 throw new ArgumentOutOfRangeException ("iSequence");
232 throw not_after_created ();
234 ParameterBuilder pb
= new ParameterBuilder (this, iSequence
, attributes
, strParamName
);
236 pinfo
= new ParameterBuilder
[parameters
.Length
+ 1];
237 pinfo
[iSequence
] = pb
;
241 public override bool IsDefined (Type attributeType
, bool inherit
)
243 throw not_supported ();
246 public override object [] GetCustomAttributes (bool inherit
)
249 * On MS.NET, this always returns not_supported, but we can't do this
250 * since there would be no way to obtain custom attributes of
251 * dynamically created ctors.
253 if (type
.is_created
&& IsCompilerContext
)
254 return MonoCustomAttrs
.GetCustomAttributes (this, inherit
);
256 throw not_supported ();
259 public override object [] GetCustomAttributes (Type attributeType
, bool inherit
)
261 if (type
.is_created
&& IsCompilerContext
)
262 return MonoCustomAttrs
.GetCustomAttributes (this, attributeType
, inherit
);
264 throw not_supported ();
267 public ILGenerator
GetILGenerator ()
269 return GetILGenerator (64);
272 public ILGenerator
GetILGenerator (int streamSize
)
276 ilgen
= new ILGenerator (type
.Module
, ((ModuleBuilder
)type
.Module
).GetTokenGenerator (), streamSize
);
280 public void SetCustomAttribute (CustomAttributeBuilder customBuilder
)
282 if (customBuilder
== null)
283 throw new ArgumentNullException ("customBuilder");
285 string attrname
= customBuilder
.Ctor
.ReflectedType
.FullName
;
286 if (attrname
== "System.Runtime.CompilerServices.MethodImplAttribute") {
287 byte[] data
= customBuilder
.Data
;
288 int impla
; // the (stupid) ctor takes a short or an int ...
289 impla
= (int)data
[2];
290 impla
|= ((int)data
[3]) << 8;
291 SetImplementationFlags ((MethodImplAttributes
)impla
);
294 if (cattrs
!= null) {
295 CustomAttributeBuilder
[] new_array
= new CustomAttributeBuilder
[cattrs
.Length
+ 1];
296 cattrs
.CopyTo (new_array
, 0);
297 new_array
[cattrs
.Length
] = customBuilder
;
300 cattrs
= new CustomAttributeBuilder
[1];
301 cattrs
[0] = customBuilder
;
306 public void SetCustomAttribute (ConstructorInfo con
, byte[] binaryAttribute
)
309 throw new ArgumentNullException ("con");
310 if (binaryAttribute
== null)
311 throw new ArgumentNullException ("binaryAttribute");
313 SetCustomAttribute (new CustomAttributeBuilder (con
, binaryAttribute
));
316 public void SetImplementationFlags (MethodImplAttributes attributes
)
319 throw not_after_created ();
324 public Module
GetModule ()
329 public MethodToken
GetToken ()
331 return new MethodToken (0x06000000 | table_idx
);
335 public void SetSymCustomAttribute (string name
, byte[] data
)
338 throw not_after_created ();
341 public override Module Module
{
347 public override string ToString ()
349 return "ConstructorBuilder ['" + type
.Name
+ "']";
352 internal void fixup ()
354 if (((attrs
& (MethodAttributes
.Abstract
| MethodAttributes
.PinvokeImpl
)) == 0) && ((iattrs
& (MethodImplAttributes
.Runtime
| MethodImplAttributes
.InternalCall
)) == 0)) {
355 if ((ilgen
== null) || (ilgen
.ILOffset
== 0))
356 throw new InvalidOperationException ("Method '" + Name
+ "' does not have a method body.");
359 ilgen
.label_fixup ();
362 internal void GenerateDebugInfo (ISymbolWriter symbolWriter
)
364 if (ilgen
!= null && ilgen
.HasDebugInfo
) {
365 SymbolToken token
= new SymbolToken (GetToken().Token
);
366 symbolWriter
.OpenMethod (token
);
367 symbolWriter
.SetSymAttribute (token
, "__name", System
.Text
.Encoding
.UTF8
.GetBytes (Name
));
368 ilgen
.GenerateDebugInfo (symbolWriter
);
369 symbolWriter
.CloseMethod ();
373 internal override int get_next_table_index (object obj
, int table
, bool inc
)
375 return type
.get_next_table_index (obj
, table
, inc
);
378 private bool IsCompilerContext
{
380 ModuleBuilder mb
= (ModuleBuilder
) TypeBuilder
.Module
;
381 AssemblyBuilder ab
= (AssemblyBuilder
) mb
.Assembly
;
382 return ab
.IsCompilerContext
;
386 private void RejectIfCreated ()
389 throw new InvalidOperationException ("Type definition of the method is complete.");
392 private Exception
not_supported ()
394 return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
397 private Exception
not_after_created ()
399 return new InvalidOperationException ("Unable to change after type has been created.");
402 private Exception
not_created ()
404 return new NotSupportedException ("The type is not yet created.");
407 void _ConstructorBuilder
.GetIDsOfNames ([In
] ref Guid riid
, IntPtr rgszNames
, uint cNames
, uint lcid
, IntPtr rgDispId
)
409 throw new NotImplementedException ();
412 void _ConstructorBuilder
.GetTypeInfo (uint iTInfo
, uint lcid
, IntPtr ppTInfo
)
414 throw new NotImplementedException ();
417 void _ConstructorBuilder
.GetTypeInfoCount (out uint pcTInfo
)
419 throw new NotImplementedException ();
422 void _ConstructorBuilder
.Invoke (uint dispIdMember
, [In
] ref Guid riid
, uint lcid
, short wFlags
, IntPtr pDispParams
, IntPtr pVarResult
, IntPtr pExcepInfo
, IntPtr puArgErr
)
424 throw new NotImplementedException ();