PageRenderTime 43ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/DICK.B1/IronPython/Runtime/Binding/PythonOverloadResolver.cs

https://bitbucket.org/williamybs/uidipythontool
C# | 170 lines | 128 code | 24 blank | 18 comment | 31 complexity | 3fb3eca52c568c2fc9f56f06832051f0 MD5 | raw file
  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. #if !CLR2
  16. using System.Linq.Expressions;
  17. #else
  18. using Microsoft.Scripting.Ast;
  19. #endif
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Dynamic;
  23. using System.Reflection;
  24. using Microsoft.Scripting.Actions;
  25. using Microsoft.Scripting.Actions.Calls;
  26. using Microsoft.Scripting.Utils;
  27. using Microsoft.Scripting.Generation;
  28. using IronPython.Runtime.Operations;
  29. using Microsoft.Scripting.Runtime;
  30. using System.Collections;
  31. namespace IronPython.Runtime.Binding {
  32. internal sealed class PythonOverloadResolverFactory : OverloadResolverFactory {
  33. private readonly PythonBinder/*!*/ _binder;
  34. internal readonly Expression/*!*/ _codeContext;
  35. public PythonOverloadResolverFactory(PythonBinder/*!*/ binder, Expression/*!*/ codeContext) {
  36. Assert.NotNull(binder, codeContext);
  37. _binder = binder;
  38. _codeContext = codeContext;
  39. }
  40. public override DefaultOverloadResolver CreateOverloadResolver(IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType) {
  41. return new PythonOverloadResolver(_binder, args, signature, callType, _codeContext);
  42. }
  43. }
  44. public sealed class PythonOverloadResolver : DefaultOverloadResolver {
  45. private readonly Expression _context;
  46. public Expression ContextExpression {
  47. get { return _context; }
  48. }
  49. // instance method call:
  50. public PythonOverloadResolver(PythonBinder binder, DynamicMetaObject instance, IList<DynamicMetaObject> args, CallSignature signature,
  51. Expression codeContext)
  52. : base(binder, instance, args, signature) {
  53. Assert.NotNull(codeContext);
  54. _context = codeContext;
  55. }
  56. // method call:
  57. public PythonOverloadResolver(PythonBinder binder, IList<DynamicMetaObject> args, CallSignature signature, Expression codeContext)
  58. : this(binder, args, signature, CallTypes.None, codeContext) {
  59. }
  60. // method call:
  61. public PythonOverloadResolver(PythonBinder binder, IList<DynamicMetaObject> args, CallSignature signature, CallTypes callType, Expression codeContext)
  62. : base(binder, args, signature, callType) {
  63. Assert.NotNull(codeContext);
  64. _context = codeContext;
  65. }
  66. private new PythonBinder Binder {
  67. get {
  68. return (PythonBinder)base.Binder;
  69. }
  70. }
  71. public override bool CanConvertFrom(Type fromType, DynamicMetaObject fromArg, ParameterWrapper toParameter, NarrowingLevel level) {
  72. if ((fromType == typeof(List) || fromType.IsSubclassOf(typeof(List)))) {
  73. if (toParameter.Type.IsGenericType &&
  74. toParameter.Type.GetGenericTypeDefinition() == typeof(IList<>) &&
  75. (toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false) ||
  76. toParameter.ParameterInfo.IsDefined(typeof(BytesConversionNoStringAttribute), false))) {
  77. return false;
  78. }
  79. } else if (fromType == typeof(string)) {
  80. if (toParameter.Type == typeof(IList<byte>) &&
  81. !Binder.Context.PythonOptions.Python30 &&
  82. toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false)) {
  83. // string -> byte array, we allow this in Python 2.6
  84. return true;
  85. }
  86. } else if (fromType == typeof(Bytes)) {
  87. if (toParameter.Type == typeof(string) &&
  88. !Binder.Context.PythonOptions.Python30 &&
  89. toParameter.ParameterInfo.IsDefined(typeof(BytesConversionAttribute), false)) {
  90. return true;
  91. }
  92. }
  93. return base.CanConvertFrom(fromType, fromArg, toParameter, level);
  94. }
  95. protected override BitArray MapSpecialParameters(ParameterMapping/*!*/ mapping) {
  96. var infos = mapping.Overload.Parameters;
  97. BitArray special = base.MapSpecialParameters(mapping);
  98. if (infos.Count > 0) {
  99. bool normalSeen = false;
  100. for (int i = 0; i < infos.Count; i++) {
  101. bool isSpecial = false;
  102. if (infos[i].ParameterType.IsSubclassOf(typeof(SiteLocalStorage))) {
  103. mapping.AddBuilder(new SiteLocalStorageBuilder(infos[i]));
  104. isSpecial = true;
  105. } else if (infos[i].ParameterType == typeof(CodeContext) && !normalSeen) {
  106. mapping.AddBuilder(new ContextArgBuilder(infos[i]));
  107. isSpecial = true;
  108. } else {
  109. normalSeen = true;
  110. }
  111. if (isSpecial) {
  112. (special = special ?? new BitArray(infos.Count))[i] = true;
  113. }
  114. }
  115. }
  116. return special;
  117. }
  118. protected override Expression GetByRefArrayExpression(Expression argumentArrayExpression) {
  119. return Expression.Call(typeof(PythonOps).GetMethod("MakeTuple"), argumentArrayExpression);
  120. }
  121. protected override bool AllowMemberInitialization(OverloadInfo method) {
  122. return method.IsInstanceFactory && !method.DeclaringType.IsDefined(typeof(PythonTypeAttribute), true);
  123. }
  124. public override Expression Convert(DynamicMetaObject metaObject, Type restrictedType, ParameterInfo info, Type toType) {
  125. return Binder.ConvertExpression(metaObject.Expression, toType, ConversionResultKind.ExplicitCast, new PythonOverloadResolverFactory(Binder, _context));
  126. }
  127. public override Expression GetDynamicConversion(Expression value, Type type) {
  128. return Expression.Dynamic(
  129. Binder.Context.Convert(type, ConversionResultKind.ExplicitCast),
  130. type,
  131. value);
  132. }
  133. public override Type GetGenericInferenceType(DynamicMetaObject dynamicObject) {
  134. Type res = PythonTypeOps.GetFinalSystemType(dynamicObject.LimitType);
  135. if (res == typeof(ExtensibleString) ||
  136. res == typeof(ExtensibleComplex) ||
  137. (res.IsGenericType && res.GetGenericTypeDefinition() == typeof(Extensible<>))) {
  138. return typeof(object);
  139. }
  140. return res;
  141. }
  142. public override Func<object[], object> GetConvertor(int index, DynamicMetaObject metaObject, ParameterInfo info, Type toType) {
  143. return Binder.ConvertObject(index, metaObject, toType, ConversionResultKind.ExplicitCast);
  144. }
  145. }
  146. }