MethodReference.cs 5.0 KB

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