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);
+ set_based_param = IndexerSpec.CreateParametersFromSetter (set, set_param_count);
}
mod = set.Modifiers;
int i = 0;
if (abstract_methods != null) {
int count = abstract_methods.Length;
- pending_implementations [i].methods = new MethodSpec [count];
pending_implementations [i].need_proxy = new MethodSpec [count];
pending_implementations [i].methods = abstract_methods;
bool BaseImplements (TypeSpec iface_type, MethodSpec mi, out MethodSpec base_method)
{
base_method = null;
- var base_type = container.BaseType;
+ bool base_can_implement = true;
+ TypeSpec lookup_type;
+
+ //
+ // Special handling for properties/indexers which cannot have accessors
+ // implementing an interface found in different types (e.g. current and base)
+ //
+ if (mi.IsAccessor && container.Interfaces != null) {
+
+ bool new_implementation = false;
+ foreach (var iface in container.Interfaces) {
+ if (TypeSpecComparer.IsEqual (iface, iface_type)) {
+ new_implementation = true;
+ break;
+ }
+ }
+
+ if (new_implementation) {
+ MemberFilter filter;
+ if (mi.Parameters.Count > 1) {
+ var indexer_params = mi.Name [0] == 'g' ? mi.Parameters : IndexerSpec.CreateParametersFromSetter (mi, mi.Parameters.Count - 1);
+ filter = new MemberFilter (MemberCache.IndexerNameAlias, 0, MemberKind.Indexer, indexer_params, null);
+ } else {
+ var pname = mi.Name.Substring (4);
+ filter = MemberFilter.Property (pname, null);
+ }
+
+ var prop = MemberCache.FindMember (container.CurrentType, filter, BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly);
+ if (prop != null && (prop.Modifiers & Modifiers.NEW) != 0)
+ base_can_implement = false;
+ }
+ }
+
+ if (base_can_implement) {
+ lookup_type = container.BaseType;
+
+ if (lookup_type.ImplementsInterface (iface_type, false))
+ return true;
+ } else {
+ lookup_type = container.CurrentType;
+ }
//
// Setup filter with no return type to give better error message
MethodSpec close_match = null;
while (true) {
- var candidates = MemberCache.FindMembers (base_type, mi.Name, false);
+ var candidates = MemberCache.FindMembers (lookup_type, mi.Name, !base_can_implement);
if (candidates == null) {
base_method = close_match;
return false;
break;
}
- base_type = candidates[0].DeclaringType.BaseType;
- if (base_type == null) {
+ if (!base_can_implement)
+ return false;
+
+ lookup_type = candidates[0].DeclaringType.BaseType;
+ if (lookup_type == null) {
base_method = close_match;
return false;
}
for (i = 0; i < top; i++){
TypeSpec type = pending_implementations [i].type;
- bool base_implements_type = type.IsInterface &&
- container.BaseType != null &&
- container.BaseType.ImplementsInterface (type, false);
-
for (int j = 0; j < pending_implementations [i].methods.Count; ++j) {
var mi = pending_implementations[i].methods[j];
if (mi == null)
continue;
}
- if (pending_implementations [i].optional)
- continue;
-
MethodSpec candidate;
- if (base_implements_type || BaseImplements (type, mi, out candidate))
+ if (BaseImplements (type, mi, out candidate))
continue;
if (candidate == null) {
}
#endregion
+ public static ParametersImported CreateParametersFromSetter (MethodSpec setter, int set_param_count)
+ {
+ //
+ // Creates 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 (setter.Parameters.FixedParameters, data, set_param_count);
+ Array.Copy (setter.Parameters.Types, types, set_param_count);
+ return new ParametersImported (data, types, setter.Parameters.HasParams);
+ }
+
public override string GetSignatureForDocumentation ()
{
return base.GetSignatureForDocumentation () + parameters.GetSignatureForDocumentation ();