internal void Initialize(RuntimeFlowControl /*!*/ runtimeFlowControl, RubyMethodAttributes methodAttributes, object selfObject) { Assert.NotNull(runtimeFlowControl); _selfObject = selfObject; _runtimeFlowControl = runtimeFlowControl; _methodAttributes = methodAttributes; }
public RubyMethodAttribute(string /*!*/ name, RubyMethodAttributes methodAttributes) : base() { ContractUtils.RequiresNotNull(name, "name"); _name = name; _methodAttributes = methodAttributes; }
private IEnumerable <string> GetMethodNames(RubyMethodAttributes methodType) { var result = new List <string>(); GetMethodNames(ClrType, methods => result.AddRange((from m in methods where m.MethodAttributes == methodType select m.Name).Distinct())); result.Sort(); return(result); }
private static RubyModule/*!*/ SetVisibility(RubyScope/*!*/ scope, object/*!*/ self, string/*!*/[]/*!*/ methodNames, RubyMethodAttributes attributes) { Assert.NotNull(scope, self, methodNames); RubyModule module; // MRI: Method is searched in the class of self (Object), not in the main singleton class. // IronRuby specific: If we are in a top-level scope with redirected method lookup module we use that module (hosted scopes). var topScope = scope.Top.GlobalScope.TopLocalScope; if (scope == topScope && topScope.MethodLookupModule != null) { module = topScope.MethodLookupModule; } else { module = scope.RubyContext.GetClassOf(self); } ModuleOps.SetMethodAttributes(scope, module, methodNames, attributes); return module; }
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(scope.RubyContext, methodName, method); } else { module.SetMethodVisibility(scope.RubyContext, methodName, method, (RubyMethodVisibility)(attributes & RubyMethodAttributes.VisibilityMask)); } } } }
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)); } } } }
internal static void SetMethodAttributes(RubyScope /*!*/ scope, RubyModule /*!*/ module, string /*!*/[] /*!*/ methodNames, RubyMethodAttributes attributes) { if (methodNames.Length == 0) { scope.GetMethodAttributesDefinitionScope().MethodAttributes = attributes; } else { SetMethodAttributes(module, methodNames, attributes); } }
private static RubyModule /*!*/ SetVisibility(RubyScope /*!*/ scope, object /*!*/ self, string /*!*/[] /*!*/ methodNames, RubyMethodAttributes attributes) { Assert.NotNull(scope, self, methodNames); RubyModule module; // MRI: Method is searched in the class of self (Object), not in the main singleton class. // IronRuby specific: If we are in a top-level scope with redirected method lookup module we use that module (hosted scopes). var topScope = scope.Top.GlobalScope.TopLocalScope; if (scope == topScope && topScope.MethodLookupModule != null) { module = topScope.MethodLookupModule; } else { module = scope.RubyContext.GetClassOf(self); } ModuleOps.SetMethodAttributes(scope, module, methodNames, attributes); return(module); }
public VisibilityContext(RubyMethodAttributes mask) { Class = null; Visible = mask; }
public void ForEachMember(bool inherited, RubyMethodAttributes attributes, Action<string/*!*/, RubyModule/*!*/, RubyMemberInfo/*!*/>/*!*/ action) { ForEachMember(inherited, attributes, null, action); }
public VisibilityContext(RubyClass cls) { Class = cls; Visible = RubyMethodAttributes.VisibilityMask; }
internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes) { return GetMethods(self, inherited, attributes, null); }
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); } } }
internal static void SetMethodAttributes(RubyScope/*!*/ scope, RubyModule/*!*/ module, string/*!*/[]/*!*/ methodNames, RubyMethodAttributes attributes) { if (methodNames.Length == 0) { scope.GetMethodAttributesDefinitionScope().MethodAttributes = attributes; } else { SetMethodAttributes(module, methodNames, attributes); } }
internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes, IEnumerable<string> foreignMembers) { var result = new RubyArray(); var symbolicNames = self.Context.RubyOptions.Compatibility > RubyCompatibility.Ruby18; using (self.Context.ClassHierarchyLocker()) { self.ForEachMember(inherited, attributes, foreignMembers, delegate(string/*!*/ name, RubyMemberInfo member) { result.Add(CreateMethodName(name, symbolicNames)); }); } return result; }
// other scopes: protected RubyScope(RubyScope/*!*/ parent, RuntimeFlowControl/*!*/ runtimeFlowControl, object selfObject) { Assert.NotNull(parent); _parent = parent; _top = parent.Top; _selfObject = selfObject; _runtimeFlowControl = runtimeFlowControl; _methodAttributes = RubyMethodAttributes.PrivateInstance; }
// top scope: protected RubyScope(RuntimeFlowControl/*!*/ runtimeFlowControl, object selfObject) { _top = (RubyTopLevelScope)this; _parent = null; _selfObject = selfObject; _runtimeFlowControl = runtimeFlowControl; _methodAttributes = RubyMethodAttributes.PrivateInstance; }
internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes, IEnumerable<string> foreignMembers) { var result = new RubyArray(); var symbolicNames = self.Context.RubyOptions.Compatibility > RubyCompatibility.Ruby18; using (self.Context.ClassHierarchyLocker()) { self.ForEachMember(inherited, attributes, foreignMembers, (name, module, member) => { if (member.IsInteropMember && (module.Restrictions & ModuleRestrictions.NoNameMapping) == 0 && RubyUtils.HasMangledName(name)) { result.Add(new ClrName(name)); } else { result.Add(CreateMethodName(name, symbolicNames)); } }); } return result; }
/// <summary> /// メソッド定義情報を取得する。 /// </summary> /// <param name="constant">モジュールまたはクラスのRubyオブジェクト。</param> /// <param name="attributes">メソッド取得対象を表すスイッチ。</param> /// <param name="objectDefinition">オブジェクト定義のインスタンス。</param> /// <param name="singleton">シングルトンメソッドか?</param> private static void GetMethodDefinitions( RubyModule constant, RubyMethodAttributes attributes, RubyObjectDefinition objectDefinition, bool singleton) { constant.ForEachMember(false, attributes | RubyMethodAttributes.VisibilityMask, (methodName, module, memberInfo) => { if (memberInfo is RubyAttributeAccessorInfo) { var accessorInfo = (RubyAttributeAccessorInfo)memberInfo; var accessorName = methodName; if (accessorInfo is RubyAttributeWriterInfo) { accessorName = accessorName.Substring(0, accessorName.Length - 1); } var accessorDefinition = ( from a in objectDefinition.Accessors where a.Name == accessorName select a ).FirstOrDefault(); if (accessorDefinition == null) { accessorDefinition = new RubyAccessorDefinition() { Name = accessorName }; objectDefinition.Accessors.Add(accessorDefinition); } if (accessorInfo is RubyAttributeWriterInfo) { accessorDefinition.Writable = true; } else if (accessorInfo is RubyAttributeReaderInfo) { accessorDefinition.Readable = true; } else { throw new NotImplementedException(); } } else if (memberInfo is RubyMethodInfo) { var methodInfo = (RubyMethodInfo)memberInfo; var methodDefinition = new RubyMethodDefinition() { Name = methodName, Singleton = singleton }; foreach (LocalVariable argument in methodInfo.Parameters.Mandatory) { methodDefinition.Arguments.Add( new RubyMethodArgumentDefinition() { Name = argument.Name, Optional = false } ); } foreach (SimpleAssignmentExpression argument in methodInfo.Parameters.Optional) { var argumentDefinition = new RubyMethodArgumentDefinition() { Name = ((LocalVariable)argument.Left).Name, Optional = true }; if (argument.Right is Literal) { argumentDefinition.DefaultValue = ((Literal)argument.Right).Value; } else if (argument.Right is ClassVariable) { argumentDefinition.DefaultValue = ((ClassVariable)argument.Right).Name; argumentDefinition.ClassVariable = true; } methodDefinition.Arguments.Add(argumentDefinition); } objectDefinition.Methods.Add(methodDefinition); } else { throw new NotImplementedException(); } }); }
/// <summary> /// inherited == false, attributes & attr == Instance: /// - get methods in the "self" module /// - also include methods on singleton ancestor classes until a non-singleton class is reached /// inherited == false, attributes & attr == Singleton: /// - get methods only in the "self" module if it's a singleton class /// - do not visit mixins nor super classes /// inherited == true, attributes & attr == Singleton: /// - walk all ancestors until a non-singleton class is reached (do not include non-singleton's methods) /// inherited == true, attributes & attr == None: /// - walk all ancestors until an Object is reached /// /// Methods are filtered by visibility specified in attributes (mutliple visibilities could be specified). /// A name undefined in a module is not visible in that module and its ancestors. /// Method names are not duplicated in the result. /// </summary> /// <remarks> /// Not thread safe. /// </remarks> public void ForEachMember(bool inherited, RubyMethodAttributes attributes, IEnumerable<string> foreignMembers, Action<string/*!*/, RubyModule/*!*/, RubyMemberInfo/*!*/>/*!*/ action) { Context.RequiresClassHierarchyLock(); var visited = new Dictionary<string, RubyMemberInfo>(); // We can look for instance methods, singleton methods or all methods. // The difference is when we stop searching. bool instanceMethods = (attributes & RubyMethodAttributes.Instance) != 0; bool singletonMethods = (attributes & RubyMethodAttributes.Singleton) != 0; // TODO: if we allow creating singletons for foreign objects we need to change this: if (foreignMembers != null) { foreach (var name in foreignMembers) { action(name, this, RubyMethodInfo.InteropMember); visited.Add(name, RubyMethodInfo.InteropMember); } } bool stop = false; ForEachInstanceMethod(true, delegate(RubyModule/*!*/ module, string name, RubyMemberInfo member) { if (member == null) { // notification received before any method of the module if (stop) { return true; } if (instanceMethods) { stop = !inherited && (!IsClass || module.IsClass && !module.IsSingletonClass); } else if (singletonMethods) { if (!inherited && module != this || module.IsClass && !module.IsSingletonClass) { return true; } } else { stop = !inherited; } } else if (!visited.ContainsKey(name)) { // yield the member only if it has the right visibility: if (!member.IsUndefined && !member.IsHidden && (((RubyMethodAttributes)member.Visibility & attributes) != 0)) { action(name, module, member); } // visit the member even if it doesn't have the right visibility so that any overridden member with the right visibility // won't later be visited: visited.Add(name, member); } return false; }); }
private static RubyArray/*!*/ GetMethods(RubyContext/*!*/ context, object self, bool inherited, RubyMethodAttributes attributes) { RubyClass immediateClass = context.GetImmediateClassOf(self); return ModuleOps.GetMethods(immediateClass, inherited, attributes); }
private Dictionary<string, RubyMemberInfo> GetMethods(RubyMethodAttributes attributes) { // TODO: custom view for methods, sorted var result = new Dictionary<string, RubyMemberInfo>(); using (_obj.Context.ClassHierarchyLocker()) { _obj.ForEachMember(false, attributes | RubyMethodAttributes.VisibilityMask, (name, _, info) => { result[name] = info; }); } return result; }
internal static RubyArray /*!*/ GetMethods(RubyModule /*!*/ self, bool inherited, RubyMethodAttributes attributes) { return(GetMethods(self, inherited, attributes, null)); }
internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes, IEnumerable<string> foreignMembers) { var result = new RubyArray(); using (self.Context.ClassHierarchyLocker()) { self.ForEachMember(inherited, attributes, foreignMembers, (name, module, member) => { if (member.IsInteropMember && (module.Restrictions & ModuleRestrictions.NoNameMapping) == 0 && RubyUtils.HasMangledName(name)) { if (Tokenizer.IsMethodName(name) || Tokenizer.IsOperatorName(name)) { result.Add(new ClrName(name)); } } else { result.Add(self.Context.StringifyIdentifier(name)); } }); } return result; }
internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes) { var result = new RubyArray(); self.ForEachMember(inherited, attributes, delegate(string/*!*/ name, RubyMemberInfo/*!*/ member) { result.Add(MutableString.Create(name)); }); return result; }
/// <summary> /// inherited == false, attributes & attr == Instance: /// - get methods in the "self" module /// - also include methods on singleton ancestor classes until a non-singleton class is reached /// inherited == false, attributes & attr == Singleton: /// - get methods only in the "self" module if it's a singleton class /// - do not visit mixins nor super classes /// inherited == true, attributes & attr == Singleton: /// - walk all ancestors until a non-singleton class is reached (do not include non-singleton's methods) /// inherited == true, attributes & attr == None: /// - walk all ancestors until an Object is reached /// /// Methods are filtered by visibility specified in attributes (mutliple visibilities could be specified). /// A name undefined in a module is not visible in that module and its ancestors. /// Method names are not duplicated in the result. /// </summary> /// <remarks> /// Not thread safe. /// </remarks> public void ForEachMember(bool inherited, RubyMethodAttributes attributes, Action<string/*!*/, RubyMemberInfo/*!*/>/*!*/ action) { Context.RequiresClassHierarchyLock(); var visited = new Dictionary<string, bool>(); // We can look for instance methods, singleton methods or all methods. // The difference is when we stop searching. bool instanceMethods = (attributes & RubyMethodAttributes.Instance) != 0; bool singletonMethods = (attributes & RubyMethodAttributes.Singleton) != 0; bool stop = false; ForEachInstanceMethod(true, delegate(RubyModule/*!*/ module, string name, RubyMemberInfo member) { if (member == null) { // notification received before any method of the module if (stop) { return true; } if (instanceMethods) { stop = !inherited && (!IsClass || module.IsClass && !module.IsSingletonClass); } else if (singletonMethods) { if (!inherited && module != this || module.IsClass && !module.IsSingletonClass) { return true; } } else { stop = !inherited; } } else if (member.IsUndefined) { visited.Add(name, true); } else if (((RubyMethodAttributes)member.Visibility & attributes) != 0 && !visited.ContainsKey(name)) { action(name, member); visited.Add(name, true); } return false; }); }
internal static RubyArray /*!*/ GetMethods(RubyModule /*!*/ self, bool inherited, RubyMethodAttributes attributes, IEnumerable <string> foreignMembers) { var result = new RubyArray(); using (self.Context.ClassHierarchyLocker()) { self.ForEachMember(inherited, attributes, foreignMembers, (name, module, member) => { if (member.IsInteropMember && (module.Restrictions & ModuleRestrictions.NoNameMapping) == 0 && RubyUtils.HasMangledName(name)) { if (Tokenizer.IsMethodName(name) || Tokenizer.IsOperatorName(name)) { result.Add(new ClrName(name)); } } else { result.Add(self.Context.StringifyIdentifier(name)); } }); } return(result); }
internal void Initialize(RuntimeFlowControl/*!*/ runtimeFlowControl, RubyMethodAttributes methodAttributes, object selfObject) { Assert.NotNull(runtimeFlowControl); _selfObject = selfObject; _runtimeFlowControl = runtimeFlowControl; _methodAttributes = methodAttributes; }
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 RubyModule/*!*/ SetVisibility(RubyScope/*!*/ scope, object/*!*/ self, object[]/*!*/ methodNames, RubyMethodAttributes attributes) { Assert.NotNull(scope, self, methodNames); RubyClass cls = scope.RubyContext.GetClassOf(self); ModuleOps.SetMethodAttributes(scope, cls, methodNames, attributes); return cls; }
internal static RubyArray /*!*/ GetMethods(RubyModule /*!*/ self, bool inherited, RubyMethodAttributes attributes) { var result = new RubyArray(); self.ForEachMember(inherited, attributes, delegate(string /*!*/ name, RubyMemberInfo /*!*/ member) { result.Add(MutableString.Create(name)); }); return(result); }
public RubyMethodAttribute(string/*!*/ name, RubyMethodAttributes methodAttributes) : base() { ContractUtils.RequiresNotNull(name, "name"); _name = name; _methodAttributes = methodAttributes; }
internal static RubyArray/*!*/ GetMethods(RubyModule/*!*/ self, bool inherited, RubyMethodAttributes attributes) { var result = new RubyArray(); var symbolicNames = self.Context.RubyOptions.Compatibility > RubyCompatibility.Ruby18; self.ForEachMember(inherited, attributes, delegate(string/*!*/ name, RubyMemberInfo/*!*/ member) { if (symbolicNames) { result.Add(SymbolTable.StringToId(name)); } else { result.Add(MutableString.Create(name)); } }); return result; }
private static RubyModule /*!*/ SetVisibility(RubyScope /*!*/ scope, object /*!*/ self, object[] /*!*/ methodNames, RubyMethodAttributes attributes) { Assert.NotNull(scope, self, methodNames); RubyClass cls = scope.RubyContext.GetClassOf(self); ModuleOps.SetMethodAttributes(scope, cls, methodNames, attributes); return(cls); }