MethodDescriptor.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using System.Runtime.CompilerServices;
  5. namespace Jint.Runtime.Interop
  6. {
  7. internal class MethodDescriptor
  8. {
  9. private MethodDescriptor(MethodBase method)
  10. {
  11. Method = method;
  12. Parameters = method.GetParameters();
  13. IsExtensionMethod = method.IsDefined(typeof(ExtensionAttribute), true);
  14. foreach (var parameter in Parameters)
  15. {
  16. if (Attribute.IsDefined(parameter, typeof(ParamArrayAttribute)))
  17. {
  18. HasParams = true;
  19. break;
  20. }
  21. if (parameter.HasDefaultValue)
  22. {
  23. ParameterDefaultValuesCount++;
  24. }
  25. }
  26. }
  27. public MethodBase Method { get; }
  28. public ParameterInfo[] Parameters { get; }
  29. public bool HasParams { get; }
  30. public int ParameterDefaultValuesCount { get; }
  31. public bool IsExtensionMethod { get; }
  32. public static MethodDescriptor[] Build<T>(List<T> source) where T : MethodBase
  33. {
  34. var descriptors = new MethodDescriptor[source.Count];
  35. for (var i = 0; i < source.Count; i++)
  36. {
  37. descriptors[i] = new MethodDescriptor(source[i]);
  38. }
  39. return Prioritize(descriptors);
  40. }
  41. public static MethodDescriptor[] Build<T>(T[] source) where T : MethodBase
  42. {
  43. var descriptors = new MethodDescriptor[source.Length];
  44. for (var i = 0; i < source.Length; i++)
  45. {
  46. descriptors[i] = new MethodDescriptor(source[i]);
  47. }
  48. return Prioritize(descriptors);
  49. }
  50. private static MethodDescriptor[] Prioritize(MethodDescriptor[] descriptors)
  51. {
  52. static int CreateComparison(MethodDescriptor d1, MethodDescriptor d2)
  53. {
  54. // put params versions to end, they can be tricky to match and can cause trouble / extra overhead
  55. if (d1.HasParams)
  56. {
  57. return 1;
  58. }
  59. if (d2.HasParams)
  60. {
  61. return -1;
  62. }
  63. // then favor less parameters
  64. if (d1.Parameters.Length > d2.Parameters.Length)
  65. {
  66. return 1;
  67. }
  68. if (d2.Parameters.Length > d1.Parameters.Length)
  69. {
  70. return -1;
  71. }
  72. return 0;
  73. }
  74. Array.Sort(descriptors, CreateComparison);
  75. return descriptors;
  76. }
  77. }
  78. }