PageRenderTime 57ms CodeModel.GetById 15ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/IronPython_Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs

#
C# | 1089 lines | 781 code | 197 blank | 111 comment | 123 complexity | 35edf797b45daf08b57568aa6bb37ed9 MD5 | raw file
   1/* ****************************************************************************
   2 *
   3 * Copyright (c) Microsoft Corporation. 
   4 *
   5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
   6 * copy of the license can be found in the License.html file at the root of this distribution. If 
   7 * you cannot locate the  Apache License, Version 2.0, please send an email to 
   8 * ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
   9 * by the terms of the Apache License, Version 2.0.
  10 *
  11 * You must not remove this notice, or any other, from this software.
  12 *
  13 *
  14 * ***************************************************************************/
  15
  16using System;
  17using System.Collections.Generic;
  18using System.Runtime.CompilerServices;
  19using System.Runtime.InteropServices;
  20using IronRuby.Compiler;
  21using IronRuby.Runtime;
  22using IronRuby.Runtime.Calls;
  23using Microsoft.Scripting.Actions;
  24using Microsoft.Scripting.Runtime;
  25using Microsoft.Scripting.Utils;
  26using Microsoft.Scripting.Generation;
  27using Microsoft.Scripting;
  28using System.Diagnostics;
  29
  30namespace IronRuby.Builtins {
  31
  32    [RubyClass("Module", Extends = typeof(RubyModule), Inherits = typeof(Object), Restrictions = ModuleRestrictions.Builtin | ModuleRestrictions.NoUnderlyingType)]
  33    public static class ModuleOps {
  34
  35        #region initialize, initialize_copy
  36
  37        [RubyMethod("initialize", RubyMethodAttributes.PrivateInstance)]
  38        public static object Reinitialize(BlockParam block, RubyModule/*!*/ self) {
  39            // no class can be reinitialized:
  40            if (self.IsClass) {
  41                throw RubyExceptions.CreateTypeError("already initialized class");
  42            }
  43
  44            return (block != null) ? RubyUtils.EvaluateInModule(self, block, null) : null;
  45        }
  46
  47        [RubyMethod("initialize_copy", RubyMethodAttributes.PrivateInstance)]
  48        public static RubyModule/*!*/ InitializeCopy(RubyModule/*!*/ self, object other) {
  49            // no class can be reinitialized:
  50            if (self.IsClass) {
  51                throw RubyExceptions.CreateTypeError("already initialized class");
  52            }
  53            
  54            // self could be a meta-module:
  55            RubyClass selfClass = self.Context.GetClassOf(self);
  56            RubyClass otherClass = self.Context.GetClassOf(other);
  57            if (otherClass != selfClass) {
  58                throw RubyExceptions.CreateTypeError("initialize_copy should take same class object");
  59            }
  60
  61            self.InitializeModuleCopy((RubyModule)other);
  62            return self;
  63        }
  64        
  65        #endregion
  66
  67        #region extend_object, extended, include, included
  68
  69        // thread-safe:
  70        [RubyMethod("extend_object", RubyMethodAttributes.PrivateInstance)]
  71        public static object ExtendObject(RubyModule/*!*/ self, object extendedObject) {
  72            // include self into extendedObject's singleton
  73            self.Context.GetOrCreateSingletonClass(extendedObject).IncludeModules(self);
  74            return extendedObject;
  75        }
  76
  77        [RubyMethod("extended", RubyMethodAttributes.PrivateInstance)]
  78        public static void ObjectExtended(RubyModule/*!*/ self, object extendedObject) {
  79            // extendedObject has been extended by self, i.e. self has been included into extendedObject's singleton class
  80        }
  81
  82        [RubyMethod("include", RubyMethodAttributes.PrivateInstance)]
  83        public static RubyModule/*!*/ Include(
  84            CallSiteStorage<Func<CallSite, RubyModule, RubyModule, object>>/*!*/ appendFeaturesStorage,
  85            CallSiteStorage<Func<CallSite, RubyModule, RubyModule, object>>/*!*/ includedStorage,
  86            RubyModule/*!*/ self, [NotNullItems]params RubyModule/*!*/[]/*!*/ modules) {
  87
  88            RubyUtils.RequireMixins(self, modules);
  89
  90            var appendFeatures = appendFeaturesStorage.GetCallSite("append_features", 1);
  91            var included = includedStorage.GetCallSite("included", 1);
  92
  93            // Kernel#append_features inserts the module at the beginning of ancestors list;
  94            // ancestors after include: [modules[0], modules[1], ..., modules[N-1], self, ...]
  95            for (int i = modules.Length - 1; i >= 0; i--) {
  96                appendFeatures.Target(appendFeatures, modules[i], self);
  97                included.Target(included, modules[i], self);
  98            }
  99
 100            return self;
 101        }
 102
 103        [RubyMethod("included", RubyMethodAttributes.PrivateInstance)]
 104        public static void Included(RubyModule/*!*/ self, RubyModule/*!*/ owner) {
 105            // self has been included into owner
 106        }
 107
 108        // thread-safe:
 109        [RubyMethod("append_features", RubyMethodAttributes.PrivateInstance)]
 110        public static RubyModule/*!*/ AppendFeatures(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ owner) {
 111            owner.IncludeModules(self);
 112            return self;
 113        }
 114
 115        #endregion
 116
 117        #region private, protected, public, private_class_method, public_class_method, module_function
 118
 119        // thread-safe:
 120        [RubyMethod("private", RubyMethodAttributes.PrivateInstance)]
 121        public static RubyModule/*!*/ SetPrivateVisibility(RubyScope/*!*/ scope, RubyModule/*!*/ self,
 122            [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
 123
 124            // overwrites methods to instance:
 125            SetMethodAttributes(scope, self, methodNames, RubyMethodAttributes.PrivateInstance);
 126            return self;
 127        }
 128
 129        // thread-safe:
 130        [RubyMethod("protected", RubyMethodAttributes.PrivateInstance)]
 131        public static RubyModule/*!*/ SetProtectedVisibility(RubyScope/*!*/ scope, RubyModule/*!*/ self,
 132            [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
 133            // overwrites methods to instance:
 134            SetMethodAttributes(scope, self, methodNames, RubyMethodAttributes.ProtectedInstance);
 135            return self;
 136        }
 137
 138        // thread-safe:
 139        [RubyMethod("public", RubyMethodAttributes.PrivateInstance)]
 140        public static RubyModule/*!*/ SetPublicVisibility(RubyScope/*!*/ scope, RubyModule/*!*/ self,
 141            [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
 142            // overwrites methods to instance:
 143            SetMethodAttributes(scope, self, methodNames, RubyMethodAttributes.PublicInstance);
 144            return self;
 145        }
 146
 147        // thread-safe:
 148        [RubyMethodAttribute("private_class_method")]
 149        public static RubyModule/*!*/ MakeClassMethodsPrivate(RubyModule/*!*/ self,
 150            [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
 151            SetMethodAttributes(self.GetOrCreateSingletonClass(), methodNames, RubyMethodAttributes.Private);
 152            return self;
 153        }
 154
 155        // thread-safe:
 156        [RubyMethodAttribute("public_class_method")]
 157        public static RubyModule/*!*/ MakeClassMethodsPublic(RubyModule/*!*/ self,
 158            [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
 159            SetMethodAttributes(self.GetOrCreateSingletonClass(), methodNames, RubyMethodAttributes.Public);
 160            return self;
 161        }
 162
 163        // thread-safe:
 164        [RubyMethod("module_function", RubyMethodAttributes.PrivateInstance)]
 165        public static RubyModule/*!*/ CopyMethodsToModuleSingleton(RubyScope/*!*/ scope, RubyModule/*!*/ self,
 166            [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ methodNames) {
 167
 168            // This is an important restriction for correct super calls in module functions (see RubyOps.DefineMethod). 
 169            // MRI has it wrong. It checks just here and not in method definition.
 170            if (self.IsClass) {
 171                throw RubyExceptions.CreateTypeError("module_function must be called for modules");
 172            }
 173            
 174            // overwrites visibility to public:
 175            SetMethodAttributes(scope, self, methodNames, RubyMethodAttributes.ModuleFunction);
 176            return self;
 177        }
 178
 179        internal static void SetMethodAttributes(RubyScope/*!*/ scope, RubyModule/*!*/ module, string/*!*/[]/*!*/ methodNames, RubyMethodAttributes attributes) {
 180            if (methodNames.Length == 0) {
 181                scope.GetMethodAttributesDefinitionScope().MethodAttributes = attributes;
 182            } else {
 183                SetMethodAttributes(module, methodNames, attributes);
 184            }
 185        }
 186
 187        internal static void SetMethodAttributes(RubyModule/*!*/ module, string/*!*/[]/*!*/ methodNames, RubyMethodAttributes attributes) {
 188            var context = module.Context;
 189
 190            bool isModuleFunction = (attributes & RubyMethodAttributes.ModuleFunction) == RubyMethodAttributes.ModuleFunction;
 191            var instanceVisibility = isModuleFunction ? RubyMethodVisibility.Private : 
 192                (RubyMethodVisibility)(attributes & RubyMethodAttributes.VisibilityMask);
 193
 194            foreach (string methodName in methodNames) {
 195                RubyMemberInfo method;
 196
 197                // we need to define new methods one by one since the method_added events can define a new method that might be used here:
 198                using (context.ClassHierarchyLocker()) {
 199                    MethodLookup options = MethodLookup.FallbackToObject;
 200                    if (!isModuleFunction) {
 201                        options |= MethodLookup.ReturnForwarder;
 202                    }
 203
 204                    method = module.ResolveMethodNoLock(methodName, VisibilityContext.AllVisible, options).Info;
 205                    if (method == null) {
 206                        throw RubyExceptions.CreateUndefinedMethodError(module, methodName);
 207                    }
 208
 209                    // MRI only adds method to the target module if visibility differs:
 210                    if (method.Visibility != instanceVisibility) {
 211                        module.SetVisibilityNoEventNoLock(context, methodName, method, instanceVisibility);
 212                    }
 213
 214                    if (isModuleFunction) {
 215                        module.SetModuleFunctionNoEventNoLock(context, methodName, method);
 216                    }
 217                }
 218
 219                if (method.Visibility != instanceVisibility) {
 220                    module.MethodAdded(methodName);
 221                }
 222
 223                if (isModuleFunction) {
 224                    module.GetOrCreateSingletonClass().MethodAdded(methodName);
 225                }
 226            }
 227        }
 228
 229        #endregion
 230
 231        #region define_method (thread-safe)
 232
 233        // thread-safe:
 234        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 235        public static RubyMethod/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self, 
 236            [DefaultProtocol, NotNull]string/*!*/ methodName, [NotNull]RubyMethod/*!*/ method) {
 237
 238            DefineMethod(scope, self, methodName, method.Info,  method.GetTargetClass());
 239            return method;
 240        }
 241
 242        // thread-safe:
 243        // Defines method using mangled CLR name and aliases that method with the actual CLR name.
 244        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 245        public static RubyMethod/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self,
 246            [NotNull]ClrName/*!*/ methodName, [NotNull]RubyMethod/*!*/ method) {
 247            var result = DefineMethod(scope, self, methodName.MangledName, method);
 248            if (methodName.HasMangledName) {
 249                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
 250            }
 251            return result;
 252        }
 253
 254        // thread-safe:
 255        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 256        public static UnboundMethod/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self, 
 257            [DefaultProtocol, NotNull]string/*!*/ methodName, [NotNull]UnboundMethod/*!*/ method) {
 258
 259            DefineMethod(scope, self, methodName, method.Info, method.TargetConstraint);
 260            return method;
 261        }
 262
 263        // thread-safe:
 264        // Defines method using mangled CLR name and aliases that method with the actual CLR name.
 265        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 266        public static UnboundMethod/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self,
 267            [NotNull]ClrName/*!*/ methodName, [NotNull]UnboundMethod/*!*/ method) {
 268            var result = DefineMethod(scope, self, methodName.MangledName, method);
 269            if (methodName.HasMangledName) {
 270                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
 271            }
 272            return result;
 273        }
 274
 275        private static void DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self, string/*!*/ methodName, RubyMemberInfo/*!*/ info,
 276            RubyModule/*!*/ targetConstraint) {
 277
 278            var visibility = GetDefinedMethodVisibility(scope, self, methodName);
 279            using (self.Context.ClassHierarchyLocker()) {
 280                // MRI 1.8 does the check when the method is called, 1.9 checks it upfront as we do:
 281                if (!self.HasAncestorNoLock(targetConstraint)) {
 282                    throw RubyExceptions.CreateTypeError(
 283                        "bind argument must be a subclass of {0}", targetConstraint.GetName(scope.RubyContext)
 284                    );
 285                }
 286
 287                self.SetDefinedMethodNoEventNoLock(self.Context, methodName, info, visibility);
 288            }
 289
 290            self.MethodAdded(methodName);
 291        }
 292
 293        // thread-safe:
 294        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 295        public static Proc/*!*/ DefineMethod(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, 
 296            RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
 297
 298            return DefineMethod(scope, self, methodName, block.Proc);
 299        }
 300
 301        // thread-safe:
 302        // Defines method using mangled CLR name and aliases that method with the actual CLR name.
 303        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 304        public static Proc/*!*/ DefineMethod(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block,
 305            RubyModule/*!*/ self, [NotNull]ClrName/*!*/ methodName) {
 306
 307            var result = DefineMethod(scope, block, self, methodName.MangledName);
 308            if (methodName.HasMangledName) {
 309                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
 310            }
 311            return result;
 312        }
 313
 314        // thread-safe:
 315        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 316        public static Proc/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self, 
 317            [DefaultProtocol, NotNull]string/*!*/ methodName, [NotNull]Proc/*!*/ block) {
 318
 319            var visibility = GetDefinedMethodVisibility(scope, self, methodName);
 320            var info = Proc.ToLambdaMethodInfo(block, methodName, visibility, self);
 321            self.AddMethod(scope.RubyContext, methodName, info);
 322            return info.Lambda;
 323        }
 324
 325        // thread-safe:
 326        [RubyMethod("define_method", RubyMethodAttributes.PrivateInstance)]
 327        public static Proc/*!*/ DefineMethod(RubyScope/*!*/ scope, RubyModule/*!*/ self,
 328            [NotNull]ClrName/*!*/ methodName, [NotNull]Proc/*!*/ block) {
 329
 330            var result = DefineMethod(scope, self, methodName.MangledName, block);
 331            if (methodName.HasMangledName) {
 332                self.AddMethodAlias(methodName.ActualName, methodName.MangledName);
 333            }
 334            return result;
 335        }
 336
 337        private static RubyMethodVisibility GetDefinedMethodVisibility(RubyScope/*!*/ scope, RubyModule/*!*/ module, string/*!*/ methodName) {
 338            // MRI: Special names are private.
 339            // MRI: Doesn't create a singleton method if module_function is used in the scope, however the private visibility is applied (bug?)
 340            // MRI 1.8: uses the current scope's visibility only if the target module is the same as the scope's module (bug?)
 341            // MFI 1.9: always uses public visibility (bug?)
 342            RubyMethodVisibility visibility;
 343            if (scope.RubyContext.RubyOptions.Compatibility < RubyCompatibility.Ruby19) {
 344                var attributesScope = scope.GetMethodAttributesDefinitionScope();
 345                if (attributesScope.GetInnerMostModuleForMethodLookup() == module) {
 346                    bool isModuleFunction = (attributesScope.MethodAttributes & RubyMethodAttributes.ModuleFunction) == RubyMethodAttributes.ModuleFunction;
 347                    visibility = (isModuleFunction) ? RubyMethodVisibility.Private : attributesScope.Visibility;
 348                } else {
 349                    visibility = RubyMethodVisibility.Public;
 350                }
 351            } else {
 352                visibility = RubyMethodVisibility.Public;
 353            }
 354
 355            return RubyUtils.GetSpecialMethodVisibility(visibility, methodName);
 356        }
 357
 358        #endregion
 359
 360        #region method_(added|removed|undefined)
 361
 362        [RubyMethod("method_added", RubyMethodAttributes.PrivateInstance | RubyMethodAttributes.Empty)]
 363        public static void MethodAdded(object/*!*/ self, object methodName) {
 364            // nop
 365        }
 366
 367        [RubyMethod("method_removed", RubyMethodAttributes.PrivateInstance | RubyMethodAttributes.Empty)]
 368        public static void MethodRemoved(object/*!*/ self, object methodName) {
 369            // nop
 370        }
 371
 372        [RubyMethod("method_undefined", RubyMethodAttributes.PrivateInstance | RubyMethodAttributes.Empty)]
 373        public static void MethodUndefined(object/*!*/ self, object methodName) {
 374            // nop
 375        }
 376
 377        #endregion
 378
 379        #region attr, attr_{reader|writer|accessor} (thread-safe)
 380
 381        private static void DefineAccessor(RubyScope/*!*/ scope, RubyModule/*!*/ self, string/*!*/ name, bool readable, bool writable) {
 382            // MRI: ignores ModuleFunction scope flag (doesn't create singleton methods):
 383
 384            if (!Tokenizer.IsVariableName(name)) {
 385                throw RubyExceptions.CreateNameError("invalid attribute name `{0}'", name);
 386            }
 387
 388            var varName = "@" + name;
 389            var attributesScope = scope.GetMethodAttributesDefinitionScope();
 390
 391            if (readable) {
 392                var flags = (RubyMemberFlags)RubyUtils.GetSpecialMethodVisibility(attributesScope.Visibility, name);
 393                self.AddMethod(scope.RubyContext, name, new RubyAttributeReaderInfo(flags, self, varName));
 394            }
 395            
 396            if (writable) {
 397                self.AddMethod(scope.RubyContext, name + "=", new RubyAttributeWriterInfo((RubyMemberFlags)attributesScope.Visibility, self, varName));
 398            }
 399        }
 400
 401        // thread-safe:
 402        [RubyMethod("attr", RubyMethodAttributes.PrivateInstance)]
 403        public static void Attr(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ name, [Optional]bool writable) {
 404            DefineAccessor(scope, self, name, true, writable);
 405        }
 406
 407        // thread-safe:
 408        [RubyMethod("attr", RubyMethodAttributes.PrivateInstance)]
 409        public static void Attr(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ names) {
 410            foreach (string name in names) {
 411                DefineAccessor(scope, self, name, true, false);
 412            }
 413        }
 414
 415        // thread-safe:
 416        [RubyMethod("attr_accessor", RubyMethodAttributes.PrivateInstance)]
 417        public static void AttrAccessor(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ name) {
 418            DefineAccessor(scope, self, name, true, true);
 419        }
 420
 421        // thread-safe:
 422        [RubyMethod("attr_accessor", RubyMethodAttributes.PrivateInstance)]
 423        public static void AttrAccessor(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ names) {
 424            foreach (string name in names) {
 425                DefineAccessor(scope, self, name, true, true);
 426            }
 427        }
 428
 429        // thread-safe:
 430        [RubyMethod("attr_reader", RubyMethodAttributes.PrivateInstance)]
 431        public static void AttrReader(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ name) {
 432            DefineAccessor(scope, self, name, true, false);
 433        }
 434
 435        // thread-safe:
 436        [RubyMethod("attr_reader", RubyMethodAttributes.PrivateInstance)]
 437        public static void AttrReader(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ names) {
 438            foreach (string name in names) {
 439                DefineAccessor(scope, self, name, true, false);
 440            }
 441        }
 442
 443        // thread-safe:
 444        [RubyMethod("attr_writer", RubyMethodAttributes.PrivateInstance)]
 445        public static void AttrWriter(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ name) {
 446            DefineAccessor(scope, self, name, false, true);
 447        }
 448
 449        // thread-safe:
 450        [RubyMethod("attr_writer", RubyMethodAttributes.PrivateInstance)]
 451        public static void AttrWriter(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string/*!*/[]/*!*/ names) {
 452            foreach (string name in names) {
 453                DefineAccessor(scope, self, name, false, true);
 454            }
 455        }
 456
 457        #endregion
 458
 459        #region alias_method, remove_method, undef_method
 460
 461        // thread-safe:
 462        [RubyMethod("alias_method", RubyMethodAttributes.PrivateInstance)]
 463        public static RubyModule/*!*/ AliasMethod(RubyContext/*!*/ context, RubyModule/*!*/ self,
 464            [DefaultProtocol, NotNull]string/*!*/ newName, [DefaultProtocol, NotNull]string/*!*/ oldName) {
 465
 466            self.AddMethodAlias(newName, oldName);
 467            return self;
 468        }
 469
 470        // thread-safe:
 471        [RubyMethod("remove_method", RubyMethodAttributes.PrivateInstance)]
 472        public static RubyModule/*!*/ RemoveMethod(RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string[]/*!*/ methodNames) {
 473            foreach (var methodName in methodNames) {
 474                // MRI: reports a warning and allows removal
 475                if (self.IsBasicObjectClass && methodName == Symbols.Initialize) {
 476                    throw RubyExceptions.CreateNameError("Cannot remove BasicObject#initialize");
 477                }
 478
 479                if (!self.RemoveMethod(methodName)) {
 480                    throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
 481                }
 482            }
 483            return self;
 484        }
 485
 486        // thread-safe:
 487        [RubyMethod("undef_method", RubyMethodAttributes.PrivateInstance)]
 488        public static RubyModule/*!*/ UndefineMethod(RubyModule/*!*/ self, [DefaultProtocol, NotNullItems]params string[]/*!*/ methodNames) {
 489            foreach (var methodName in methodNames) {
 490                if (!self.ResolveMethod(methodName, VisibilityContext.AllVisible).Found) {
 491                    throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
 492                }
 493                self.UndefineMethod(methodName);
 494            }
 495            return self;
 496        }
 497
 498        #endregion
 499
 500
 501        #region <, >, <=, >=, <=>, ==, ===, ancestors, included_modules, include? (thread-safe)
 502
 503        // thread-safe:
 504        [RubyMethod("==")]
 505        public static bool Equals(RubyModule/*!*/ self, object other) {
 506            return ReferenceEquals(self, other);
 507        }
 508
 509        // thread-safe:
 510        [RubyMethod("===")]
 511        public static bool CaseEquals(RubyModule/*!*/ self, object other) {
 512            return self.Context.IsKindOf(other, self);
 513        }
 514
 515        // thread-safe:
 516        [RubyMethod("<")]
 517        public static object IsSubclassOrIncluded(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ module) {
 518            if (ReferenceEquals(self, module)) {
 519                return ScriptingRuntimeHelpers.False;
 520            }
 521            return self.HasAncestor(module) ? ScriptingRuntimeHelpers.True : null;
 522        }
 523
 524        // thread-safe:
 525        [RubyMethod("<=")]
 526        public static object IsSubclassSameOrIncluded(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ module) {
 527            if (self.Context != module.Context) {
 528                return null;
 529            } 
 530            
 531            using (self.Context.ClassHierarchyLocker()) {
 532                if (self.HasAncestorNoLock(module)) {
 533                    return ScriptingRuntimeHelpers.True;
 534                }
 535                return module.HasAncestorNoLock(self) ? ScriptingRuntimeHelpers.False : null;
 536            }
 537        }
 538
 539        // thread-safe:
 540        [RubyMethod(">")]
 541        public static object IsNotSubclassOrIncluded(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ module) {
 542            if (ReferenceEquals(self, module)) {
 543                return false;
 544            }
 545            return module.HasAncestor(self) ? ScriptingRuntimeHelpers.True : null;
 546        }
 547
 548        // thread-safe:
 549        [RubyMethod(">=")]
 550        public static object IsNotSubclassSameOrIncluded(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ module) {
 551            if (self.Context != module.Context) {
 552                return null;
 553            } 
 554            
 555            using (self.Context.ClassHierarchyLocker()) {
 556                if (module.HasAncestorNoLock(self)) {
 557                    return ScriptingRuntimeHelpers.True;
 558                }
 559                return self.HasAncestorNoLock(module) ? ScriptingRuntimeHelpers.False : null;
 560            }
 561        }
 562
 563        // thread-safe:
 564        [RubyMethod("<=>")]
 565        public static object Comparison(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ module) {
 566            if (ReferenceEquals(self, module)) {
 567                return ClrInteger.Zero;
 568            }
 569
 570            if (self.Context != module.Context) {
 571                return null;
 572            }
 573
 574            using (self.Context.ClassHierarchyLocker()) {
 575                if (self.HasAncestorNoLock(module)) {
 576                    return ClrInteger.MinusOne;
 577                }
 578
 579                if (module.HasAncestorNoLock(self)) {
 580                    return ClrInteger.One;
 581                }
 582            }
 583            return null;
 584        }
 585
 586        [RubyMethod("<=>")]
 587        public static object Comparison(RubyModule/*!*/ self, object module) {
 588            return null;
 589        }
 590
 591        [RubyMethod("<")]
 592        [RubyMethod(">")]
 593        [RubyMethod("<=")]
 594        [RubyMethod(">=")]
 595        public static object InvalidComparison(RubyModule/*!*/ self, object module) {
 596            throw RubyExceptions.CreateTypeError("compared with non class/module");
 597        }
 598
 599        // thread-safe:
 600        [RubyMethod("ancestors")]
 601        public static RubyArray/*!*/ Ancestors(RubyModule/*!*/ self) {
 602            RubyArray ancestors = new RubyArray();
 603
 604            using (self.Context.ClassHierarchyLocker()) {
 605                self.ForEachAncestor(true, delegate(RubyModule/*!*/ module) {
 606                    if (!module.IsSingletonClass) {
 607                        ancestors.Add(module);
 608                    }
 609                    return false;
 610                });
 611            }
 612            return ancestors;
 613        }
 614
 615        // thread-safe:
 616        [RubyMethod("included_modules")]
 617        public static RubyArray/*!*/ GetIncludedModules(RubyModule/*!*/ self) {
 618            RubyArray ancestorModules = new RubyArray();
 619
 620            using (self.Context.ClassHierarchyLocker()) {
 621                self.ForEachAncestor(true, delegate(RubyModule/*!*/ module) {
 622                    if (module != self && !module.IsClass && !ancestorModules.Contains(module)) {
 623                        ancestorModules.Add(module);
 624                    }
 625                    return false;
 626                });
 627            }
 628
 629            return ancestorModules;
 630        }
 631
 632        // thread-safe:
 633        [RubyMethod("include?")]
 634        public static bool IncludesModule(RubyModule/*!*/ self, [NotNull]RubyModule/*!*/ other) {
 635            if (other.IsClass) {
 636                throw RubyExceptions.CreateTypeError("wrong argument type Class (expected Module)");
 637            }
 638
 639            return other != self && self.HasAncestor(other);
 640        }
 641
 642        #endregion
 643
 644        #region (module|class)_(eval|exec)
 645
 646        [RubyMethod("module_eval")]
 647        [RubyMethod("class_eval")]
 648        public static object Evaluate(RubyScope/*!*/ scope, BlockParam block, RubyModule/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ code,
 649            [Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
 650
 651            if (block != null) {
 652                throw RubyExceptions.CreateArgumentError("wrong number of arguments");
 653            } 
 654            
 655            return RubyUtils.Evaluate(code, scope, self, self, file, line);
 656        }
 657
 658        [RubyMethod("module_eval")]
 659        [RubyMethod("class_eval")]
 660        public static object Evaluate([NotNull]BlockParam/*!*/ block, RubyModule/*!*/ self) {
 661            return RubyUtils.EvaluateInModule(self, block, null);
 662        }
 663
 664        // This method is not available in 1.8 so far, but since the usual workaround is very inefficient it is useful to have it in 1.8 as well.
 665        [RubyMethod("module_exec")]
 666        [RubyMethod("class_exec")]
 667        public static object Execute([NotNull]BlockParam/*!*/ block, RubyModule/*!*/ self, params object[]/*!*/ args) {
 668            return RubyUtils.EvaluateInModule(self, block, args);
 669        }
 670
 671        #endregion
 672
 673        #region class_variables, class_variable_defined?, class_variable_get, class_variable_set, remove_class_variable
 674
 675        // not thread-safe
 676        [RubyMethod("class_variables")]
 677        public static RubyArray/*!*/ ClassVariables(RubyModule/*!*/ self) {
 678            var result = new RubyArray();
 679            self.EnumerateClassVariables((module, name, value) => {
 680                result.Add(self.Context.StringifyIdentifier(name));
 681                return false;
 682            });
 683            return result;
 684        }
 685
 686        // not thread-safe:
 687        [RubyMethod("class_variable_defined?")]
 688        public static bool IsClassVariableDefined(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ variableName) {
 689            object value;
 690            if (self.TryResolveClassVariable(variableName, out value) == null) {
 691                RubyUtils.CheckClassVariableName(variableName);
 692                return false;
 693            }
 694            return true;
 695        }
 696
 697        // not thread-safe:
 698        [RubyMethod("class_variable_get", RubyMethodAttributes.PrivateInstance)]
 699        public static object GetClassVariable(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ variableName) {
 700            object value;
 701            if (self.TryResolveClassVariable(variableName, out value) == null) {
 702                RubyUtils.CheckClassVariableName(variableName);
 703                throw RubyExceptions.CreateNameError("uninitialized class variable {0} in {1}", variableName, self.Name);
 704            }
 705            return value;
 706        }
 707
 708        // not thread-safe:
 709        [RubyMethod("class_variable_set", RubyMethodAttributes.PrivateInstance)]
 710        public static object ClassVariableSet(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ variableName, object value) {
 711            RubyUtils.CheckClassVariableName(variableName);
 712            self.SetClassVariable(variableName, value);
 713            return value;
 714        }
 715
 716        // not thread-safe:
 717        [RubyMethod("remove_class_variable", RubyMethodAttributes.PrivateInstance)]
 718        public static object RemoveClassVariable(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ variableName) {
 719            object value;
 720            if (!self.TryGetClassVariable(variableName, out value)) {
 721                RubyUtils.CheckClassVariableName(variableName);
 722                throw RubyExceptions.CreateNameError("class variable {0} not defined for {1}", variableName, self.Name);
 723            }
 724            self.RemoveClassVariable(variableName);
 725            return value;
 726        }
 727
 728        #endregion
 729
 730        #region constants, const_defined?, const_set, const_get, remove_const, const_missing
 731
 732        // thread-safe:
 733        [RubyMethod("constants", RubyMethodAttributes.PublicSingleton)]
 734        public static RubyArray/*!*/ GetGlobalConstants(RubyModule/*!*/ self, [DefaultParameterValue(true)]bool inherited) {
 735            return GetDefinedConstants(self.Context.ObjectClass, inherited);
 736        }
 737
 738        // thread-safe:
 739        [RubyMethod("constants")]
 740        public static RubyArray/*!*/ GetDefinedConstants(RubyModule/*!*/ self, [DefaultParameterValue(true)]bool inherited) {
 741            var result = new RubyArray();
 742            if (inherited) {
 743                var visited = new Dictionary<string, bool>();
 744
 745                bool hideGlobalConstants = !self.IsObjectClass;
 746
 747                using (self.Context.ClassHierarchyLocker()) {
 748                    self.ForEachConstant(true, delegate(RubyModule/*!*/ module, string name, object value) {
 749                        if (name == null) {
 750                            // terminate enumeration when Object is reached
 751                            return hideGlobalConstants && module.IsObjectClass;
 752                        }
 753
 754                        if (!visited.ContainsKey(name)) {
 755                            if (Tokenizer.IsConstantName(name)) {
 756                                result.Add(self.Context.StringifyIdentifier(name));
 757                            }
 758                            visited.Add(name, true);
 759                        }
 760                        return false;
 761                    });
 762                }
 763
 764            } else {
 765                using (self.Context.ClassHierarchyLocker()) {
 766                    self.EnumerateConstants((module, name, value) => {
 767                        if (Tokenizer.IsConstantName(name)) {
 768                            result.Add(self.Context.StringifyIdentifier(name));
 769                        }
 770                        return false;
 771                    });
 772                }
 773            }
 774            return result;
 775        }
 776
 777        // thread-safe:
 778        [RubyMethod("const_defined?")]
 779        public static bool IsConstantDefined(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ constantName) {
 780            RubyUtils.CheckConstantName(constantName);
 781            object constant;
 782
 783            // MRI checks declared constans only and don't trigger autoload:
 784            return self.TryGetConstant(null, constantName, out constant);
 785        }
 786
 787        // thread-safe:
 788        [RubyMethod("const_get")]
 789        public static object GetConstantValue(RubyScope/*!*/ scope, RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ constantName) {
 790            return RubyUtils.GetConstant(scope.GlobalScope, self, constantName, true);
 791        }
 792
 793        // thread-safe:
 794        [RubyMethod("const_set")]
 795        public static object SetConstantValue(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ constantName, object value) {
 796            RubyUtils.CheckConstantName(constantName);
 797            RubyUtils.SetConstant(self, constantName, value);
 798            return value;
 799        }
 800
 801        // thread-safe:
 802        [RubyMethod("remove_const", RubyMethodAttributes.PrivateInstance)]
 803        public static object RemoveConstant(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ constantName) {
 804            object value;
 805            if (!self.TryRemoveConstant(constantName, out value)) {
 806                RubyUtils.CheckConstantName(constantName);
 807                throw RubyExceptions.CreateNameError("constant {0}::{1} not defined", self.Name, constantName);
 808            }
 809            return value;
 810        }
 811
 812        [RubyMethod("const_missing")]
 813        public static object ConstantMissing(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ name) {
 814            return self.Context.ResolveMissingConstant(self, name);
 815        }
 816
 817        #endregion
 818
 819        #region autoload, autoload?
 820
 821        // thread-safe:
 822        [RubyMethod("autoload")]
 823        public static void SetAutoloadedConstant(RubyModule/*!*/ self,
 824            [DefaultProtocol, NotNull]string/*!*/ constantName, [DefaultProtocol, NotNull]MutableString/*!*/ path) {
 825
 826            RubyUtils.CheckConstantName(constantName);
 827            if (path.IsEmpty) {
 828                throw RubyExceptions.CreateArgumentError("empty file name");
 829            }
 830
 831            self.SetAutoloadedConstant(constantName, path);
 832        }
 833
 834        // thread-safe:
 835        [RubyMethod("autoload?")]
 836        public static MutableString GetAutoloadedConstantPath(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ constantName) {
 837            return self.GetAutoloadedConstantPath(constantName);
 838        }
 839
 840        #endregion
 841
 842        #region {private_|protected_|public_|}instance_methods (thread-safe)
 843
 844        // thread-safe:
 845        [RubyMethod("instance_methods")]
 846        public static RubyArray/*!*/ GetInstanceMethods(RubyModule/*!*/ self) {
 847            return GetInstanceMethods(self, true);
 848        }
 849
 850        // thread-safe:
 851        [RubyMethod("instance_methods")]
 852        public static RubyArray/*!*/ GetInstanceMethods(RubyModule/*!*/ self, bool inherited) {
 853            return GetMethods(self, inherited, RubyMethodAttributes.PublicInstance | RubyMethodAttributes.ProtectedInstance);
 854        }
 855
 856        // thread-safe:
 857        [RubyMethod("private_instance_methods")]
 858        public static RubyArray/*!*/ GetPrivateInstanceMethods(RubyModule/*!*/ self) {
 859            return GetPrivateInstanceMethods(self, true);
 860        }
 861
 862        // thread-safe:
 863        [RubyMethod("private_instance_methods")]
 864        public static RubyArray/*!*/ GetPrivateInstanceMethods(RubyModule/*!*/ self, bool inherited) {
 865            return GetMethods(self, inherited, RubyMethodAttributes.PrivateInstance);
 866        }
 867
 868        // thread-safe:
 869        [RubyMethod("protected_instance_methods")]
 870        public static RubyArray/*!*/ GetProtectedInstanceMethods(RubyModule/*!*/ self) {
 871            return GetProtectedInstanceMethods(self, true);
 872        }
 873
 874        // thread-safe:
 875        [RubyMethod("protected_instance_methods")]
 876        public static RubyArray/*!*/ GetProtectedInstanceMethods(RubyModule/*!*/ self, bool inherited) {
 877            return GetMethods(self, inherited, RubyMethodAttributes.ProtectedInstance);
 878        }
 879
 880        // thread-safe:
 881        [RubyMethod("public_instance_methods")]
 882        public static RubyArray/*!*/ GetPublicInstanceMethods(RubyModule/*!*/ self) {
 883            return GetPublicInstanceMethods(self, true);
 884        }
 885
 886        // thread-safe:
 887        [RubyMethod("public_instance_methods")]
 888        public static RubyArray/*!*/ GetPublicInstanceMethods(RubyModule/*!*/ self, bool inherited) {
 889            return GetMethods(self, inherited, RubyMethodAttributes.PublicInstance);
 890        }
 891
 892        internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes) {
 893            return GetMethods(self, inherited, attributes, null);
 894        }
 895
 896        internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes,
 897            IEnumerable<string> foreignMembers) {
 898
 899            var result = new RubyArray();
 900            using (self.Context.ClassHierarchyLocker()) {
 901                self.ForEachMember(inherited, attributes, foreignMembers, (name, module, member) => {
 902                    if (member.IsInteropMember && (module.Restrictions & ModuleRestrictions.NoNameMapping) == 0 && RubyUtils.HasMangledName(name)) {
 903                        if (Tokenizer.IsMethodName(name) || Tokenizer.IsOperatorName(name)) {
 904                            result.Add(new ClrName(name));
 905                        }
 906                    } else {
 907                        result.Add(self.Context.StringifyIdentifier(name));
 908                    }
 909                });
 910            }
 911            return result;
 912        }
 913
 914        #endregion
 915
 916        #region {private_|protected_|public_|}method_defined? (thread-safe)
 917
 918        // thread-safe:
 919        [RubyMethod("method_defined?")]
 920        public static bool MethodDefined(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
 921            RubyMemberInfo method = self.ResolveMethod(methodName, VisibilityContext.AllVisible).Info;
 922            return method != null && method.Visibility != RubyMethodVisibility.Private;
 923        }
 924
 925        // thread-safe:
 926        [RubyMethod("private_method_defined?")]
 927        public static bool PrivateMethodDefined(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
 928            RubyMemberInfo method = self.ResolveMethod(methodName, VisibilityContext.AllVisible).Info;
 929            return method != null && method.Visibility == RubyMethodVisibility.Private;
 930        }
 931
 932        // thread-safe:
 933        [RubyMethod("protected_method_defined?")]
 934        public static bool ProtectedMethodDefined(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
 935            RubyMemberInfo method = self.ResolveMethod(methodName, VisibilityContext.AllVisible).Info;
 936            return method != null && method.Visibility == RubyMethodVisibility.Protected;
 937        }
 938
 939        // thread-safe:
 940        [RubyMethod("public_method_defined?")]
 941        public static bool PublicMethodDefined(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
 942            RubyMemberInfo method = self.ResolveMethod(methodName, VisibilityContext.AllVisible).Info;
 943            return method != null && method.Visibility == RubyMethodVisibility.Public;
 944        }
 945
 946        #endregion
 947
 948        #region instance_method, 1.9: public_instance_method
 949
 950        // thread-safe:
 951        [RubyMethod("instance_method")]
 952        public static UnboundMethod/*!*/ GetInstanceMethod(RubyModule/*!*/ self, [DefaultProtocol, NotNull]string/*!*/ methodName) {
 953            RubyMemberInfo method = self.ResolveMethod(methodName, VisibilityContext.AllVisible).Info;
 954            if (method == null) {
 955                throw RubyExceptions.CreateUndefinedMethodError(self, methodName);
 956            }
 957
 958            RubyModule constraint = self;
 959            if (self.IsSingletonClass && method.DeclaringModule != self) {
 960                constraint = ((RubyClass)self).SuperClass;
 961            }
 962
 963            // unbound method binable to any class with "constraint" mixin:
 964            return new UnboundMethod(constraint, methodName, method);
 965        }
 966
 967        #endregion
 968
 969        #region to_s, name, freeze
 970
 971        [RubyMethod("to_s")]
 972        public static MutableString/*!*/ ToS(RubyContext/*!*/ context, RubyModule/*!*/ self) {
 973            return self.GetDisplayName(context, false);
 974        }
 975
 976        [RubyMethod("name")]
 977        public static MutableString/*!*/ GetName(RubyContext/*!*/ context, RubyModule/*!*/ self) {
 978            return self.GetDisplayName(context, true);
 979        }
 980
 981        [RubyMethod("freeze")]
 982        public static RubyModule/*!*/ Freeze(RubyContext/*!*/ context, RubyModule/*!*/ self) {
 983            self.Freeze();
 984            return self;
 985        }
 986
 987        #endregion
 988
 989        #region IronRuby: to_clr_type, of, []
 990
 991        [RubyMethod("to_clr_type")]
 992        public static Type ToClrType(RubyModule/*!*/ self) {
 993            return self.TypeTracker != null ? self.TypeTracker.Type : null;
 994        }
 995
 996        [RubyMethod("to_clr_ref")]
 997        public static RubyModule ToClrRef(RubyModule/*!*/ self) {
 998            try {
 999                return self.TypeTracker != null ? self.Context.GetClass(self.TypeTracker.Type.MakeByRefType()) : null;
1000            } catch (Exception) {
1001                throw RubyExceptions.CreateTypeError(
1002                    "Cannot create by-ref type for `{0}'", self.Context.GetTypeName(self.TypeTracker.Type, true)
1003                );
1004            }
1005        }
1006
1007        [RubyMethod("of")]
1008        [RubyMethod("[]")]
1009        public static RubyModule/*!*/ Of(RubyModule/*!*/ self, [NotNullItems]params object/*!*/[]/*!*/ typeArgs) {
1010            if (self.TypeTracker == null) {
1011                throw RubyExceptions.CreateArgumentError("'{0}' is not a type", self.Name);
1012            }
1013
1014            Type type = self.TypeTracker.Type;
1015            int provided = typeArgs.Length;
1016
1017            if (provided == 1 && type == typeof(Array)) {
1018                Type elementType = Protocols.ToType(self.Context, typeArgs[0]);
1019                Type arrayType;
1020                try {
1021                    arrayType = elementType.MakeArrayType();
1022                } catch (Exception) {
1023                    throw RubyExceptions.CreateTypeError(
1024                        "Cannot create array type for `{0}'", self.Context.GetTypeName(elementType, true)
1025                    );
1026                }
1027                return self.Context.GetModule(arrayType);
1028            }
1029
1030            if (!type.IsGenericTypeDefinition) {
1031                if (provided > 0) {
1032                    throw RubyExceptions.CreateArgumentError("`{0}' is not a generic type definition", self.Name);
1033                }
1034                return self;
1035            }
1036
1037            int required = type.GetGenericArguments().Length;
1038            if (required != provided) {
1039                throw RubyExceptions.CreateArgumentError("Type `{0}' requires {1} generic type arguments, {2} provided", self.Name, required, provided);
1040            }
1041
1042            Type concreteType = type.MakeGenericType(Protocols.ToTypes(self.Context, typeArgs));
1043            return self.Context.GetModule(concreteType);
1044        }
1045
1046        [RubyMethod("of")]
1047        [RubyMethod("[]")]
1048        public static RubyModule/*!*/ Of(RubyModule/*!*/ self, int genericArity) {
1049            if (self.TypeTracker == null) {
1050                throw RubyExceptions.CreateArgumentError("`{0}' is not a type", self.Name);
1051            }
1052
1053            Type type = self.TypeTracker.Type;
1054
1055            if (!type.IsGenericTypeDefinition) {
1056                if (genericArity > 0) {
1057                    throw RubyExceptions.CreateArgumentError("`{0}' is not a generic type definition", self.Name);
1058                }
1059                return self;
1060            }
1061            
1062            if (type.GetGenericArguments().Length != genericArity) {
1063                throw RubyExceptions.CreateArgumentError("`{0}' does not have generic arity {1}", self.Name, genericArity);
1064            }
1065
1066            return self;
1067        }
1068
1069        #endregion
1070
1071        
1072        #region nesting
1073
1074        [RubyMethod("nesting", RubyMethodAttributes.PublicSingleton)]
1075        public static RubyArray/*!*/ GetLexicalModuleNesting(RubyScope/*!*/ scope, RubyModule/*!*/ self) {
1076            RubyArray result = new RubyArray();
1077            do {
1078                // Ruby 1.9: the anonymous module doesn't show up
1079                if (scope.Module != null) {
1080                    result.Add(scope.Module);
1081                }
1082                scope = (RubyScope)scope.Parent;
1083            } while (scope != null);
1084            return result;
1085        }
1086
1087        #endregion
1088    }
1089}