/Mono.Cecil/MethodReference.cs

http://github.com/jbevain/cecil · C# · 202 lines · 152 code · 41 blank · 9 comment · 20 complexity · 1a8cf78474581aa7d5588c5853195179 MD5 · raw file

  1. //
  2. // Author:
  3. // Jb Evain (jbevain@gmail.com)
  4. //
  5. // Copyright (c) 2008 - 2015 Jb Evain
  6. // Copyright (c) 2008 - 2011 Novell, Inc.
  7. //
  8. // Licensed under the MIT/X11 license.
  9. //
  10. using System;
  11. using System.Text;
  12. using System.Threading;
  13. using Mono.Collections.Generic;
  14. namespace Mono.Cecil {
  15. public class MethodReference : MemberReference, IMethodSignature, IGenericParameterProvider, IGenericContext {
  16. internal ParameterDefinitionCollection parameters;
  17. MethodReturnType return_type;
  18. bool has_this;
  19. bool explicit_this;
  20. MethodCallingConvention calling_convention;
  21. internal Collection<GenericParameter> generic_parameters;
  22. public virtual bool HasThis {
  23. get { return has_this; }
  24. set { has_this = value; }
  25. }
  26. public virtual bool ExplicitThis {
  27. get { return explicit_this; }
  28. set { explicit_this = value; }
  29. }
  30. public virtual MethodCallingConvention CallingConvention {
  31. get { return calling_convention; }
  32. set { calling_convention = value; }
  33. }
  34. public virtual bool HasParameters {
  35. get { return !parameters.IsNullOrEmpty (); }
  36. }
  37. public virtual Collection<ParameterDefinition> Parameters {
  38. get {
  39. if (parameters == null)
  40. Interlocked.CompareExchange (ref parameters, new ParameterDefinitionCollection (this), null);
  41. return parameters;
  42. }
  43. }
  44. IGenericParameterProvider IGenericContext.Type {
  45. get {
  46. var declaring_type = this.DeclaringType;
  47. var instance = declaring_type as GenericInstanceType;
  48. if (instance != null)
  49. return instance.ElementType;
  50. return declaring_type;
  51. }
  52. }
  53. IGenericParameterProvider IGenericContext.Method {
  54. get { return this; }
  55. }
  56. GenericParameterType IGenericParameterProvider.GenericParameterType {
  57. get { return GenericParameterType.Method; }
  58. }
  59. public virtual bool HasGenericParameters {
  60. get { return !generic_parameters.IsNullOrEmpty (); }
  61. }
  62. public virtual Collection<GenericParameter> GenericParameters {
  63. get {
  64. if (generic_parameters == null)
  65. Interlocked.CompareExchange (ref generic_parameters, new GenericParameterCollection (this), null);
  66. return generic_parameters;
  67. }
  68. }
  69. public TypeReference ReturnType {
  70. get {
  71. var return_type = MethodReturnType;
  72. return return_type != null ? return_type.ReturnType : null;
  73. }
  74. set {
  75. var return_type = MethodReturnType;
  76. if (return_type != null)
  77. return_type.ReturnType = value;
  78. }
  79. }
  80. public virtual MethodReturnType MethodReturnType {
  81. get { return return_type; }
  82. set { return_type = value; }
  83. }
  84. public override string FullName {
  85. get {
  86. var builder = new StringBuilder ();
  87. builder.Append (ReturnType.FullName)
  88. .Append (" ")
  89. .Append (MemberFullName ());
  90. this.MethodSignatureFullName (builder);
  91. return builder.ToString ();
  92. }
  93. }
  94. public virtual bool IsGenericInstance {
  95. get { return false; }
  96. }
  97. public override bool ContainsGenericParameter {
  98. get {
  99. if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter)
  100. return true;
  101. if (!HasParameters)
  102. return false;
  103. var parameters = this.Parameters;
  104. for (int i = 0; i < parameters.Count; i++)
  105. if (parameters [i].ParameterType.ContainsGenericParameter)
  106. return true;
  107. return false;
  108. }
  109. }
  110. internal MethodReference ()
  111. {
  112. this.return_type = new MethodReturnType (this);
  113. this.token = new MetadataToken (TokenType.MemberRef);
  114. }
  115. public MethodReference (string name, TypeReference returnType)
  116. : base (name)
  117. {
  118. Mixin.CheckType (returnType, Mixin.Argument.returnType);
  119. this.return_type = new MethodReturnType (this);
  120. this.return_type.ReturnType = returnType;
  121. this.token = new MetadataToken (TokenType.MemberRef);
  122. }
  123. public MethodReference (string name, TypeReference returnType, TypeReference declaringType)
  124. : this (name, returnType)
  125. {
  126. Mixin.CheckType (declaringType, Mixin.Argument.declaringType);
  127. this.DeclaringType = declaringType;
  128. }
  129. public virtual MethodReference GetElementMethod ()
  130. {
  131. return this;
  132. }
  133. protected override IMemberDefinition ResolveDefinition ()
  134. {
  135. return this.Resolve ();
  136. }
  137. public new virtual MethodDefinition Resolve ()
  138. {
  139. var module = this.Module;
  140. if (module == null)
  141. throw new NotSupportedException ();
  142. return module.Resolve (this);
  143. }
  144. }
  145. static partial class Mixin {
  146. public static bool IsVarArg (this IMethodSignature self)
  147. {
  148. return self.CallingConvention == MethodCallingConvention.VarArg;
  149. }
  150. public static int GetSentinelPosition (this IMethodSignature self)
  151. {
  152. if (!self.HasParameters)
  153. return -1;
  154. var parameters = self.Parameters;
  155. for (int i = 0; i < parameters.Count; i++)
  156. if (parameters [i].ParameterType.IsSentinel)
  157. return i;
  158. return -1;
  159. }
  160. }
  161. }