// mod = (mod & ~Modifiers.ABSTRACT) | Modifiers.VIRTUAL;
//}
- bool is_generic;
+ TypeParameterSpec[] tparams;
ImportedMethodDefinition definition;
var parameters = ParametersImported.Create (declaringType, mb);
if (!mb.IsGenericMethodDefinition)
throw new NotSupportedException ("assert");
- var tparams = CreateGenericParameters<TypeParameterSpec>(0, mb.GetGenericArguments ());
+ tparams = CreateGenericParameters<TypeParameterSpec>(0, mb.GetGenericArguments ());
definition = new ImportedGenericMethodDefinition ((MethodInfo) mb, parameters, tparams);
- is_generic = true;
} else {
definition = new ImportedMethodDefinition (mb, parameters);
- is_generic = false;
+ tparams = null;
}
MemberKind kind;
//
string name = mb.Name;
kind = MemberKind.Method;
- if (!mb.DeclaringType.IsInterface && name.Length > 6) {
+ 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) {
+ 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;
+ }
}
}
returnType = ImportType (((MethodInfo)mb).ReturnType);
+
+ // 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 (is_generic)
+ if (tparams != null)
ms.IsGeneric = true;
return ms;
is_valid_property = false;
var set_param_count = set.Parameters.Count - 1;
- if (set_param_count < 0)
- is_valid_property = false;
- var data = new IParameterData [set_param_count];
- var types = new TypeSpec[set_param_count];
- for (int i = 0; i < set_param_count; ++i ) {
- data[i] = set.Parameters.FixedParameters[i];
- types[i] = set.Parameters.Types[i];
+ if (set_param_count < 0) {
+ set_param_count = 0;
+ is_valid_property = false;
}
- var set_param = new ParametersImported (data, types);
var set_type = set.Parameters.Types[set_param_count];
if (mod == 0) {
+ AParametersCollection set_based_param;
+
+ if (set_param_count == 0) {
+ set_based_param = ParametersCompiled.EmptyReadOnlyParameters;
+ } else {
+ //
+ // Create indexer parameters based on setter method parameters (the last parameter has to be removed)
+ //
+ var data = new IParameterData[set_param_count];
+ var types = new TypeSpec[set_param_count];
+ Array.Copy (set.Parameters.FixedParameters, data, set_param_count);
+ Array.Copy (set.Parameters.Types, types, set_param_count);
+ set_based_param = new ParametersImported (data, types, set.Parameters.HasParams);
+ }
+
mod = set.Modifiers;
- param = set_param;
+ param = set_based_param;
type = set_type;
} else {
if (set_param_count != get.Parameters.Count)
is_valid_property = false;
// Possible custom accessor modifiers
- if ((mod & ~Modifiers.AccessibilityMask) != (set.Modifiers & ~Modifiers.AccessibilityMask)) {
+ if ((mod & Modifiers.AccessibilityMask) != (set.Modifiers & Modifiers.AccessibilityMask)) {
var get_acc = mod & Modifiers.AccessibilityMask;
if (get_acc != Modifiers.PUBLIC) {
var set_acc = set.Modifiers & Modifiers.AccessibilityMask;
is_valid_property = false; // Neither is more restrictive
}
- if (set_restr) {
+ if (get_restr) {
mod &= ~Modifiers.AccessibilityMask;
mod |= set_acc;
}
public static TypeSpec CreateType (Type type)
{
- return CreateType (type, null);
+ TypeSpec declaring_type;
+ if (type.IsNested && !type.IsGenericParameter)
+ declaring_type = CreateType (type.DeclaringType);
+ else
+ declaring_type = null;
+
+ return CreateType (type, declaring_type);
}
public static TypeSpec CreateType (Type type, TypeSpec declaringType)
if ((ma & MethodAttributes.Static) != 0) {
mod |= Modifiers.STATIC;
- } else if ((ma & MethodAttributes.Final) != 0) {
- mod |= Modifiers.SEALED;
- } else if ((ma & MethodAttributes.Abstract) != 0 && declaringType.IsClass) {
+ return mod;
+ }
+ if ((ma & MethodAttributes.Abstract) != 0 && declaringType.IsClass) {
mod |= Modifiers.ABSTRACT;
+ return mod;
}
+ if ((ma & MethodAttributes.Final) != 0)
+ mod |= Modifiers.SEALED;
+
// It can be sealed and override
if ((ma & MethodAttributes.Virtual) != 0) {
if ((ma & MethodAttributes.NewSlot) != 0 || !declaringType.IsClass || mod == Modifiers.PRIVATE) {
mod |= Modifiers.VIRTUAL;
} else {
- // Cannot set to OVERRIDE without full hierarchy checks
- // this flag indicates that the method could be override
- // but further validation is needed
- mod |= Modifiers.OVERRIDE_UNCHECKED;
+ mod |= Modifiers.OVERRIDE;
}
}
const MethodAttributes explicit_impl = MethodAttributes.NewSlot |
MethodAttributes.Virtual | MethodAttributes.HideBySig |
- MethodAttributes.Final | MethodAttributes.Private;
+ MethodAttributes.Final;
Dictionary<MethodBase, MethodSpec> possible_accessors = null;
MemberSpec imported;
MethodInfo m;
- List<string> fields_to_ignore = null;
//
// This requires methods to be returned first which seems to work for both Mono and .NET
//
- var all = loading_type.GetMembers (all_members);
+ MemberInfo[] all;
+ try {
+ all = loading_type.GetMembers (all_members);
+ } catch (Exception e) {
+ throw new InternalErrorException (e, "Could not import type `{0}' from `{1}'",
+ declaringType.GetSignatureForError (), declaringType.Assembly.Location);
+ }
var cache = new MemberCache (all.Length);
foreach (var member in all) {
MethodBase mb = (MethodBase) member;
// Ignore explicitly implemented members
- if ((mb.Attributes & explicit_impl) == explicit_impl)
+ if ((mb.Attributes & explicit_impl) == explicit_impl && (mb.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private)
continue;
// Ignore compiler generated methods
continue;
imported = Import.CreateMethod (mb, declaringType);
- if (imported.Kind == MemberKind.Method) {
+ if (imported.Kind == MemberKind.Method && !imported.IsGeneric) {
if (possible_accessors == null)
possible_accessors = new Dictionary<MethodBase, MethodSpec> (ReferenceEquality<MethodBase>.Default);
- // There are no metadata rules for accessors, we have to any method as possible candidate
+ // There are no metadata rules for accessors, we have to consider any method as possible candidate
possible_accessors.Add (mb, (MethodSpec) imported);
}
if (add == null || remove == null)
continue;
- if (fields_to_ignore == null)
- fields_to_ignore = new List<string> ();
-
- fields_to_ignore.Add (e.Name);
-
imported = Import.CreateEvent (e, declaringType, add, remove);
break;
case MemberTypes.Field:
if (fi.IsPrivate && fi.IsDefined (typeof (CompilerGeneratedAttribute), false))
continue;
- if (fields_to_ignore != null && fields_to_ignore.Contains (fi.Name))
- continue;
-
imported = Import.CreateField (fi, declaringType);
if (imported == null)
continue;