public override IMethodBase GetMethod(IType iType, AnnotatedItem item)
        {
            var t       = iType.Value();
            var list    = t.GetMethods().Where(m => item.MemberName == "#ctor" ? m is Ctor : m is Method);
            var methods = list.Where(m =>
                                     (item.MemberName == "#ctor" && m is Ctor || m is Method && ((Method)m).JavaName == item.MemberName) &&
                                     m.Parameters.Count == item.Arguments.Length)
                          .ToArray();

            // First, try loose match.

            MethodBase candidate  = null;
            bool       overloaded = false;

            foreach (var m in methods)
            {
                if (overloaded)
                {
                    break;
                }
                if (candidate != null)
                {
                    overloaded = true;
                    break;
                }
                else
                {
                    candidate = m;
                }
            }
            if (!overloaded)
            {
                if (candidate == null)
                {
                    Errors.Add("warning: method with matching argument count not found: " + t.FullName + " member: " + item.FormatMember());
                }
                return(candidate.Wrap());
            }

            // Second, try strict match.

            var argTypeLists = methods.Select(m => new { Method = m, Jni = m is Ctor ? ((Ctor)m).JniSignature : ((Method)m).JniSignature })
                               .Select(p => new { Method = p.Method, Arguments = p.Jni == null ? null : ParseJniMethodArgumentsSignature(p.Jni) })
                               .ToArray();

            // this .Replace() is needed so that T[] can match generic arguments
            Func <string, string>       stripParamSuffix = s => s.Replace("...", "").Replace("[]", "");
            Func <string, string>       stripGenParams   = s => s == null ? s : (s.Contains('<') ? s.Substring(0, s.IndexOf('<')) : s).Replace("...", "[]");
            Func <string, string, bool> cmp = (v, w) => stripGenParams(v) == stripGenParams(w);

            for (int i = 0; i < argTypeLists.Length; i++)
            {
                var argTypeListPair = argTypeLists [i];
                var argTypeList     = argTypeListPair.Arguments;
                if (argTypeList == null || item.Arguments.Length != argTypeList.Length)
                {
                    continue;
                }

                bool mismatch = false;
                for (int a = 0; a < argTypeList.Length; a++)
                {
                    if (cmp(argTypeList [a], item.Arguments [a]) ||
                        t.TypeParameters != null && t.TypeParameters.Any(ga => cmp(ga.Name, stripParamSuffix(item.Arguments [a]))) ||
                        argTypeListPair.Method.GenericArguments != null && argTypeListPair.Method.GenericArguments.Any(ga => cmp(ga.Name, stripParamSuffix(item.Arguments [a]))))
                    {
                        continue;
                    }
                    mismatch = true;
                    break;
                }
                if (mismatch)
                {
                    continue;
                }
                return(methods [i].Wrap());
            }
            Errors.Add("warning: method overload not found: " + t.FullName + " member: " + item.FormatMember());
            return(null);
        }
예제 #2
0
        public override IMethodBase GetMethod(IType iType, AnnotatedItem item)
        {
            var t = iType.Value();
            Func <ICustomAttributeProvider, string> getRegisterAttName = type => {
                var ca = getRegisterAtt(type);
                return(ca == null ? null : ca.ConstructorArguments [0].Value as string);
            };
            Func <ICustomAttributeProvider, string> getRegisterAttJni = type => {
                var ca = getRegisterAtt(type);
                return(ca == null ? null : ca.ConstructorArguments [1].Value as string);
            };

            var methods = t.GetMethods()
                          .Where(m => (item.MemberName == "#ctor" && m.IsConstructor || getRegisterAttName(m) == item.MemberName) && m.Parameters.Count == item.Arguments.Length)
                          .ToArray();

            // First, try loose match just by checking argument count.

            MethodDefinition candidate  = null;
            bool             overloaded = false;

            foreach (var m in methods)
            {
                if (overloaded)
                {
                    break;
                }
                if (candidate != null)
                {
                    overloaded = true;
                    break;
                }
                else
                {
                    candidate = m;
                }
            }
            if (!overloaded)
            {
                if (candidate == null)
                {
                    Errors.Add("warning: method with matching argument count not found: " + t + " member: " + item.FormatMember());
                }
                return(candidate.Wrap());
            }

            // Second, try strict match.

            Func <ICustomAttributeProvider, string []> getJavaGenTypesValue = td => {
                var a   = getJavaTypesAtt(td);
                var arr = a == null ? new string [0] : ((CustomAttributeArgument [])a.ConstructorArguments [0].Value).Select(ca => ca.Value as string);
                return(arr.Select(s => s.Contains(' ') ? s.Substring(0, s.IndexOf(' ')) : s).ToArray());
            };
            var typeGenArgs = t.GetSelfAndAncestors().SelectMany(getJavaGenTypesValue).ToArray();

            var argTypeLists = methods.Select(m => new { Method = m, Jni = getRegisterAttJni(m) })
                               .Select(p => new { Method = p.Method, Arguments = p.Jni == null ? null : ParseJniMethodArgumentsSignature(p.Jni) })
                               .ToArray();

            for (int i = 0; i < argTypeLists.Length; i++)
            {
                var argTypeListPair = argTypeLists [i];
                var argTypeList     = argTypeListPair.Arguments;
                var methodGenArgs   = getJavaGenTypesValue(argTypeListPair.Method);
                if (!AreArgumentsEqualLax(argTypeList, item.Arguments, typeGenArgs.Concat(methodGenArgs)))
                {
                    continue;
                }
                return(methods [i].Wrap());
            }
            Errors.Add("warning: method overload not found: " + t + " member: " + item.FormatMember());
            return(null);
        }