Fixes to the Type Binder and static method handling

This commit is contained in:
Deukhoofd 2018-12-09 22:12:03 +01:00
parent 3d9b7a53e9
commit 5646ff1da1
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
3 changed files with 130 additions and 104 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Linq;
using System.Reflection; using System.Reflection;
using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.Number;
using Upsilon.BaseTypes.ScriptFunction; using Upsilon.BaseTypes.ScriptFunction;
@ -71,6 +72,11 @@ namespace Upsilon.BaseTypes
} }
} }
if (o is IEnumerable enumerable)
{
return new ListUserData(enumerable.Cast<object>().ToList());
}
return new GenericUserData(o); return new GenericUserData(o);
} }

View File

@ -24,6 +24,16 @@ namespace Upsilon.BaseTypes.UserData
state = null; state = null;
foreach (var match in matches) foreach (var match in matches)
{
if (IsValidMatch(match, ref args))
return match;
}
state = null;
return null;
}
public bool IsValidMatch(MethodBase match, ref object[] args)
{ {
var validMatch = true; var validMatch = true;
var parameters = match.GetParameters(); var parameters = match.GetParameters();
@ -33,10 +43,10 @@ namespace Upsilon.BaseTypes.UserData
if (args.Length <= i) if (args.Length <= i)
{ {
if (matchParameter.IsOptional) if (matchParameter.IsOptional)
return match; return true;
validMatch = false; return false;
break;
} }
var argument = args[i]; var argument = args[i];
var argumentType = argument.GetType(); var argumentType = argument.GetType();
@ -48,6 +58,7 @@ namespace Upsilon.BaseTypes.UserData
{ {
continue; continue;
} }
break; break;
case TypeCode.Char: case TypeCode.Char:
case TypeCode.String: case TypeCode.String:
@ -55,6 +66,7 @@ namespace Upsilon.BaseTypes.UserData
{ {
continue; continue;
} }
break; break;
case TypeCode.Byte: case TypeCode.Byte:
case TypeCode.Decimal: case TypeCode.Decimal:
@ -71,6 +83,7 @@ namespace Upsilon.BaseTypes.UserData
{ {
continue; continue;
} }
break; break;
case TypeCode.Object: case TypeCode.Object:
continue; continue;
@ -91,17 +104,10 @@ namespace Upsilon.BaseTypes.UserData
if (!matchParameter.ParameterType.IsAssignableFrom(argumentType)) if (!matchParameter.ParameterType.IsAssignableFrom(argumentType))
{ {
validMatch = false; return false;
break;
} }
} }
return validMatch;
if (validMatch)
return match;
}
state = null;
return null;
} }
public override object ChangeType(object value, System.Type type, CultureInfo culture) public override object ChangeType(object value, System.Type type, CultureInfo culture)
@ -185,7 +191,40 @@ namespace Upsilon.BaseTypes.UserData
if (value is ListUserData d) if (value is ListUserData d)
return d.List; return d.List;
if (value is ScriptTable.ScriptTable table) if (value is ScriptTable.ScriptTable table)
return table.EvaluationScope.Variables.Select(x => x.Value.ToCSharpObject()); {
var generics = type.GetGenericArguments();
if (generics.Length > 0)
{
var l1 = typeof(List<>);
var requiredListType = l1.MakeGenericType(generics[0]);
var list = (IList)Activator.CreateInstance(requiredListType);
foreach (var variable in table.EvaluationScope.Variables)
{
list.Add(variable.Value.ToCSharpObject());
}
return list;
}
return table.EvaluationScope.Variables.Select(x => x.Value.ToCSharpObject()).ToArray();
}
}
if (typeof(IEnumerable).IsAssignableFrom(type))
{
if (value is ListUserData d)
return d.List;
if (value is ScriptTable.ScriptTable table)
{
var generics = type.GetGenericArguments();
var l1 = typeof(List<>);
var requiredListType = l1.MakeGenericType(generics[0]);
var list = (IList)Activator.CreateInstance(requiredListType);
foreach (var variable in table.EvaluationScope.Variables)
{
list.Add(variable.Value.ToCSharpObject());
}
return list;
}
} }
var isScriptTypeRequired = typeof(ScriptType).IsAssignableFrom(type); var isScriptTypeRequired = typeof(ScriptType).IsAssignableFrom(type);

View File

@ -1,5 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Globalization;
using System.Reflection; using System.Reflection;
using Upsilon.Evaluator; using Upsilon.Evaluator;
using Upsilon.StandardLibraries; using Upsilon.StandardLibraries;
@ -73,43 +73,24 @@ namespace Upsilon.BaseTypes.UserData
return MethodParts; return MethodParts;
} }
public MethodInfo GetMethod(ref object[] parameters) public MethodInfo GetMethod(ref object[] arguments)
{ {
foreach (var userDataMethodPart in MethodParts) foreach (var userDataMethodPart in MethodParts)
{ {
if (userDataMethodPart.Parameters.Length < parameters.Length) var methodBase = userDataMethodPart.Method;
continue; if (UpsilonBinder.Default.IsValidMatch(methodBase, ref arguments))
bool valid = true;
for (var index = 0; index < userDataMethodPart.Parameters.Length; index++)
{ {
var userDataMethodParameter = userDataMethodPart.Parameters[index]; var parameters = methodBase.GetParameters();
if (index >= parameters.Length) for (var i = 0; i < parameters.Length; i++)
{ {
if (userDataMethodParameter.IsOptional) var argument = arguments[i];
return userDataMethodPart.Method; var requiredType = parameters[i].ParameterType;
valid = false; arguments[i] =
break; UpsilonBinder.Default.ChangeType(argument, requiredType, CultureInfo.InvariantCulture);
}
var parameter = parameters[index];
var parameterType = parameter.GetType();
if (parameterType.IsGenericType) parameter = parameterType.GetGenericTypeDefinition();
if (userDataMethodParameter.Type != parameterType &&
!userDataMethodParameter.Type.IsAssignableFrom(parameterType))
{
if (parameter is ScriptType t)
{
if (userDataMethodParameter.Type.IsAssignableFrom(t.GetCSharpType()))
{
parameters[index] = ((ScriptType) parameter).ToCSharpObject();
continue;
}
}
valid = false;
break;
}
} }
if (valid) return userDataMethodPart.Method; return methodBase;
}
} }
return null; return null;