public void AddMethodAlias(string/*!*/ newName, string/*!*/ oldName) {
// MRI 1.8: if (newName == oldName) return;
// MRI 1.9: no check
RubyMemberInfo method;
using (Context.ClassHierarchyLocker()) {
// MRI: aliases a super-forwarder not the real method.
method = ResolveMethodNoLock(oldName, VisibilityContext.AllVisible, MethodLookup.FallbackToObject | MethodLookup.ReturnForwarder).Info;
if (method == null) {
throw RubyExceptions.CreateUndefinedMethodError(this, oldName);
}
// Alias preserves visibility and declaring module even though the alias is declared in a different module (e.g. subclass) =>
// we can share method info (in fact, sharing is sound with Method#== semantics - it returns true on aliased methods).
//
// CLR members:
// Detaches the member from its underlying type (by creating a copy).
// Note: We need to copy overload group since otherwise it might mess up caching if the alias is defined in a sub-module and
// overloads of the same name that are not included in the overload group are inherited to this module.
// EnumerateMethods also relies on overload groups only representing cached CLR members.
if (!method.IsRubyMember) {
SetMethodNoEventNoLock(Context, newName, method.Copy(method.Flags, method.DeclaringModule));
} else {
SetMethodNoEventNoLock(Context, newName, method);
}
}
MethodAdded(newName);
}