Skip to content

DLR-based overload resolution #1278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
drop legacy collections from MethodBinder implementation
  • Loading branch information
lostmsu committed Nov 12, 2020
commit 5806f58bcf8e848533ff27c3e97dbbff58f1e21f
2 changes: 1 addition & 1 deletion src/runtime/classobject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal ClassObject(Type tp) : base(tp)
/// </summary>
internal IntPtr GetDocString()
{
MethodBase[] methods = binder.GetMethods();
var methods = binder.GetMethods();
var str = "";
foreach (MethodBase t in methods)
{
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/constructorbinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public static IntPtr tp_repr(IntPtr ob)
Runtime.XIncref(self.repr);
return self.repr;
}
MethodBase[] methods = self.ctorBinder.GetMethods();
var methods = self.ctorBinder.GetMethods();
string name = self.type.FullName;
var doc = "";
foreach (MethodBase t in methods)
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/indexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ internal void SetItem(IntPtr inst, IntPtr args)
internal bool NeedsDefaultArgs(IntPtr args)
{
var pynargs = Runtime.PyTuple_Size(args);
MethodBase[] methods = SetterBinder.GetMethods();
if (methods.Length == 0)
var methods = SetterBinder.GetMethods();
if (methods.Count == 0)
{
return false;
}
Expand Down Expand Up @@ -99,7 +99,7 @@ internal IntPtr GetDefaultArgs(IntPtr args)
var pynargs = Runtime.PyTuple_Size(args);

// Get the default arg tuple
MethodBase[] methods = SetterBinder.GetMethods();
var methods = SetterBinder.GetMethods();
MethodBase mi = methods[0];
ParameterInfo[] pi = mi.GetParameters();
int clrnargs = pi.Length - 1;
Expand Down
66 changes: 20 additions & 46 deletions src/runtime/methodbinder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Reflection;
using System.Text;
using System.Collections.Generic;
Expand All @@ -16,29 +15,25 @@ namespace Python.Runtime
[Serializable]
internal class MethodBinder
{
public ArrayList list;
public MethodBase[] methods;
readonly List<MethodBase> methods = new List<MethodBase>();
public bool init = false;
public bool allow_threads = true;

internal MethodBinder()
{
list = new ArrayList();
}
internal MethodBinder(){}

internal MethodBinder(MethodInfo mi)
{
list = new ArrayList { mi };
this.methods.Add(mi);
}

public int Count
{
get { return list.Count; }
get { return this.methods.Count; }
}

internal void AddMethod(MethodBase m)
{
list.Add(m);
this.methods.Add(m);
}

/// <summary>
Expand Down Expand Up @@ -158,13 +153,12 @@ internal static MethodInfo MatchSignatureAndParameters(MethodInfo[] mi, Type[] g
/// is arranged in order of precedence (done lazily to avoid doing it
/// at all for methods that are never called).
/// </summary>
internal MethodBase[] GetMethods()
internal List<MethodBase> GetMethods()
{
if (!init)
{
// I'm sure this could be made more efficient.
list.Sort(new MethodSorter());
methods = (MethodBase[])list.ToArray(typeof(MethodBase));
this.methods.Sort(new MethodSorter());
init = true;
}
return methods;
Expand Down Expand Up @@ -281,9 +275,6 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info)

internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo)
{
// loop to find match, return invoker w/ or /wo error
MethodBase[] _methods = null;

var kwargDict = new Dictionary<string, IntPtr>();
if (kw != IntPtr.Zero)
{
Expand All @@ -301,15 +292,9 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth

var pynargs = (int)Runtime.PyTuple_Size(args);
var isGeneric = false;
if (info != null)
{
_methods = new MethodBase[1];
_methods.SetValue(info, 0);
}
else
{
_methods = GetMethods();
}

// loop to find match, return invoker w/ or /wo error
List<MethodBase> _methods = info != null ? new List<MethodBase> { info } : GetMethods();

// TODO: Clean up
foreach (MethodBase mi in _methods)
Expand All @@ -319,16 +304,15 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
isGeneric = true;
}
ParameterInfo[] pi = mi.GetParameters();
ArrayList defaultArgList;
bool paramsArray;

if (!MatchesArgumentCount(pynargs, pi, kwargDict, out paramsArray, out defaultArgList))
if (!MatchesArgumentCount(pynargs, pi, kwargDict, out paramsArray, out var defaultArgList))
{
continue;
}
var outs = 0;
var margs = TryConvertArguments(pi, paramsArray, args, pynargs, kwargDict, defaultArgList,
needsResolution: _methods.Length > 1,
needsResolution: _methods.Count > 1,
outs: out outs);

if (margs == null)
Expand Down Expand Up @@ -417,7 +401,7 @@ static IntPtr HandleParamsArray(IntPtr args, int arrayStart, int pyArgCount, out
static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray,
IntPtr args, int pyArgCount,
Dictionary<string, IntPtr> kwargDict,
ArrayList defaultArgList,
List<object> defaultArgList,
bool needsResolution,
out int outs)
{
Expand Down Expand Up @@ -575,7 +559,7 @@ static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool
static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] parameters,
Dictionary<string, IntPtr> kwargDict,
out bool paramsArray,
out ArrayList defaultArgList)
out List<object> defaultArgList)
{
defaultArgList = null;
var match = false;
Expand All @@ -590,7 +574,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa
// every parameter past 'positionalArgumentCount' must have either
// a corresponding keyword argument or a default parameter
match = true;
defaultArgList = new ArrayList();
defaultArgList = new List<object>();
for (var v = positionalArgumentCount; v < parameters.Length; v++)
{
if (kwargDict.ContainsKey(parameters[v].Name))
Expand Down Expand Up @@ -770,12 +754,10 @@ internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase i
/// <summary>
/// Utility class to sort method info by parameter type precedence.
/// </summary>
internal class MethodSorter : IComparer
internal class MethodSorter : IComparer<MethodBase>
{
int IComparer.Compare(object m1, object m2)
int IComparer<MethodBase>.Compare(MethodBase me1, MethodBase me2)
{
var me1 = (MethodBase)m1;
var me2 = (MethodBase)m2;
if (me1.DeclaringType != me2.DeclaringType)
{
// m2's type derives from m1's type, favor m2
Expand All @@ -787,17 +769,9 @@ int IComparer.Compare(object m1, object m2)
return -1;
}

int p1 = MethodBinder.GetPrecedence((MethodBase)m1);
int p2 = MethodBinder.GetPrecedence((MethodBase)m2);
if (p1 < p2)
{
return -1;
}
if (p1 > p2)
{
return 1;
}
return 0;
int p1 = MethodBinder.GetPrecedence(me1);
int p2 = MethodBinder.GetPrecedence(me2);
return p1.CompareTo(p2);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/methodobject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ internal IntPtr GetDocString()
}
var str = "";
Type marker = typeof(DocStringAttribute);
MethodBase[] methods = binder.GetMethods();
var methods = binder.GetMethods();
foreach (MethodBase method in methods)
{
if (str.Length > 0)
Expand Down