1 // 2 // MethodReference.cs 3 // 4 // Author: 5 // Jb Evain (jbevain@gmail.com) 6 // 7 // Copyright (c) 2008 - 2011 Jb Evain 8 // 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: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 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. 27 // 28 29 using System; 30 using System.Text; 31 32 using Mono.Collections.Generic; 33 34 namespace Mono.Cecil { 35 36 public class MethodReference : MemberReference, IMethodSignature, IGenericParameterProvider, IGenericContext { 37 38 internal ParameterDefinitionCollection parameters; 39 MethodReturnType return_type; 40 41 bool has_this; 42 bool explicit_this; 43 MethodCallingConvention calling_convention; 44 internal Collection<GenericParameter> generic_parameters; 45 46 public virtual bool HasThis { 47 get { return has_this; } 48 set { has_this = value; } 49 } 50 51 public virtual bool ExplicitThis { 52 get { return explicit_this; } 53 set { explicit_this = value; } 54 } 55 56 public virtual MethodCallingConvention CallingConvention { 57 get { return calling_convention; } 58 set { calling_convention = value; } 59 } 60 61 public virtual bool HasParameters { 62 get { return !parameters.IsNullOrEmpty (); } 63 } 64 65 public virtual Collection<ParameterDefinition> Parameters { 66 get { 67 if (parameters == null) 68 parameters = new ParameterDefinitionCollection (this); 69 70 return parameters; 71 } 72 } 73 74 IGenericParameterProvider IGenericContext.Type { 75 get { 76 var declaring_type = this.DeclaringType; 77 var instance = declaring_type as GenericInstanceType; 78 if (instance != null) 79 return instance.ElementType; 80 81 return declaring_type; 82 } 83 } 84 85 IGenericParameterProvider IGenericContext.Method { 86 get { return this; } 87 } 88 89 GenericParameterType IGenericParameterProvider.GenericParameterType { 90 get { return GenericParameterType.Method; } 91 } 92 93 public virtual bool HasGenericParameters { 94 get { return !generic_parameters.IsNullOrEmpty (); } 95 } 96 97 public virtual Collection<GenericParameter> GenericParameters { 98 get { 99 if (generic_parameters != null) 100 return generic_parameters; 101 102 return generic_parameters = new GenericParameterCollection (this); 103 } 104 } 105 106 public TypeReference ReturnType { 107 get { 108 var return_type = MethodReturnType; 109 return return_type != null ? return_type.ReturnType : null; 110 } 111 set { 112 var return_type = MethodReturnType; 113 if (return_type != null) 114 return_type.ReturnType = value; 115 } 116 } 117 118 public virtual MethodReturnType MethodReturnType { 119 get { return return_type; } 120 set { return_type = value; } 121 } 122 123 public override string FullName { 124 get { 125 var builder = new StringBuilder (); 126 builder.Append (ReturnType.FullName) 127 .Append (" ") 128 .Append (MemberFullName ()); 129 this.MethodSignatureFullName (builder); 130 return builder.ToString (); 131 } 132 } 133 134 public virtual bool IsGenericInstance { 135 get { return false; } 136 } 137 138 internal override bool ContainsGenericParameter { 139 get { 140 if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter) 141 return true; 142 143 var parameters = this.Parameters; 144 145 for (int i = 0; i < parameters.Count; i++) 146 if (parameters [i].ParameterType.ContainsGenericParameter) 147 return true; 148 149 return false; 150 } 151 } 152 MethodReference()153 internal MethodReference () 154 { 155 this.return_type = new MethodReturnType (this); 156 this.token = new MetadataToken (TokenType.MemberRef); 157 } 158 MethodReference(string name, TypeReference returnType)159 public MethodReference (string name, TypeReference returnType) 160 : base (name) 161 { 162 if (returnType == null) 163 throw new ArgumentNullException ("returnType"); 164 165 this.return_type = new MethodReturnType (this); 166 this.return_type.ReturnType = returnType; 167 this.token = new MetadataToken (TokenType.MemberRef); 168 } 169 MethodReference(string name, TypeReference returnType, TypeReference declaringType)170 public MethodReference (string name, TypeReference returnType, TypeReference declaringType) 171 : this (name, returnType) 172 { 173 if (declaringType == null) 174 throw new ArgumentNullException ("declaringType"); 175 176 this.DeclaringType = declaringType; 177 } 178 GetElementMethod()179 public virtual MethodReference GetElementMethod () 180 { 181 return this; 182 } 183 Resolve()184 public virtual MethodDefinition Resolve () 185 { 186 var module = this.Module; 187 if (module == null) 188 throw new NotSupportedException (); 189 190 return module.Resolve (this); 191 } 192 } 193 194 static partial class Mixin { 195 IsVarArg(this IMethodSignature self)196 public static bool IsVarArg (this IMethodSignature self) 197 { 198 return (self.CallingConvention & MethodCallingConvention.VarArg) != 0; 199 } 200 GetSentinelPosition(this IMethodSignature self)201 public static int GetSentinelPosition (this IMethodSignature self) 202 { 203 if (!self.HasParameters) 204 return -1; 205 206 var parameters = self.Parameters; 207 for (int i = 0; i < parameters.Count; i++) 208 if (parameters [i].ParameterType.IsSentinel) 209 return i; 210 211 return -1; 212 } 213 } 214 } 215