internal bool TryGetMethod(string/*!*/ name, ref bool skipHidden, bool virtualLookup, out RubyMemberInfo method) {
Context.RequiresClassHierarchyLock();
Debug.Assert(_methods != null);
// lookup Ruby method first:
if (TryGetDefinedMethod(name, ref skipHidden, out method)) {
return true;
}
if (virtualLookup) {
string mangled;
// Note: property and default indexers getters and setters use FooBar, FooBar= and [], []= names, respectively, in virtual sites:
if ((mangled = RubyUtils.TryMangleMethodName(name)) != null && TryGetDefinedMethod(mangled, ref skipHidden, out method)
&& method.IsRubyMember) {
return true;
}
// Special mappings:
// Do not map to Kernel#hash/eql?/to_s to prevent recursion in case Object.GetHashCode/Equals/ToString is removed.
if (this != Context.KernelModule) {
if (name == "GetHashCode" && TryGetDefinedMethod("hash", out method) && method.IsRubyMember) {
return true;
} else if (name == "Equals" && TryGetDefinedMethod("eql?", out method) && method.IsRubyMember) {
return true;
} if (name == "ToString" && TryGetDefinedMethod("to_s", out method) && method.IsRubyMember) {
return true;
}
}
}
return !skipHidden && TryGetClrMember(name, virtualLookup, out method);
}