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); } } }
private static void DefineMethod(RubyScope /*!*/ scope, RubyModule /*!*/ self, string /*!*/ methodName, RubyMemberInfo /*!*/ info, RubyModule /*!*/ targetConstraint) { var visibility = GetDefinedMethodVisibility(scope, self, methodName); using (self.Context.ClassHierarchyLocker()) { // MRI 1.8 does the check when the method is called, 1.9 checks it upfront as we do: if (!self.HasAncestorNoLock(targetConstraint)) { throw RubyExceptions.CreateTypeError( "bind argument must be a subclass of {0}", targetConstraint.GetName(scope.RubyContext) ); } self.SetDefinedMethodNoEventNoLock(self.Context, methodName, info, visibility); } self.MethodAdded(methodName); }
private static void DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self, string/*!*/ methodName, RubyMemberInfo/*!*/ info, RubyModule/*!*/ targetConstraint) { var visibility = GetDefinedMethodVisibility(scope, self, methodName); using (self.Context.ClassHierarchyLocker()) { // MRI 1.8 does the check when the method is called, 1.9 checks it upfront as we do: if (!self.HasAncestorNoLock(targetConstraint)) { throw RubyExceptions.CreateTypeError( "bind argument must be a subclass of {0}", targetConstraint.GetName(scope.RubyContext) ); } self.SetDefinedMethodNoEventNoLock(self.Context, methodName, info, visibility); } self.MethodAdded(methodName); }
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.CreateNameError(RubyExceptions.FormatMethodMissingMessage(context, 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.SingletonClass.MethodAdded(methodName); } } }