PageRenderTime 26ms CodeModel.GetById 14ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

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