public ResolveMethodNoLock ( string name, |
||
name | string | |
visibility | ||
options | MethodLookup | |
return | IronRuby.Runtime.Calls.MethodResolutionResult |
public MethodResolutionResult ResolveMethodNoLock(string/*!*/ name, VisibilityContext visibility, MethodLookup options) {
Context.RequiresClassHierarchyLock();
Assert.NotNull(name);
InitializeMethodsNoLock();
RubyMemberInfo info = null;
RubyModule owner = null;
bool skipHidden = false;
bool foundCallerSelf = false;
MethodResolutionResult result;
if (ForEachAncestor((module) => {
owner = module;
foundCallerSelf |= module == visibility.Class;
return module.TryGetMethod(name, ref skipHidden, (options & MethodLookup.Virtual) != 0, out info);
})) {
if (info == null || info.IsUndefined) {
result = MethodResolutionResult.NotFound;
} else if (!IsMethodVisible(info, owner, visibility, foundCallerSelf)) {
result = new MethodResolutionResult(info, owner, false);
} else if (info.IsSuperForwarder) {
if ((options & MethodLookup.ReturnForwarder) != 0) {
result = new MethodResolutionResult(info, owner, true);
} else {
// start again with owner's super ancestor and ignore visibility:
result = owner.ResolveSuperMethodNoLock(((SuperForwarderInfo)info).SuperName, owner);
}
} else {
result = new MethodResolutionResult(info, owner, true);
}
} else {
result = MethodResolutionResult.NotFound;
}
// TODO: BasicObject
// Note: all classes include Object in ancestors, so we don't need to search it again:
if (!result.Found && (options & MethodLookup.FallbackToObject) != 0 && !IsClass) {
return _context.ObjectClass.ResolveMethodNoLock(name, visibility, options & ~MethodLookup.FallbackToObject);
}
return result;
}
RubyModule::ResolveMethodNoLock ( string name, |
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); } } }