Skip to content

Commit

Permalink
fixes method selector
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyredondo committed Jun 23, 2020
1 parent 23a3564 commit e930dd2
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 37 deletions.
92 changes: 56 additions & 36 deletions src/Wanhjor.ObjectInspector/DuckType.Methods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in
return x.Version.CompareTo(y.Version);
});

MethodInfo[] allMethods = null!;
MethodAttributesSelector[] allMethods = null!;
foreach (var duckAttr in duckAttrs)
{
if (!(duckAttr.Version is null) && asmVersion > duckAttr.Version)
Expand All @@ -222,61 +222,68 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in

if (!(method is null))
return method;

if (allMethods is null)
{
var methods = instanceType.GetMethods(duckAttr.Flags);
allMethods = new MethodAttributesSelector[methods.Length];
for (var i = 0; i < allMethods.Length; i++)
allMethods[i] = new MethodAttributesSelector(methods[i],
new List<DuckAttribute>(methods[i].GetCustomAttributes<DuckAttribute>(true)));
}

allMethods ??= instanceType.GetMethods(duckAttr.Flags);

// Trying to select the one with the same name (used by reverse proxy)
var iMethodString = iMethod.ToString();
var remaining = allMethods.Where(m =>
var remaining = allMethods.Where(ma =>
{
foreach (var duckAttribute in m.GetCustomAttributes<DuckAttribute>(true))
if (ma.Attributes.Count == 0)
{
if (duckAttribute.Name == iMethodString)
if (ma.Method.Name != duckAttr.Name) return false;
// Trying to select the ones with the same parameters count
var mParams = ma.Method.GetParameters();
if (mParams.Length == parameters.Length)
return true;
}
return false;
}).ToList();

if (remaining.Count == 1)
return remaining[0];

// Trying to select the ones with the same parameters count
remaining = allMethods.Where(m =>
{
if (m.Name != duckAttr.Name) return false;
var mParams = m.GetParameters();
if (mParams.Length == parameters.Length)
return true;
var min = Math.Min(mParams.Length, parameters.Length);
var max = Math.Max(mParams.Length, parameters.Length);
for (var i = min; i < max; i++)
var min = Math.Min(mParams.Length, parameters.Length);
var max = Math.Max(mParams.Length, parameters.Length);
for (var i = min; i < max; i++)
{
if (mParams.Length > i && !mParams[i].HasDefaultValue) return false;
if (parameters.Length > i && !parameters[i].HasDefaultValue) return false;
}
return true;
}
// Trying to select the one with the same name (used by reverse proxy)
foreach (var attribute in ma.Attributes)
{
if (mParams.Length > i && !mParams[i].HasDefaultValue) return false;
if (parameters.Length > i && !parameters[i].HasDefaultValue) return false;
if (attribute.Name == iMethodString)
return true;
}
return true;
return false;
}).ToList();

if (remaining.Count == 0)
continue;
if (remaining.Count == 1)
return remaining[0];
return remaining[0].Method;

var remainWithAttribute = remaining.FirstOrDefault(r => r.Attributes.Count > 0);
if (!(remainWithAttribute.Method is null))
return remainWithAttribute.Method;

// Trying to select the ones with the same return type
var sameReturnType = remaining.Where(m => m.ReturnType == iMethod.ReturnType).ToList();
var sameReturnType = remaining.Where(ma => ma.Method.ReturnType == iMethod.ReturnType).ToList();
if (sameReturnType.Count == 1)
return sameReturnType[0];
return sameReturnType[0].Method;

if (sameReturnType.Count > 1)
remaining = sameReturnType;

if (iMethod.ReturnType.IsInterface && iMethod.ReturnType.GetInterface(iMethod.ReturnType.FullName) == null)
{
var duckReturnType = remaining.Where(m => !m.ReturnType.IsValueType).ToList();
var duckReturnType = remaining.Where(ma => !ma.Method.ReturnType.IsValueType).ToList();
if (duckReturnType.Count == 1)
return duckReturnType[0];
return duckReturnType[0].Method;

if (duckReturnType.Count > 1)
remaining = duckReturnType;
Expand All @@ -285,7 +292,7 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in
// Trying to select the one with the same parameters types
var sameParameters = remaining.Where(m =>
{
var mParams = m.GetParameters();
var mParams = m.Method.GetParameters();
var min = Math.Min(mParams.Length, parameters.Length);
for (var i = 0; i < min; i++)
{
Expand All @@ -302,12 +309,25 @@ private static void CreateMethods(Type baseType, Type instanceType, FieldInfo in
}).ToList();

if (sameParameters.Count == 1)
return sameParameters[0];
return sameParameters[0].Method;

return remaining[0];
return remaining[0].Method;
}

return null;
}

private readonly struct MethodAttributesSelector
{
public readonly MethodInfo Method;
public readonly List<DuckAttribute> Attributes;

public MethodAttributesSelector(MethodInfo methodInfo, List<DuckAttribute> attributes)
{
Method = methodInfo;
Attributes = attributes;
}
}

}
}
2 changes: 1 addition & 1 deletion src/Wanhjor.ObjectInspector/Wanhjor.ObjectInspector.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Description>An efficient .NET object inspector/accesor to avoid reflection usage with duck typing support.</Description>
<LangVersion>8</LangVersion>
<Nullable>enable</Nullable>
<Version>0.4.0-beta.7</Version>
<Version>0.4.0-beta.8</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Title>ObjectInspector</Title>
<Authors>Daniel Redondo</Authors>
Expand Down

0 comments on commit e930dd2

Please sign in to comment.