+ TypeParameterSpec[] TypeParameters { get; }
+ int TypeParametersCount { get; }
+
+// MethodInfo MakeGenericMethod (TypeSpec[] targs);
+ }
+
+ public class MethodSpec : MemberSpec, IParametersMember
+ {
+ MethodBase metaInfo;
+ AParametersCollection parameters;
+ TypeSpec returnType;
+
+ TypeSpec[] targs;
+ TypeParameterSpec[] constraints;
+
+ public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
+ MethodBase info, AParametersCollection parameters, Modifiers modifiers)
+ : base (kind, declaringType, details, modifiers)
+ {
+ this.metaInfo = info;
+ this.parameters = parameters;
+ this.returnType = returnType;
+ }
+
+ #region Properties
+
+ public override int Arity {
+ get {
+ return IsGeneric ? GenericDefinition.TypeParametersCount : 0;
+ }
+ }
+
+ public TypeParameterSpec[] Constraints {
+ get {
+ if (constraints == null && IsGeneric)
+ constraints = GenericDefinition.TypeParameters;
+
+ return constraints;
+ }
+ }
+
+ public bool IsConstructor {
+ get {
+ return Kind == MemberKind.Constructor;
+ }
+ }
+
+ public IGenericMethodDefinition GenericDefinition {
+ get {
+ return (IGenericMethodDefinition) definition;
+ }
+ }
+
+ public bool IsExtensionMethod {
+ get {
+ return IsStatic && parameters.HasExtensionMethodType;
+ }
+ }
+
+ public bool IsSealed {
+ get {
+ return (Modifiers & Modifiers.SEALED) != 0;
+ }
+ }
+
+ // When is virtual or abstract
+ public bool IsVirtual {
+ get {
+ return (Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != 0;
+ }
+ }
+
+ public bool IsReservedMethod {
+ get {
+ return Kind == MemberKind.Operator || IsAccessor;
+ }
+ }
+
+ TypeSpec IInterfaceMemberSpec.MemberType {
+ get {
+ return returnType;
+ }
+ }
+
+ public AParametersCollection Parameters {
+ get {
+ return parameters;
+ }
+ }
+
+ public TypeSpec ReturnType {
+ get {
+ return returnType;
+ }
+ }
+
+ public TypeSpec[] TypeArguments {
+ get {
+ return targs;
+ }
+ }
+
+ #endregion
+
+ public MethodSpec GetGenericMethodDefinition ()
+ {
+ if (!IsGeneric && !DeclaringType.IsGeneric)
+ return this;
+
+ return MemberCache.GetMember (declaringType, this);
+ }
+
+ public MethodBase GetMetaInfo ()
+ {
+ if ((state & StateFlags.PendingMetaInflate) != 0) {
+ if (DeclaringType.IsTypeBuilder) {
+ if (IsConstructor)
+ metaInfo = TypeBuilder.GetConstructor (DeclaringType.GetMetaInfo (), (ConstructorInfo) metaInfo);
+ else
+ metaInfo = TypeBuilder.GetMethod (DeclaringType.GetMetaInfo (), (MethodInfo) metaInfo);
+ } else {
+ metaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, DeclaringType.GetMetaInfo ().TypeHandle);
+ }
+
+ state &= ~StateFlags.PendingMetaInflate;
+ }
+
+ if ((state & StateFlags.PendingMakeMethod) != 0) {
+ var sre_targs = new Type[targs.Length];
+ for (int i = 0; i < sre_targs.Length; ++i)
+ sre_targs[i] = targs[i].GetMetaInfo ();
+
+ metaInfo = ((MethodInfo) metaInfo).MakeGenericMethod (sre_targs);
+ state &= ~StateFlags.PendingMakeMethod;
+ }
+
+ return metaInfo;
+ }
+
+ public override string GetSignatureForError ()
+ {
+ string name;
+ if (IsConstructor) {
+ name = DeclaringType.GetSignatureForError () + "." + DeclaringType.Name;
+ } else if (Kind == MemberKind.Operator) {
+ var op = Operator.GetType (Name).Value;
+ if (op == Operator.OpType.Implicit || op == Operator.OpType.Explicit) {
+ name = DeclaringType.GetSignatureForError () + "." + Operator.GetName (op) + " operator " + returnType.GetSignatureForError ();
+ } else {
+ name = DeclaringType.GetSignatureForError () + ".operator " + Operator.GetName (op);
+ }
+ } else if (IsAccessor) {
+ int split = Name.IndexOf ('_');
+ name = Name.Substring (split + 1);
+ var postfix = Name.Substring (0, split);
+ if (split == 3) {
+ var pc = parameters.Count;
+ if (pc > 0 && postfix == "get") {
+ name = "this" + parameters.GetSignatureForError ("[", "]", pc);
+ } else if (pc > 1 && postfix == "set") {
+ name = "this" + parameters.GetSignatureForError ("[", "]", pc - 1);
+ }
+ }
+
+ return DeclaringType.GetSignatureForError () + "." + name + "." + postfix;
+ } else {
+ name = base.GetSignatureForError ();
+ if (targs != null)
+ name += "<" + TypeManager.CSharpName (targs) + ">";
+ else if (IsGeneric)
+ name += "<" + TypeManager.CSharpName (GenericDefinition.TypeParameters) + ">";
+ }
+
+ return name + parameters.GetSignatureForError ();
+ }
+
+ public override MemberSpec InflateMember (TypeParameterInflator inflator)
+ {
+ var ms = (MethodSpec) base.InflateMember (inflator);
+ ms.returnType = inflator.Inflate (returnType);
+ ms.parameters = parameters.Inflate (inflator);
+ if (IsGeneric)
+ ms.constraints = TypeParameterSpec.InflateConstraints (inflator, Constraints);