private static bool DoesMatchMethod(MethodReference mInternal, MethodReference m) { var mInternalDef = mInternal.Resolve(); if (mInternalDef.GetCustomAttribute<JsRedirectAttribute>() != null) { // Can never return a redirected method return false; } // Look for methods with custom signatures var detailsAttr = mInternalDef.GetCustomAttribute<JsDetailAttribute>(true); if (detailsAttr != null) { var signature = detailsAttr.Properties.FirstOrDefault(x => x.Name == "Signature"); if (signature.Name != null) { if (mInternal.Name != m.Name) { return false; } var sigTypes = ((CustomAttributeArgument[])signature.Argument.Value) .Select(x => ((TypeReference)x.Value).FullResolve(m)) .ToArray(); var mReturnType = m.ReturnType.FullResolve(m); if (!mReturnType.IsSame(sigTypes[0])) { return false; } for (int i = 0; i < m.Parameters.Count; i++) { var mParameterType = m.Parameters[i].ParameterType.FullResolve(m); if (!mParameterType.IsSame(sigTypes[i + 1])) { return false; } } return true; } } // Look for C# method that matches with custom 'this' Func<bool> isFakeThis = () => { if (mInternal.HasThis) { return false; } if (mInternal.Name != m.Name) { return false; } if (mInternal.Parameters.Count != m.Parameters.Count + 1) { return false; } if (mInternal.Parameters[0].GetCustomAttribute<JsFakeThisAttribute>() == null) { return false; } if (!mInternal.ReturnType.IsSame(m.ReturnType)) { return false; } for (int i = 1; i < mInternal.Parameters.Count; i++) { if (!mInternal.Parameters[i].ParameterType.IsSame(m.Parameters[i - 1].ParameterType)) { return false; } } return true; }; if (isFakeThis()) { return true; } // Look for C# method that match signature return mInternal.MatchMethodOnly(m); }