Mono.CSharp.MetadataImporter.CreateMethod C# (CSharp) Method

CreateMethod() public method

public CreateMethod ( MethodBase mb, System.TypeSpec declaringType ) : MethodSpec
mb MethodBase
declaringType System.TypeSpec
return MethodSpec
        public MethodSpec CreateMethod(MethodBase mb, TypeSpec declaringType)
        {
            Modifiers mod = ReadMethodModifiers (mb, declaringType);
            TypeParameterSpec[] tparams;

            var parameters = CreateParameters (declaringType, mb.GetParameters (), mb);

            if (mb.IsGenericMethod) {
                if (!mb.IsGenericMethodDefinition)
                    throw new NotSupportedException ("assert");

                tparams = CreateGenericParameters (0, mb.GetGenericArguments ());
            } else {
                tparams = null;
            }

            MemberKind kind;
            TypeSpec returnType;
            if (mb.MemberType == MemberTypes.Constructor) {
                kind = MemberKind.Constructor;
                returnType = TypeManager.void_type;
            } else {
                //
                // Detect operators and destructors
                //
                string name = mb.Name;
                kind = MemberKind.Method;
                if (tparams == null && !mb.DeclaringType.IsInterface && name.Length > 6) {
                    if ((mod & (Modifiers.STATIC | Modifiers.PUBLIC)) == (Modifiers.STATIC | Modifiers.PUBLIC)) {
                        if (name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
                            var op_type = Operator.GetType (name);
                            if (op_type.HasValue && parameters.Count > 0 && parameters.Count < 3) {
                                kind = MemberKind.Operator;
                            }
                        }
                    } else if (parameters.IsEmpty && name == Destructor.MetadataName) {
                        kind = MemberKind.Destructor;
                        if (declaringType == TypeManager.object_type) {
                            mod &= ~Modifiers.OVERRIDE;
                            mod |= Modifiers.VIRTUAL;
                        }
                    }
                }

                var mi = (MethodInfo) mb;
                returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter));

                // Cannot set to OVERRIDE without full hierarchy checks
                // this flag indicates that the method could be override
                // but further validation is needed
                if ((mod & Modifiers.OVERRIDE) != 0 && kind == MemberKind.Method && declaringType.BaseType != null) {
                    var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
                    var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None);

                    //
                    // For imported class method do additional validation to be sure that metadata
                    // override flag was correct
                    //
                    // Difference between protected internal and protected is ok
                    //
                    const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
                    if (candidate == null || (candidate.Modifiers & conflict_mask) != (mod & conflict_mask) || candidate.IsStatic) {
                        mod &= ~Modifiers.OVERRIDE;
                        mod |= Modifiers.VIRTUAL;
                    }
                }
            }

            IMemberDefinition definition;
            if (tparams != null) {
                var gmd = new ImportedGenericMethodDefinition ((MethodInfo) mb, returnType, parameters, tparams, this);
                foreach (var tp in gmd.TypeParameters) {
                    ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ());
                }

                definition = gmd;
            } else {
                definition = new ImportedParameterMemberDefinition (mb, returnType, parameters, this);
            }

            MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
            if (tparams != null)
                ms.IsGeneric = true;

            return ms;
        }