private bool TryGetClrMember(Type/*!*/ type, string/*!*/ name, bool mapNames, bool unmangleNames, BindingFlags basicBindingFlags, out RubyMemberInfo method) {
Context.RequiresClassHierarchyLock();
basicBindingFlags |= BindingFlags.Public | BindingFlags.NonPublic;
// We look only for members directly declared on the type and handle method overloads inheritance manually.
BindingFlags bindingFlags = basicBindingFlags | ((_isSingletonClass) ? BindingFlags.Static : BindingFlags.Instance);
// instance methods on Object are also available in static context:
if (type == typeof(Object)) {
bindingFlags |= BindingFlags.Instance;
}
string operatorName;
if (mapNames && !_isSingletonClass && (operatorName = RubyUtils.ToClrOperatorName(name)) != null) {
// instance invocation of an operator:
if (TryGetClrMethod(type, basicBindingFlags | BindingFlags.Static, true, name, null, operatorName, null, out method)) {
return true;
}
} else if (mapNames && (name == "[]" || name == "[]=")) {
if (type.IsArray && !_isSingletonClass) {
bool isSetter = name.Length == 3;
TryGetClrMethod(type, bindingFlags, false, name, null, isSetter ? "Set" : "Get", null, out method);
Debug.Assert(method != null);
return true;
} else {
object[] attrs = type.GetCustomAttributes(typeof(DefaultMemberAttribute), false);
if (attrs.Length == 1) {
// default indexer accessor:
bool isSetter = name.Length == 3;
if (TryGetClrProperty(type, bindingFlags, isSetter, name, ((DefaultMemberAttribute)attrs[0]).MemberName, null, out method)) {
return true;
}
}
}
} else if (name.LastCharacter() == '=') {
string propertyName = name.Substring(0, name.Length - 1);
string altName = unmangleNames ? RubyUtils.TryUnmangleMethodName(propertyName) : null;
// property setter:
if (TryGetClrProperty(type, bindingFlags, true, name, propertyName, altName, out method)) return true;
// writeable field:
if (TryGetClrField(type, bindingFlags, true, propertyName, altName, out method)) return true;
} else {
string altName = unmangleNames ? RubyUtils.TryUnmangleMethodName(name) : null;
// method:
if (TryGetClrMethod(type, bindingFlags, false, name, null, name, altName, out method)) return true;
// getter:
if (TryGetClrProperty(type, bindingFlags, false, name, name, altName, out method)) return true;
// event:
if (TryGetClrEvent(type, bindingFlags, name, altName, out method)) return true;
// field:
if (TryGetClrField(type, bindingFlags, false, name, altName, out method)) return true;
}
method = null;
return false;
}