+ //
+ // Removes hidden base members of an interface. For compiled interfaces we cannot
+ // do name filtering during Add (as we do for import) because we need all base
+ // names to be valid during type definition.
+ // Add replaces hidden base member with current one which means any name collision
+ // (CS0108) of non-first name would be unnoticed because the name was replaced
+ // with the one from compiled type
+ //
+ public void RemoveHiddenMembers (TypeSpec container)
+ {
+ foreach (var entry in member_hash) {
+ var values = entry.Value;
+
+ int container_members_start_at = 0;
+ while (values[container_members_start_at].DeclaringType != container && ++container_members_start_at < entry.Value.Count);
+
+ if (container_members_start_at == 0 || container_members_start_at == values.Count)
+ continue;
+
+ for (int i = 0; i < container_members_start_at; ++i) {
+ var member = values[i];
+
+ if (!container.ImplementsInterface (member.DeclaringType, false))
+ continue;
+
+ var member_param = member is IParametersMember ? ((IParametersMember) member).Parameters : ParametersCompiled.EmptyReadOnlyParameters;
+
+ for (int ii = container_members_start_at; ii < values.Count; ++ii) {
+ var container_entry = values[ii];
+
+ if (container_entry.Arity != member.Arity)
+ continue;
+
+ if (container_entry is IParametersMember) {
+ if (!TypeSpecComparer.Override.IsEqual (((IParametersMember) container_entry).Parameters, member_param))
+ continue;
+ }
+
+ values.RemoveAt (i);
+ --container_members_start_at;
+ --ii;
+ --i;
+ }
+ }
+ }
+ }
+