5 // Jb Evain (jbevain@gmail.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 namespace Mono.Cecil {
31 using Mono.Cecil.Binary;
34 internal sealed class MethodDefinition : MethodReference, IMemberDefinition,
35 IHasSecurity, ICustomAttributeProvider {
37 public const string Cctor = ".cctor";
38 public const string Ctor = ".ctor";
40 MethodAttributes m_attributes;
41 MethodImplAttributes m_implAttrs;
42 MethodSemanticsAttributes m_semAttrs;
43 SecurityDeclarationCollection m_secDecls;
44 CustomAttributeCollection m_customAttrs;
48 OverrideCollection m_overrides;
49 PInvokeInfo m_pinvoke;
50 readonly ParameterDefinition m_this;
52 public MethodAttributes Attributes {
53 get { return m_attributes; }
54 set { m_attributes = value; }
57 public MethodImplAttributes ImplAttributes {
58 get { return m_implAttrs; }
59 set { m_implAttrs = value; }
62 public MethodSemanticsAttributes SemanticsAttributes {
63 get { return m_semAttrs; }
64 set { m_semAttrs = value; }
67 public bool HasSecurityDeclarations {
68 get { return (m_secDecls == null) ? false : (m_secDecls.Count > 0); }
71 public SecurityDeclarationCollection SecurityDeclarations {
73 if (m_secDecls == null)
74 m_secDecls = new SecurityDeclarationCollection (this);
80 public bool HasCustomAttributes {
81 get { return (m_customAttrs == null) ? false : (m_customAttrs.Count > 0); }
84 public CustomAttributeCollection CustomAttributes {
86 if (m_customAttrs == null)
87 m_customAttrs = new CustomAttributeCollection (this);
95 set { m_rva = value; }
98 public MethodBody Body {
103 set { m_body = value; }
106 public PInvokeInfo PInvokeInfo {
107 get { return m_pinvoke; }
108 set { m_pinvoke = value; }
111 public bool HasOverrides {
112 get { return (m_overrides == null) ? false : (m_overrides.Count > 0); }
115 public OverrideCollection Overrides {
117 if (m_overrides == null)
118 m_overrides = new OverrideCollection (this);
124 public ParameterDefinition This {
125 get { return m_this; }
128 #region MethodAttributes
130 public bool IsCompilerControlled {
131 get { return (m_attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Compilercontrolled; }
134 m_attributes &= ~MethodAttributes.MemberAccessMask;
135 m_attributes |= MethodAttributes.Compilercontrolled;
137 m_attributes &= ~(MethodAttributes.MemberAccessMask & MethodAttributes.Compilercontrolled);
141 public bool IsPrivate {
142 get { return (m_attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; }
145 m_attributes &= ~MethodAttributes.MemberAccessMask;
146 m_attributes |= MethodAttributes.Private;
148 m_attributes &= ~(MethodAttributes.MemberAccessMask & MethodAttributes.Private);
152 public bool IsFamilyAndAssembly {
153 get { return (m_attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; }
156 m_attributes &= ~MethodAttributes.MemberAccessMask;
157 m_attributes |= MethodAttributes.FamANDAssem;
159 m_attributes &= ~(MethodAttributes.MemberAccessMask & MethodAttributes.FamANDAssem);
163 public bool IsAssembly {
164 get { return (m_attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assem; }
167 m_attributes &= ~MethodAttributes.MemberAccessMask;
168 m_attributes |= MethodAttributes.Assem;
170 m_attributes &= ~(MethodAttributes.MemberAccessMask & MethodAttributes.Assem);
174 public bool IsFamily {
175 get { return (m_attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; }
178 m_attributes &= ~MethodAttributes.MemberAccessMask;
179 m_attributes |= MethodAttributes.Family;
181 m_attributes &= ~(MethodAttributes.MemberAccessMask & MethodAttributes.Family);
185 public bool IsFamilyOrAssembly {
186 get { return (m_attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; }
189 m_attributes &= ~MethodAttributes.MemberAccessMask;
190 m_attributes |= MethodAttributes.FamORAssem;
192 m_attributes &= ~(MethodAttributes.MemberAccessMask & MethodAttributes.FamORAssem);
196 public bool IsPublic {
197 get { return (m_attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; }
200 m_attributes &= ~MethodAttributes.MemberAccessMask;
201 m_attributes |= MethodAttributes.Public;
203 m_attributes &= ~(MethodAttributes.MemberAccessMask & MethodAttributes.Public);
207 public bool IsStatic {
208 get { return (m_attributes & MethodAttributes.Static) != 0; }
211 m_attributes |= MethodAttributes.Static;
213 m_attributes &= ~MethodAttributes.Static;
217 public bool IsFinal {
218 get { return (m_attributes & MethodAttributes.Final) != 0; }
221 m_attributes |= MethodAttributes.Final;
223 m_attributes &= ~MethodAttributes.Final;
227 public bool IsVirtual {
228 get { return (m_attributes & MethodAttributes.Virtual) != 0; }
231 m_attributes |= MethodAttributes.Virtual;
233 m_attributes &= ~MethodAttributes.Virtual;
237 public bool IsHideBySig {
238 get { return (m_attributes & MethodAttributes.HideBySig) != 0; }
241 m_attributes |= MethodAttributes.HideBySig;
243 m_attributes &= ~MethodAttributes.HideBySig;
247 public bool IsReuseSlot {
248 get { return (m_attributes & MethodAttributes.VtableLayoutMask) == MethodAttributes.ReuseSlot; }
251 m_attributes &= ~MethodAttributes.VtableLayoutMask;
252 m_attributes |= MethodAttributes.ReuseSlot;
254 m_attributes &= ~(MethodAttributes.VtableLayoutMask & MethodAttributes.ReuseSlot);
258 public bool IsNewSlot {
259 get { return (m_attributes & MethodAttributes.VtableLayoutMask) == MethodAttributes.NewSlot; }
262 m_attributes &= ~MethodAttributes.VtableLayoutMask;
263 m_attributes |= MethodAttributes.NewSlot;
265 m_attributes &= ~(MethodAttributes.VtableLayoutMask & MethodAttributes.NewSlot);
269 public bool IsStrict {
270 get { return (m_attributes & MethodAttributes.Strict) != 0; }
273 m_attributes |= MethodAttributes.Strict;
275 m_attributes &= ~MethodAttributes.Strict;
279 public bool IsAbstract {
280 get { return (m_attributes & MethodAttributes.Abstract) != 0; }
283 m_attributes |= MethodAttributes.Abstract;
285 m_attributes &= ~MethodAttributes.Abstract;
289 public bool IsSpecialName {
290 get { return (m_attributes & MethodAttributes.SpecialName) != 0; }
293 m_attributes |= MethodAttributes.SpecialName;
295 m_attributes &= ~MethodAttributes.SpecialName;
299 public bool IsPInvokeImpl {
300 get { return (m_attributes & MethodAttributes.PInvokeImpl) != 0; }
303 m_attributes |= MethodAttributes.PInvokeImpl;
305 m_attributes &= ~MethodAttributes.PInvokeImpl;
309 public bool IsUnmanagedExport {
310 get { return (m_attributes & MethodAttributes.UnmanagedExport) != 0; }
313 m_attributes |= MethodAttributes.UnmanagedExport;
315 m_attributes &= ~MethodAttributes.UnmanagedExport;
319 public bool IsRuntimeSpecialName {
320 get { return (m_attributes & MethodAttributes.RTSpecialName) != 0; }
323 m_attributes |= MethodAttributes.RTSpecialName;
325 m_attributes &= ~MethodAttributes.RTSpecialName;
329 public bool HasSecurity {
330 get { return (m_attributes & MethodAttributes.HasSecurity) != 0; }
333 m_attributes |= MethodAttributes.HasSecurity;
335 m_attributes &= ~MethodAttributes.HasSecurity;
341 #region MethodImplAttributes
344 get { return (m_implAttrs & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.IL; }
347 m_implAttrs &= ~MethodImplAttributes.CodeTypeMask;
348 m_implAttrs |= MethodImplAttributes.IL;
350 m_implAttrs &= ~(MethodImplAttributes.CodeTypeMask & MethodImplAttributes.IL);
354 public bool IsNative {
355 get { return (m_implAttrs & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Native; }
358 m_implAttrs &= ~MethodImplAttributes.CodeTypeMask;
359 m_implAttrs |= MethodImplAttributes.Native;
361 m_implAttrs &= ~(MethodImplAttributes.CodeTypeMask & MethodImplAttributes.Native);
365 public bool IsRuntime {
366 get { return (m_implAttrs & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Runtime; }
369 m_implAttrs &= ~MethodImplAttributes.CodeTypeMask;
370 m_implAttrs |= MethodImplAttributes.Runtime;
372 m_implAttrs &= ~(MethodImplAttributes.CodeTypeMask & MethodImplAttributes.Runtime);
376 public bool IsUnmanaged {
377 get { return (m_implAttrs & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Unmanaged; }
380 m_implAttrs &= ~MethodImplAttributes.ManagedMask;
381 m_implAttrs |= MethodImplAttributes.Unmanaged;
383 m_implAttrs &= ~(MethodImplAttributes.ManagedMask & MethodImplAttributes.Unmanaged);
387 public bool IsManaged {
388 get { return (m_implAttrs & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed; }
391 m_implAttrs &= ~MethodImplAttributes.ManagedMask;
392 m_implAttrs |= MethodImplAttributes.Managed;
394 m_implAttrs &= ~(MethodImplAttributes.ManagedMask & MethodImplAttributes.Managed);
398 public bool IsForwardRef {
399 get { return (m_implAttrs & MethodImplAttributes.ForwardRef) != 0; }
402 m_implAttrs |= MethodImplAttributes.ForwardRef;
404 m_implAttrs &= ~MethodImplAttributes.ForwardRef;
408 public bool IsPreserveSig {
409 get { return (m_implAttrs & MethodImplAttributes.PreserveSig) != 0; }
412 m_implAttrs |= MethodImplAttributes.PreserveSig;
414 m_implAttrs &= ~MethodImplAttributes.PreserveSig;
418 public bool IsInternalCall {
419 get { return (m_implAttrs & MethodImplAttributes.InternalCall) != 0; }
422 m_implAttrs |= MethodImplAttributes.InternalCall;
424 m_implAttrs &= ~MethodImplAttributes.InternalCall;
428 public bool IsSynchronized {
429 get { return (m_implAttrs & MethodImplAttributes.Synchronized) != 0; }
432 m_implAttrs |= MethodImplAttributes.Synchronized;
434 m_implAttrs &= ~MethodImplAttributes.Synchronized;
438 public bool NoInlining {
439 get { return (m_implAttrs & MethodImplAttributes.NoInlining) != 0; }
442 m_implAttrs |= MethodImplAttributes.NoInlining;
444 m_implAttrs &= ~MethodImplAttributes.NoInlining;
450 #region MethodSemanticsAttributes
451 public bool IsSetter {
452 get { return (m_semAttrs & MethodSemanticsAttributes.Setter) != 0; }
455 m_semAttrs |= MethodSemanticsAttributes.Setter;
457 m_semAttrs &= ~MethodSemanticsAttributes.Setter;
461 public bool IsGetter {
462 get { return (m_semAttrs & MethodSemanticsAttributes.Getter) != 0; }
465 m_semAttrs |= MethodSemanticsAttributes.Getter;
467 m_semAttrs &= ~MethodSemanticsAttributes.Getter;
471 public bool IsOther {
472 get { return (m_semAttrs & MethodSemanticsAttributes.Other) != 0; }
475 m_semAttrs |= MethodSemanticsAttributes.Other;
477 m_semAttrs &= ~MethodSemanticsAttributes.Other;
481 public bool IsAddOn {
482 get { return (m_semAttrs & MethodSemanticsAttributes.AddOn) != 0; }
485 m_semAttrs |= MethodSemanticsAttributes.AddOn;
487 m_semAttrs &= ~MethodSemanticsAttributes.AddOn;
491 public bool IsRemoveOn {
492 get { return (m_semAttrs & MethodSemanticsAttributes.RemoveOn) != 0; }
495 m_semAttrs |= MethodSemanticsAttributes.RemoveOn;
497 m_semAttrs &= ~MethodSemanticsAttributes.RemoveOn;
502 get { return (m_semAttrs & MethodSemanticsAttributes.Fire) != 0; }
505 m_semAttrs |= MethodSemanticsAttributes.Fire;
507 m_semAttrs &= ~MethodSemanticsAttributes.Fire;
513 public bool IsConstructor {
515 return this.IsRuntimeSpecialName && this.IsSpecialName &&
516 (this.Name == Cctor || this.Name == Ctor);
520 public bool HasBody {
522 return (m_attributes & MethodAttributes.Abstract) == 0 &&
523 (m_attributes & MethodAttributes.PInvokeImpl) == 0 &&
524 (m_implAttrs & MethodImplAttributes.InternalCall) == 0 &&
525 (m_implAttrs & MethodImplAttributes.Native) == 0 &&
526 (m_implAttrs & MethodImplAttributes.Unmanaged) == 0 &&
527 (m_implAttrs & MethodImplAttributes.Runtime) == 0;
531 public new TypeDefinition DeclaringType {
532 get { return (TypeDefinition) base.DeclaringType; }
533 set { base.DeclaringType = value; }
536 public MethodDefinition (string name, RVA rva,
537 MethodAttributes attrs, MethodImplAttributes implAttrs,
538 bool hasThis, bool explicitThis, MethodCallingConvention callConv) :
539 base (name, hasThis, explicitThis, callConv)
542 m_attributes = attrs;
543 m_implAttrs = implAttrs;
546 m_this = new ParameterDefinition ("this", 0, (ParameterAttributes) 0, null);
549 internal MethodDefinition (string name, MethodAttributes attrs) : base (name)
551 m_attributes = attrs;
553 this.HasThis = !this.IsStatic;
555 m_this = new ParameterDefinition ("this", 0, (ParameterAttributes) 0, null);
558 public MethodDefinition (string name, MethodAttributes attrs, TypeReference returnType) :
561 this.ReturnType.ReturnType = returnType;
564 internal void LoadBody ()
566 if (m_body == null && this.HasBody) {
567 m_body = new MethodBody (this);
569 ModuleDefinition module = DeclaringType != null ? DeclaringType.Module : null;
571 if (module != null && m_rva != RVA.Zero)
572 module.Controller.Reader.Code.VisitMethodBody (m_body);
576 public override MethodDefinition Resolve ()
581 public MethodDefinition Clone ()
583 return Clone (this, new ImportContext (NullReferenceImporter.Instance, this));
586 internal static MethodDefinition Clone (MethodDefinition meth, ImportContext context)
588 MethodDefinition nm = new MethodDefinition (
595 meth.CallingConvention);
597 MethodReference contextMethod = context.GenericContext.Method;
599 context.GenericContext.Method = nm;
601 GenericParameter.CloneInto (meth, nm, context);
603 nm.ReturnType.ReturnType = context.Import (meth.ReturnType.ReturnType);
605 if (meth.ReturnType.Parameter != null) {
606 nm.ReturnType.Parameter = ParameterDefinition.Clone (meth.ReturnType.Parameter, context);
607 nm.ReturnType.Parameter.Method = nm;
610 if (meth.PInvokeInfo != null)
611 nm.PInvokeInfo = meth.PInvokeInfo; // TODO: import module ?
613 if (meth.HasParameters) {
614 foreach (ParameterDefinition param in meth.Parameters)
615 nm.Parameters.Add (ParameterDefinition.Clone (param, context));
617 if (meth.HasOverrides) {
618 foreach (MethodReference ov in meth.Overrides)
619 nm.Overrides.Add (context.Import (ov));
621 if (meth.HasCustomAttributes) {
622 foreach (CustomAttribute ca in meth.CustomAttributes)
623 nm.CustomAttributes.Add (CustomAttribute.Clone (ca, context));
625 if (meth.HasSecurityDeclarations) {
626 foreach (SecurityDeclaration sec in meth.SecurityDeclarations)
627 nm.SecurityDeclarations.Add (SecurityDeclaration.Clone (sec));
630 if (meth.Body != null)
631 nm.Body = MethodBody.Clone (meth.Body, nm, context);
633 context.GenericContext.Method = contextMethod;
638 public override void Accept (IReflectionVisitor visitor)
640 visitor.VisitMethodDefinition (this);
642 this.GenericParameters.Accept (visitor);
643 this.Parameters.Accept (visitor);
645 if (this.PInvokeInfo != null)
646 this.PInvokeInfo.Accept (visitor);
648 this.SecurityDeclarations.Accept (visitor);
649 this.Overrides.Accept (visitor);
650 this.CustomAttributes.Accept (visitor);