2 // System.Reflection.Emit/MethodOnTypeBuilderInst.cs
5 // Zoltan Varga (vargaz@gmail.com)
8 // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Globalization
;
32 using System
.Reflection
;
35 namespace System
.Reflection
.Emit
38 * This class represents a method of an instantiation of a generic type builder.
40 internal class MethodOnTypeBuilderInst
: MethodInfo
42 #region Keep in sync with object-internals.h
44 MethodInfo base_method
; /*This is the base method definition, it must be non-inflated and belong to a non-inflated type.*/
45 Type
[] method_arguments
;
47 MethodInfo generic_method_definition
;
48 int is_compiler_context
= -1;
50 public MethodOnTypeBuilderInst (MonoGenericClass instantiation
, MethodInfo base_method
)
52 this.instantiation
= instantiation
;
53 this.base_method
= base_method
;
56 internal MethodOnTypeBuilderInst (MethodOnTypeBuilderInst gmd
, Type
[] typeArguments
)
58 this.instantiation
= gmd
.instantiation
;
59 this.base_method
= gmd
.base_method
;
60 this.method_arguments
= new Type
[typeArguments
.Length
];
61 typeArguments
.CopyTo (this.method_arguments
, 0);
62 this.generic_method_definition
= gmd
;
65 internal MethodOnTypeBuilderInst (MethodInfo method
, Type
[] typeArguments
)
67 this.instantiation
= method
.DeclaringType
;
68 this.base_method
= ExtractBaseMethod (method
);
69 this.method_arguments
= new Type
[typeArguments
.Length
];
70 typeArguments
.CopyTo (this.method_arguments
, 0);
71 if (base_method
!= method
)
72 this.generic_method_definition
= method
;
75 static MethodInfo
ExtractBaseMethod (MethodInfo info
)
77 if (info
is MethodBuilder
)
79 if (info
is MethodOnTypeBuilderInst
)
80 return ((MethodOnTypeBuilderInst
)info
).base_method
;
82 if (info
.IsGenericMethod
)
83 info
= info
.GetGenericMethodDefinition ();
85 Type t
= info
.DeclaringType
;
86 if (!t
.IsGenericType
|| t
.IsGenericTypeDefinition
)
89 return (MethodInfo
)t
.Module
.ResolveMethod (info
.MetadataToken
);
92 internal Type
[] GetTypeArgs ()
94 if (!instantiation
.IsGenericType
|| instantiation
.IsGenericParameter
)
97 return instantiation
.GetGenericArguments ();
100 internal bool IsCompilerContext
{
102 if (is_compiler_context
== -1) {
104 is_cc
|= instantiation
.IsCompilerContext
;
105 if (!is_cc
&& method_arguments
!= null) {
106 foreach (Type t
in method_arguments
)
107 is_cc
|= t
.IsCompilerContext
;
109 is_compiler_context
= is_cc
? 1 : 0;
111 return is_compiler_context
== 1;
116 // MemberInfo members
119 public override Type DeclaringType
{
121 return instantiation
;
125 public override string Name
{
127 return base_method
.Name
;
131 public override Type ReflectedType
{
133 return instantiation
;
137 public override Type ReturnType
{
139 if (!IsCompilerContext
)
140 return base_method
.ReturnType
;
141 return MonoGenericClass
.InflateType (base_method
.ReturnType
, GetTypeArgs (), method_arguments
);
145 public override bool IsDefined (Type attributeType
, bool inherit
)
147 if (!IsCompilerContext
)
148 throw new NotSupportedException ();
149 return base_method
.IsDefined (attributeType
, inherit
);
152 public override object [] GetCustomAttributes (bool inherit
)
154 if (!IsCompilerContext
)
155 throw new NotSupportedException ();
156 return base_method
.GetCustomAttributes (inherit
);
159 public override object [] GetCustomAttributes (Type attributeType
, bool inherit
)
161 if (!IsCompilerContext
)
162 throw new NotSupportedException ();
163 return base_method
.GetCustomAttributes (attributeType
, inherit
);
166 public override string ToString ()
168 //IEnumerable`1 get_Item(TKey)
169 StringBuilder sb
= new StringBuilder (ReturnType
.ToString ());
171 sb
.Append (base_method
.Name
);
173 if (IsCompilerContext
) {
174 ParameterInfo
[] par
= GetParameters ();
175 for (int i
= 0; i
< par
.Length
; ++i
) {
178 sb
.Append (par
[i
].ParameterType
);
182 return sb
.ToString ();
185 // MethodBase members
188 public override MethodImplAttributes
GetMethodImplementationFlags ()
190 return base_method
.GetMethodImplementationFlags ();
193 public override ParameterInfo
[] GetParameters ()
195 ParameterInfo
[] res
= null;
196 if (!IsCompilerContext
)
197 throw new NotSupportedException ();
199 if (base_method
is MethodBuilder
) {
200 MethodBuilder mb
= (MethodBuilder
)base_method
;
201 res
= new ParameterInfo
[mb
.parameters
.Length
];
202 for (int i
= 0; i
< mb
.parameters
.Length
; i
++) {
203 Type type
= MonoGenericClass
.InflateType (mb
.parameters
[i
], GetTypeArgs (), method_arguments
);
204 res
[i
] = new ParameterInfo (mb
.pinfo
== null ? null : mb
.pinfo
[i
+ 1], type
, this, i
+ 1);
207 ParameterInfo
[] base_params
= base_method
.GetParameters ();
208 res
= new ParameterInfo
[base_params
.Length
];
209 for (int i
= 0; i
< base_params
.Length
; i
++) {
210 Type type
= MonoGenericClass
.InflateType (base_params
[i
].ParameterType
, GetTypeArgs (), method_arguments
);
211 res
[i
] = new ParameterInfo (base_params
[i
], type
, this, i
+ 1);
217 public override int MetadataToken
{
219 if (!IsCompilerContext
)
220 return base.MetadataToken
;
221 return base_method
.MetadataToken
;
225 internal override int GetParameterCount ()
227 return base_method
.GetParameterCount ();
230 public override Object
Invoke(Object obj
, BindingFlags invokeAttr
, Binder binder
, Object
[] parameters
, CultureInfo culture
)
232 throw new NotSupportedException ();
235 public override RuntimeMethodHandle MethodHandle
{
237 throw new NotSupportedException ();
241 public override MethodAttributes Attributes
{
243 return base_method
.Attributes
;
247 public override CallingConventions CallingConvention
{
249 return base_method
.CallingConvention
;
253 public override MethodInfo
MakeGenericMethod (params Type
[] methodInstantiation
)
255 if (!base_method
.IsGenericMethodDefinition
|| (method_arguments
!= null && !IsCompilerContext
))
256 throw new InvalidOperationException ("Method is not a generic method definition");
258 if (methodInstantiation
== null)
259 throw new ArgumentNullException ("methodInstantiation");
261 if (base_method
.GetGenericArguments ().Length
!= methodInstantiation
.Length
)
262 throw new ArgumentException ("Incorrect length", "methodInstantiation");
264 foreach (Type type
in methodInstantiation
) {
266 throw new ArgumentNullException ("methodInstantiation");
269 return new MethodOnTypeBuilderInst (this, methodInstantiation
);
272 public override Type
[] GetGenericArguments ()
274 if (!base_method
.IsGenericMethodDefinition
)
276 Type
[] source
= method_arguments
?? base_method
.GetGenericArguments ();
277 Type
[] result
= new Type
[source
.Length
];
278 source
.CopyTo (result
, 0);
282 public override MethodInfo
GetGenericMethodDefinition ()
284 return generic_method_definition
?? base_method
;
287 public override bool ContainsGenericParameters
{
289 if (base_method
.ContainsGenericParameters
)
291 if (!base_method
.IsGenericMethodDefinition
)
292 throw new NotSupportedException ();
293 if (method_arguments
== null)
295 foreach (Type t
in method_arguments
) {
296 if (t
.ContainsGenericParameters
)
303 public override bool IsGenericMethodDefinition
{
305 return base_method
.IsGenericMethodDefinition
&& method_arguments
== null;
309 public override bool IsGenericMethod
{
311 return base_method
.IsGenericMethodDefinition
;
316 // MethodInfo members
319 public override MethodInfo
GetBaseDefinition ()
321 throw new NotSupportedException ();
324 public override ICustomAttributeProvider ReturnTypeCustomAttributes
{
326 throw new NotSupportedException ();