internal static void SetMethodAttributes(RubyModule /*!*/ module, string /*!*/[] /*!*/ methodNames, RubyMethodAttributes attributes)
{
var context = module.Context;
bool isModuleFunction = (attributes & RubyMethodAttributes.ModuleFunction) == RubyMethodAttributes.ModuleFunction;
var instanceVisibility = isModuleFunction ? RubyMethodVisibility.Private :
(RubyMethodVisibility)(attributes & RubyMethodAttributes.VisibilityMask);
foreach (string methodName in methodNames)
{
RubyMemberInfo method;
// we need to define new methods one by one since the method_added events can define a new method that might be used here:
using (context.ClassHierarchyLocker()) {
MethodLookup options = MethodLookup.FallbackToObject;
if (!isModuleFunction)
{
options |= MethodLookup.ReturnForwarder;
}
method = module.ResolveMethodNoLock(methodName, VisibilityContext.AllVisible, options).Info;
if (method == null)
{
throw RubyExceptions.CreateUndefinedMethodError(module, methodName);
}
// MRI only adds method to the target module if visibility differs:
if (method.Visibility != instanceVisibility)
{
module.SetVisibilityNoEventNoLock(context, methodName, method, instanceVisibility);
}
if (isModuleFunction)
{
module.SetModuleFunctionNoEventNoLock(context, methodName, method);
}
}
if (method.Visibility != instanceVisibility)
{
module.MethodAdded(methodName);
}
if (isModuleFunction)
{
module.GetOrCreateSingletonClass().MethodAdded(methodName);
}
}
}