PageRenderTime 56ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/IronPython_2_0/Src/IronPython/Runtime/Types/BuiltinFunctionOverloadMapper.cs

#
C# | 145 lines | 94 code | 25 blank | 26 comment | 13 complexity | 9e24af93a7f82ea0bbff28a9a63c93b5 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Microsoft Public License, please send an email to
  8. * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System; using Microsoft;
  16. using System.Collections.Generic;
  17. using System.Reflection;
  18. using Microsoft.Scripting.Runtime;
  19. using IronPython.Runtime.Types;
  20. using IronPython.Runtime.Operations;
  21. namespace IronPython.Runtime.Types {
  22. // Used to map signatures to specific targets on the embedded reflected method.
  23. public class BuiltinFunctionOverloadMapper : ICodeFormattable {
  24. private BuiltinFunction _function;
  25. private object _instance;
  26. public BuiltinFunctionOverloadMapper(BuiltinFunction builtinFunction, object instance) {
  27. this._function = builtinFunction;
  28. this._instance = instance;
  29. }
  30. public object this[params Type[] types] {
  31. get {
  32. return GetOverload(types, Targets);
  33. }
  34. }
  35. protected object GetOverload(Type[] sig, IList<MethodBase> targets) {
  36. // We can still end up with more than one target since generic and non-generic
  37. // methods can share the same name and signature. So we'll build up a new
  38. // reflected method with all the candidate targets. A caller can then index this
  39. // reflected method if necessary in order to provide generic type arguments and
  40. // fully disambiguate the target.
  41. // Search for targets with the right number of arguments.
  42. MethodBase[] newTargets = FindMatchingTargets(sig, targets);
  43. if (targets == null)
  44. throw RuntimeHelpers.SimpleTypeError(String.Format("No match found for the method signature {0}", sig)); // TODO: Sig to usable display
  45. BuiltinFunction bf = new BuiltinFunction(_function.Name, newTargets, Function.DeclaringType, _function.FunctionType);
  46. if (_instance != null) {
  47. return bf.BindToInstance(_instance);
  48. } else {
  49. return GetTargetFunction(bf);
  50. }
  51. }
  52. private MethodBase[] FindMatchingTargets(Type[] sig, IList<MethodBase> targets) {
  53. int args = sig.Length;
  54. List<MethodBase> res = new List<MethodBase>();
  55. foreach (MethodBase mb in targets) {
  56. ParameterInfo[] pis = mb.GetParameters();
  57. if (pis.Length != args)
  58. continue;
  59. // Check each parameter type for an exact match.
  60. bool match = true;
  61. for (int i = 0; i < args; i++)
  62. if (pis[i].ParameterType != sig[i]) {
  63. match = false;
  64. break;
  65. }
  66. if (!match)
  67. continue;
  68. // Okay, we have a match, add it to the list.
  69. res.Add(mb);
  70. }
  71. return res.ToArray();
  72. }
  73. public BuiltinFunction Function {
  74. get {
  75. return _function;
  76. }
  77. }
  78. public virtual IList<MethodBase> Targets {
  79. get {
  80. return _function.Targets;
  81. }
  82. }
  83. protected virtual object GetTargetFunction(BuiltinFunction bf) {
  84. return bf;
  85. }
  86. internal virtual object GetKeywordArgumentOverload(Type[] key) {
  87. return GetOverload(key, Function.Targets);
  88. }
  89. public virtual string/*!*/ __repr__(CodeContext/*!*/ context) {
  90. PythonDictionary overloadList = new PythonDictionary();
  91. foreach (MethodBase mb in Targets) {
  92. string key = DocBuilder.CreateAutoDoc(mb);
  93. overloadList[key] = Function;
  94. }
  95. return overloadList.__repr__(context);
  96. }
  97. }
  98. public class ConstructorOverloadMapper : BuiltinFunctionOverloadMapper {
  99. public ConstructorOverloadMapper(ConstructorFunction builtinFunction, object instance)
  100. : base(builtinFunction, instance) {
  101. }
  102. public override IList<MethodBase> Targets {
  103. get {
  104. return ((ConstructorFunction)Function).ConstructorTargets;
  105. }
  106. }
  107. internal override object GetKeywordArgumentOverload(Type[] key) {
  108. return base.GetOverload(key, Function.Targets);
  109. }
  110. protected override object GetTargetFunction(BuiltinFunction bf) {
  111. // return a function that's bound to the overloads, we'll
  112. // the user then calls this w/ the dynamic type, and the bound
  113. // function drops the class & calls the overload.
  114. if (bf.Targets[0].DeclaringType != typeof(InstanceOps)) {
  115. return new ConstructorFunction(InstanceOps.OverloadedNew, bf.Targets).BindToInstance(bf);
  116. }
  117. return base.GetTargetFunction(bf);
  118. }
  119. }
  120. }