private bool RemoveMethodNoEvent(string/*!*/ name) {
Mutate();
using (Context.ClassHierarchyLocker()) {
InitializeMethodsNoLock();
RubyMemberInfo method;
if (_methods.TryGetValue(name, out method)) {
if (method.IsHidden || method.IsUndefined) {
return false;
} else if (IsBasicObjectClass && name == Symbols.Initialize) {
// We prohibit removing Object#initialize to simplify object construction logic.
return false;
} else if (method.IsRemovable) {
// Method is used in a dynamic site or group => update version of all dependencies of this module.
if (method.InvalidateSitesOnOverride || method.InvalidateGroupsOnRemoval) {
MethodsUpdated("RemoveMethod: " + name);
}
// Method hides CLR overloads => update method groups in all dependencies of this module.
// TODO (opt): Do not update the entire subtree, update subtrees of all invalidated groups.
// TODO (opt): We can calculate max-level but it requires maintanance whenever a method is overridden
// and whenever method group is lazily created (TryGetClrMethod).
if (method.InvalidateGroupsOnRemoval) {
InvalidateGroupsInDependentClasses(name, Int32.MaxValue);
}
_methods.Remove(name);
} else {
SetMethodNoEventNoLock(Context, name, RubyMemberInfo.HiddenMethod);
}
return true;
} else if (TryGetClrMember(name, false, out method)) {
Debug.Assert(!method.IsRemovable);
SetMethodNoEventNoLock(Context, name, RubyMemberInfo.HiddenMethod);
return true;
} else {
return false;
}
}
}