Exemplo n.º 1
0
        internal static void SetMethodAttributes(RubyScope /*!*/ scope, RubyModule /*!*/ module, object[] /*!*/ methodNames, RubyMethodAttributes attributes)
        {
            ContractUtils.RequiresNotNull(scope, "scope");
            ContractUtils.RequiresNotNull(methodNames, "methodNames");

            if (methodNames.Length == 0)
            {
                scope.GetMethodAttributesDefinitionScope().MethodAttributes = attributes;
            }
            else
            {
                foreach (string methodName in Protocols.CastToSymbols(scope.RubyContext, methodNames))
                {
                    RubyMemberInfo method = module.ResolveMethodFallbackToObject(methodName, true);
                    if (method == null)
                    {
                        throw RubyExceptions.CreateNameError(RubyExceptions.FormatMethodMissingMessage(scope.RubyContext, module, methodName));
                    }

                    if ((attributes & RubyMethodAttributes.ModuleFunction) == RubyMethodAttributes.ModuleFunction)
                    {
                        module.AddModuleFunction(methodName, method);
                    }
                    else
                    {
                        module.SetMethodVisibility(methodName, method, (RubyMethodVisibility)(attributes & RubyMethodAttributes.VisibilityMask));
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Implements Class#new feature.
        /// </summary>
        public void BuildObjectConstruction(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ methodName)
        {
            Debug.Assert(!IsSingletonClass, "Cannot instantiate singletons");

            Type type = GetUnderlyingSystemType();

            RubyMemberInfo initializer           = ResolveMethod(Symbols.Initialize, true).InvalidateSitesOnOverride();
            RubyMethodInfo overriddenInitializer = initializer as RubyMethodInfo;

            // check the version of this class to ensure the initializer won't be changed without rebuilding the site:
            metaBuilder.AddCondition(
                Ast.Equal(Ast.Property(Ast.Constant(this), RubyModule.VersionProperty), Ast.Constant(this.Version))
                );

            // Initializer is overridden => initializer is invoked on an uninitialized instance.
            // Is user class (defined in Ruby code) => construct it as if it had initializer that calls super immediately
            // (we need to "inherit" factories/constructors from the base class (e.g. class S < String; self; end.new('foo')).
            if (overriddenInitializer != null || (_isRubyClass && _structInfo == null))
            {
                metaBuilder.Result = MakeAllocatorCall(args, () => Ast.Constant(Name));

                if (overriddenInitializer != null || (_isRubyClass && initializer != null && !initializer.IsEmpty))
                {
                    BuildOverriddenInitializerCall(metaBuilder, args, initializer);
                }
            }
            else if (type.IsSubclassOf(typeof(Delegate)))
            {
                metaBuilder.Result = MakeDelegateConstructorCall(type, args);
            }
            else
            {
                MethodBase[] constructionOverloads;

                bool includeSelf;
                if (_structInfo != null)
                {
                    constructionOverloads = new MethodBase[] { Methods.CreateStructInstance };
                    includeSelf           = true;
                }
                else if (_factories != null)
                {
                    constructionOverloads = (MethodBase[])ReflectionUtils.GetMethodInfos(_factories);
                    includeSelf           = true;
                }
                else
                {
                    constructionOverloads = type.GetConstructors();
                    if (constructionOverloads.Length == 0)
                    {
                        throw RubyExceptions.CreateTypeError(String.Format("allocator undefined for {0}", Name));
                    }
                    includeSelf = false;
                }

                RubyMethodGroupInfo.BuildCallNoFlow(metaBuilder, args, methodName, constructionOverloads, includeSelf, false);
                RubyMethodGroupInfo.ApplyBlockFlowHandlingInternal(metaBuilder, args);
            }
        }
Exemplo n.º 3
0
        internal UnboundMethod(RubyModule /*!*/ targetConstraint, string /*!*/ name, RubyMemberInfo /*!*/ info)
        {
            Assert.NotNull(targetConstraint, name, info);

            _name             = name;
            _info             = info;
            _targetConstraint = targetConstraint;
        }
Exemplo n.º 4
0
 public static RubyMemberInfo InvalidateSitesOnOverride(this RubyMemberInfo member)
 {
     if (member != null)
     {
         member.InvalidateSitesOnOverride = true;
     }
     return(member);
 }
Exemplo n.º 5
0
        public RubyMethod(object target, RubyMemberInfo /*!*/ info, string /*!*/ name)
        {
            ContractUtils.RequiresNotNull(info, "info");
            ContractUtils.RequiresNotNull(name, "name");

            _target = target;
            _info   = info;
            _name   = name;
        }
Exemplo n.º 6
0
        internal static RubyMemberInfo /*!*/ BindGenericParameters(RubyContext /*!*/ context, RubyMemberInfo /*!*/ info, string /*!*/ name, object[] /*!*/ typeArgs)
        {
            RubyMemberInfo result = info.TryBindGenericParameters(Protocols.ToTypes(context, typeArgs));

            if (result == null)
            {
                throw RubyExceptions.CreateArgumentError("wrong number of generic arguments for `{0}'", name);
            }
            return(result);
        }
Exemplo n.º 7
0
        internal static RubyArray GetSourceLocation(RubyMemberInfo /*!*/ info)
        {
            RubyMethodInfo rubyInfo = info as RubyMethodInfo;

            return((rubyInfo == null) ? null : new RubyArray(2)
            {
                rubyInfo.DeclaringModule.Context.EncodePath(rubyInfo.Document.FileName),
                rubyInfo.SourceSpan.Start.Line
            });
        }
Exemplo n.º 8
0
        internal static RubyMemberInfo /*!*/ SelectOverload(RubyContext /*!*/ context, RubyMemberInfo /*!*/ info, string /*!*/ name, object[] /*!*/ typeArgs)
        {
            RubyMemberInfo result = info.TrySelectOverload(Protocols.ToTypes(context, typeArgs));

            if (result == null)
            {
                throw RubyExceptions.CreateArgumentError("no overload of `{0}' matches given parameter types", name);
            }
            return(result);
        }
Exemplo n.º 9
0
        public static RubyModule /*!*/ UndefineMethod(RubyModule /*!*/ self, [DefaultProtocol] string /*!*/ methodName)
        {
            RubyMemberInfo method = self.ResolveMethod(methodName, true);

            if (method == null)
            {
                throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
            }
            self.UndefineMethod(methodName);
            return(self);
        }
Exemplo n.º 10
0
        public static UnboundMethod /*!*/ GetInstanceMethod(RubyModule /*!*/ self, [DefaultProtocol] string /*!*/ methodName)
        {
            RubyMemberInfo method = self.ResolveMethod(methodName, true);

            if (method == null)
            {
                throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
            }

            // unbound method binable to any class with "self" mixin:
            return(new UnboundMethod(self, methodName, method));
        }
Exemplo n.º 11
0
        public static RubyModule /*!*/ AliasMethod(RubyModule /*!*/ self,
                                                   [DefaultProtocol] string /*!*/ newName, [DefaultProtocol] string /*!*/ oldName)
        {
            RubyMemberInfo method = self.ResolveMethodFallbackToObject(oldName, true);

            if (method == null)
            {
                throw RubyExceptions.CreateUndefinedMethodError(self, oldName);
            }

            self.AddMethodAlias(newName, method);
            return(self);
        }
Exemplo n.º 12
0
        internal static void BuildConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            const string ToS = "to_s";

            if (TryImplicitConversion(metaBuilder, args))
            {
                metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
                return;
            }

            RubyMemberInfo conversionMethod, methodMissing = null;

            RubyClass targetClass = args.RubyContext.GetImmediateClassOf(args.Target);

            using (targetClass.Context.ClassHierarchyLocker()) {
                metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext,
                                              new[] { ToS, Symbols.MethodMissing }
                                              );

                conversionMethod = targetClass.ResolveMethodForSiteNoLock(ToS, VisibilityContext.AllVisible).Info;

                // find method_missing - we need to add "to_s" method to the missing methods table:
                if (conversionMethod == null)
                {
                    methodMissing = targetClass.ResolveMethodMissingForSite(ToS, RubyMethodVisibility.None);
                }
            }

            // invoke target.to_s and if successful convert the result to string unless it is already:
            if (conversionMethod != null)
            {
                conversionMethod.BuildCall(metaBuilder, args, ToS);
            }
            else
            {
                RubyCallAction.BuildMethodMissingCall(metaBuilder, args, ToS, methodMissing, RubyMethodVisibility.None, false, true);
            }

            if (metaBuilder.Error)
            {
                return;
            }

            metaBuilder.Result = Methods.ToSDefaultConversion.OpCall(
                AstUtils.Convert(args.MetaContext.Expression, typeof(RubyContext)),
                AstUtils.Box(args.TargetExpression),
                AstUtils.Box(metaBuilder.Result)
                );
        }
Exemplo n.º 13
0
        protected override Node /*!*/ CreateNode(object data)
        {
            RubyMemberInfo method = Context.GetImmediateClassOf(data).ResolveMethodForSite("to_yaml", VisibilityContext.AllVisible).Info;

            if (method == _siteStorage.ObjectToYamlMethod)
            {
                var site = _siteStorage.ToYamlNode;
                return(ToNode(site.Target(site, data, this)));
            }
            else
            {
                var site = _siteStorage.ToYaml;
                return(ToNode(site.Target(site, data, this)));
            }
        }
Exemplo n.º 14
0
        protected override Node CreateNode(object data)
        {
            RubyMemberInfo method = _context.ResolveMethod(data, "to_yaml", false).InvalidateSitesOnOverride();

            if (method == _objectToYamlMethod)
            {
                return(_ToYamlNode.Target(_ToYamlNode, _context, data, this));
            }
            else
            {
                // TODO: this doesn't seem right
                // (we're passing the extra argument, but the callee might not take it?)
                return(_ToYaml.Target(_ToYaml, _context, data, this));
            }
        }
Exemplo n.º 15
0
        private static void SetClassMethodsVisibility(RubyModule /*!*/ module, string[] /*!*/ methodNames, RubyMethodVisibility visibility)
        {
            var methods = new RubyMemberInfo[methodNames.Length];

            for (int i = 0; i < methods.Length; i++)
            {
                RubyMemberInfo method = module.SingletonClass.ResolveMethod(methodNames[i], true);
                if (method == null)
                {
                    throw RubyExceptions.CreateUndefinedMethodError(module, methodNames[i]);
                }
                methods[i] = method;
            }

            for (int i = 0; i < methods.Length; i++)
            {
                module.SingletonClass.SetMethodVisibility(methodNames[i], methods[i], visibility);
            }
        }
Exemplo n.º 16
0
        public static UnboundMethod /*!*/ GetInstanceMethod(RubyModule /*!*/ self, [DefaultProtocol, NotNull] string /*!*/ methodName)
        {
            RubyMemberInfo method = self.ResolveMethod(methodName, VisibilityContext.AllVisible).Info;

            if (method == null)
            {
                throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
            }

            RubyModule constraint = self;

            if (self.IsSingletonClass && method.DeclaringModule != self)
            {
                constraint = ((RubyClass)self).SuperClass;
            }

            // unbound method binable to any class with "constraint" mixin:
            return(new UnboundMethod(constraint, methodName, method));
        }
Exemplo n.º 17
0
 public RubyRepresenter(RubyContext /*!*/ context, ISerializer /*!*/ serializer, YamlOptions /*!*/ opts)
     : base(serializer, opts)
 {
     _context            = context;
     _objectToYamlMethod = context.GetClass(typeof(object)).ResolveMethod("to_yaml", false);
 }
Exemplo n.º 18
0
        protected override bool TryGetClrMember(Type /*!*/ type, string /*!*/ name, out RubyMemberInfo method)
        {
            string unmangled;

            if (IsFailureCached(type, name))
            {
                method = null;
                return(false);
            }

            BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;

            bindingFlags |= (_isSingletonClass) ? BindingFlags.Static : BindingFlags.Instance;

            if (name.EndsWith("="))
            {
                string propertyName = name.Substring(0, name.Length - 1);

                // property setter:
                if (TryGetClrMethod(type, bindingFlags, "set_" + propertyName, out method))
                {
                    return(true);
                }
                unmangled = RubyUtils.TryUnmangleName(propertyName);
                if (unmangled != null && TryGetClrMethod(type, bindingFlags, "set_" + unmangled, out method))
                {
                    return(true);
                }

                // writeable field:
                if (TryGetClrField(type, bindingFlags, propertyName, true, out method))
                {
                    return(true);
                }
                if (unmangled != null && TryGetClrField(type, bindingFlags, unmangled, true, out method))
                {
                    return(true);
                }
            }
            else
            {
                // method:
                if (TryGetClrMethod(type, bindingFlags, name, out method))
                {
                    return(true);
                }
                unmangled = RubyUtils.TryUnmangleName(name);
                if (unmangled != null && TryGetClrMethod(type, bindingFlags, unmangled, out method))
                {
                    return(true);
                }

                // getter:
                if (TryGetClrMethod(type, bindingFlags, "get_" + name, out method))
                {
                    return(true);
                }
                if (unmangled != null && TryGetClrMethod(type, bindingFlags, "get_" + unmangled, out method))
                {
                    return(true);
                }

                // event:
                if (TryGetClrEvent(type, bindingFlags, name, out method))
                {
                    return(true);
                }
                if (unmangled != null && TryGetClrEvent(type, bindingFlags, unmangled, out method))
                {
                    return(true);
                }

                // field:
                if (TryGetClrField(type, bindingFlags, name, false, out method))
                {
                    return(true);
                }
                if (unmangled != null && TryGetClrField(type, bindingFlags, unmangled, false, out method))
                {
                    return(true);
                }
            }

            CacheFailure(type, name);

            method = null;
            return(false);
        }
Exemplo n.º 19
0
        public static bool PublicMethodDefined(RubyModule /*!*/ self, [DefaultProtocol] string /*!*/ methodName)
        {
            RubyMemberInfo method = self.ResolveMethod(methodName, true);

            return(method != null && method.Visibility == RubyMethodVisibility.Public);
        }
Exemplo n.º 20
0
        private bool TryGetClrMethod(Type /*!*/ type, BindingFlags bindingFlags, string /*!*/ name, out RubyMemberInfo method)
        {
            Assert.NotNull(type, name);

            MemberInfo[] members = type.GetMember(name, MemberTypes.Method, bindingFlags | BindingFlags.InvokeMethod);
            if (members.Length > 0)
            {
                method = new RubyMethodGroupInfo(SelectNonPrivateMethods(members), this, _isSingletonClass);
                return(true);
            }
            else
            {
                method = null;
                return(false);
            }
        }
Exemplo n.º 21
0
        private bool TryGetClrField(Type /*!*/ type, BindingFlags bindingFlags, string /*!*/ name, bool isWrite, out RubyMemberInfo method)
        {
            Assert.NotNull(type, name);

            FieldInfo fieldInfo = type.GetField(name, bindingFlags);

            if (fieldInfo != null && !fieldInfo.IsPrivate && (!isWrite || !fieldInfo.IsInitOnly && !fieldInfo.IsLiteral))
            {
                method = new RubyFieldInfo(fieldInfo, RubyMemberFlags.Public, this, isWrite);
                return(true);
            }

            method = null;
            return(false);
        }
Exemplo n.º 22
0
        private bool TryGetClrEvent(Type /*!*/ type, BindingFlags bindingFlags, string /*!*/ name, out RubyMemberInfo method)
        {
            Assert.NotNull(type, name);

            EventInfo eventInfo = type.GetEvent(name, bindingFlags);

            if (eventInfo != null)
            {
                method = new RubyEventInfo(eventInfo, RubyMemberFlags.Public, this);
                return(true);
            }

            method = null;
            return(false);
        }
Exemplo n.º 23
0
 public YamlCallSiteStorage(RubyContext /*!*/ context)
     : base(context)
 {
     _objectToYamlMethod = context.ObjectClass.ResolveMethod("to_yaml", VisibilityContext.AllVisible).Info;
 }
Exemplo n.º 24
0
        internal static void BuildConversion(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, Type /*!*/ resultType,
                                             params ProtocolConversionAction /*!*/[] /*!*/ conversions)
        {
            Assert.NotNull(metaBuilder, args, conversions);
            Debug.Assert(args.SimpleArgumentCount == 0 && !args.Signature.HasBlock && !args.Signature.HasSplattedArgument && !args.Signature.HasRhsArgument);
            Debug.Assert(!args.Signature.HasScope);

            // implicit conversions should only depend on the static type:
            foreach (var conversion in conversions)
            {
                if (conversion.TryImplicitConversion(metaBuilder, args))
                {
                    metaBuilder.AddObjectTypeRestriction(args.Target, args.TargetExpression);

                    if (!metaBuilder.Error)
                    {
                        metaBuilder.Result = ConvertResult(metaBuilder.Result, resultType);
                    }
                    return;
                }
            }

            RubyClass                targetClass = args.RubyContext.GetImmediateClassOf(args.Target);
            Expression               targetClassNameConstant = AstUtils.Constant(targetClass.GetNonSingletonClass().Name, typeof(string));
            MethodResolutionResult   respondToMethod, methodMissing = MethodResolutionResult.NotFound;
            ProtocolConversionAction selectedConversion = null;
            RubyMemberInfo           conversionMethod   = null;

            using (targetClass.Context.ClassHierarchyLocker()) {
                // check for type version:
                metaBuilder.AddTargetTypeTest(args.Target, targetClass, args.TargetExpression, args.MetaContext,
                                              ArrayUtils.Insert(Symbols.RespondTo, Symbols.MethodMissing, ArrayUtils.ConvertAll(conversions, (c) => c.ToMethodName))
                                              );

                // we can optimize if Kernel#respond_to? method is not overridden:
                respondToMethod = targetClass.ResolveMethodForSiteNoLock(Symbols.RespondTo, VisibilityContext.AllVisible);
                if (respondToMethod.Found && respondToMethod.Info.DeclaringModule == targetClass.Context.KernelModule && respondToMethod.Info is RubyLibraryMethodInfo)   // TODO: better override detection
                {
                    respondToMethod = MethodResolutionResult.NotFound;

                    // get the first applicable conversion:
                    foreach (var conversion in conversions)
                    {
                        selectedConversion = conversion;
                        conversionMethod   = targetClass.ResolveMethodForSiteNoLock(conversion.ToMethodName, VisibilityContext.AllVisible).Info;
                        if (conversionMethod != null)
                        {
                            break;
                        }
                        else
                        {
                            // find method_missing - we need to add "to_xxx" methods to the missing methods table:
                            if (!methodMissing.Found)
                            {
                                methodMissing = targetClass.ResolveMethodNoLock(Symbols.MethodMissing, VisibilityContext.AllVisible);
                            }
                            methodMissing.InvalidateSitesOnMissingMethodAddition(conversion.ToMethodName, targetClass.Context);
                        }
                    }
                }
            }

            if (!respondToMethod.Found)
            {
                if (conversionMethod == null)
                {
                    // error:
                    selectedConversion.SetError(metaBuilder, args, targetClassNameConstant, resultType);
                    return;
                }
                else
                {
                    // invoke target.to_xxx() and validate it; returns an instance of TTargetType:
                    conversionMethod.BuildCall(metaBuilder, args, selectedConversion.ToMethodName);

                    if (!metaBuilder.Error)
                    {
                        metaBuilder.Result = ConvertResult(
                            selectedConversion.MakeValidatorCall(args, targetClassNameConstant, metaBuilder.Result),
                            resultType
                            );
                    }
                    return;
                }
            }

            // slow path: invoke respond_to?, to_xxx and result validation:
            for (int i = conversions.Length - 1; i >= 0; i--)
            {
                string toMethodName = conversions[i].ToMethodName;

                var conversionCallSite = AstUtils.LightDynamic(
                    RubyCallAction.Make(args.RubyContext, toMethodName, RubyCallSignature.WithImplicitSelf(0)),
                    args.TargetExpression
                    );

                metaBuilder.Result = Ast.Condition(
                    // If

                    // respond_to?()
                    Methods.IsTrue.OpCall(
                        AstUtils.LightDynamic(
                            RubyCallAction.Make(args.RubyContext, Symbols.RespondTo, RubyCallSignature.WithImplicitSelf(1)),
                            args.TargetExpression,
                            Ast.Constant(args.RubyContext.CreateSymbol(toMethodName, RubyEncoding.Binary))
                            )
                        ),

                    // Then

                    // to_xxx():
                    ConvertResult(
                        conversions[i].MakeValidatorCall(args, targetClassNameConstant, conversionCallSite),
                        resultType
                        ),

                    // Else

                    (i < conversions.Length - 1) ? metaBuilder.Result :
                    conversions[i].MakeErrorExpression(args, targetClassNameConstant, resultType)
                    );
            }
        }
Exemplo n.º 25
0
        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);
        }
