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 = module.Compiler.BuiltinTypes.Void; } 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.BuiltinType == BuiltinTypeSpec.Type.Object) { 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) { bool is_real_override = false; if (kind == MemberKind.Method && declaringType.BaseType != null) { var btype = declaringType.BaseType; if (IsOverrideMethodBaseTypeAccessible (btype)) { var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null); var candidate = MemberCache.FindMember (btype, 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) { is_real_override = true; } } } if (!is_real_override) { mod &= ~Modifiers.OVERRIDE; if ((mod & Modifiers.SEALED) != 0) mod &= ~Modifiers.SEALED; else 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; }
public MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType) { Modifiers mod = ReadMethodModifiers (mb, declaringType); TypeParameterSpec[] tparams; ImportedMethodDefinition definition; var parameters = CreateParameters (declaringType, mb.GetParameters (), mb); if (mb.IsGenericMethod) { if (!mb.IsGenericMethodDefinition) throw new NotSupportedException ("assert"); tparams = CreateGenericParameters (0, mb.GetGenericArguments ()); definition = new ImportedGenericMethodDefinition ((MethodInfo) mb, parameters, tparams); } else { definition = new ImportedMethodDefinition (mb, parameters); 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, mi.ReturnTypeCustomAttributes, 0); // 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; } } } MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod); if (tparams != null) ms.IsGeneric = true; return ms; }