Exemplo n.º 26
0
        public static bool PublicMethodDefined(RubyModule /*!*/ self, [DefaultProtocol, NotNull] string /*!*/ methodName)
        {
            RubyMemberInfo method = self.ResolveMethod(methodName, VisibilityContext.AllVisible).Info;

            return(method != null && method.Visibility == RubyMethodVisibility.Public);
        }
Exemplo n.º 27
0
        private static void BuildOverriddenInitializerCall(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, RubyMemberInfo /*!*/ initializer)
        {
            var instanceExpr = metaBuilder.Result;

            metaBuilder.Result = null;

            var instanceVariable = metaBuilder.GetTemporary(instanceExpr.Type, "#instance");

            // We know an exact type of the new instance and that there is no singleton for that instance.
            // We also have the exact method we need to call ("initialize" is a RubyMethodInfo).
            // => no tests are necessary:
            args.SetTarget(instanceVariable, null);

            if (initializer is RubyMethodInfo)
            {
                initializer.BuildCall(metaBuilder, args, Symbols.Initialize);
            }
            else
            {
                // TODO: we need more refactoring of RubyMethodGroupInfo.BuildCall to be able to inline this:
                metaBuilder.Result = Ast.Dynamic(
                    RubyCallAction.Make("initialize",
                                        new RubyCallSignature(args.Signature.ArgumentCount, args.Signature.Flags | RubyCallFlags.HasImplicitSelf)
                                        ),
                    typeof(object),
                    args.GetCallSiteArguments(instanceVariable)
                    );
            }

            if (!metaBuilder.Error)
            {
                // PropagateRetrySingleton(instance = new <type>(), instance.initialize(<args>))
                metaBuilder.Result = Methods.PropagateRetrySingleton.OpCall(
                    Ast.Assign(instanceVariable, instanceExpr),
                    metaBuilder.Result
                    );
                RubyMethodInfo.ApplyBlockFlowHandlingInternal(metaBuilder, args);
            }
        }
Exemplo n.º 28
0
 internal Curried(object target, RubyMemberInfo /*!*/ info, string /*!*/ methodNameArg)
     : base(target, info, "method_missing")
 {
     _methodNameArg = methodNameArg;
 }
Exemplo n.º 29
0
        // thread-safe:
        private static void SetLibraryMethod(RubyModule /*!*/ module, string /*!*/ name, RubyMemberInfo /*!*/ method, bool noEvent)
        {
            var context = module.Context;

            // trigger event only for non-builtins:
            if (noEvent)
            {
                // TODO: hoist lock?
                using (context.ClassHierarchyLocker()) {
                    module.SetMethodNoMutateNoEventNoLock(context, name, method);
                }
            }
            else
            {
                module.AddMethod(context, name, method);
            }
        }