Allow non-standard libraries to have a script pass variable as well
This commit is contained in:
parent
80afeacda6
commit
59909b0d53
|
@ -63,7 +63,8 @@ namespace Upsilon.BoundTypes
|
||||||
Properties = new Dictionary<string, UserDataBoundProperty>(),
|
Properties = new Dictionary<string, UserDataBoundProperty>(),
|
||||||
Name = name
|
Name = name
|
||||||
};
|
};
|
||||||
var fields = backingType.GetFields(BindingFlags.Public | BindingFlags.Instance).Select(x => new UserDataBoundProperty()
|
const BindingFlags generalBindAttributes = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;
|
||||||
|
var fields = backingType.GetFields(generalBindAttributes).Select(x => new UserDataBoundProperty()
|
||||||
{
|
{
|
||||||
Name = x.Name,
|
Name = x.Name,
|
||||||
ActualType = x.FieldType.Name,
|
ActualType = x.FieldType.Name,
|
||||||
|
@ -79,11 +80,11 @@ namespace Upsilon.BoundTypes
|
||||||
{
|
{
|
||||||
realProperties = new[]{backingType}
|
realProperties = new[]{backingType}
|
||||||
.Concat(backingType.GetInterfaces())
|
.Concat(backingType.GetInterfaces())
|
||||||
.SelectMany(x => x.GetProperties(BindingFlags.Public | BindingFlags.Instance)).ToArray();
|
.SelectMany(x => x.GetProperties(generalBindAttributes)).ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
realProperties = backingType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
realProperties = backingType.GetProperties(generalBindAttributes);
|
||||||
}
|
}
|
||||||
var properties = realProperties.Select(x => new UserDataBoundProperty()
|
var properties = realProperties.Select(x => new UserDataBoundProperty()
|
||||||
{
|
{
|
||||||
|
@ -96,16 +97,18 @@ namespace Upsilon.BoundTypes
|
||||||
obj.Properties.Add(f.Name.ToLowerInvariant(), f);
|
obj.Properties.Add(f.Name.ToLowerInvariant(), f);
|
||||||
}
|
}
|
||||||
var methods = new Dictionary<string, UserDataBoundMethod>();
|
var methods = new Dictionary<string, UserDataBoundMethod>();
|
||||||
var backingMethods = backingType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
|
var backingMethods = backingType.GetMethods(generalBindAttributes);
|
||||||
foreach (var backingMethod in backingMethods)
|
foreach (var backingMethod in backingMethods)
|
||||||
{
|
{
|
||||||
if (backingMethod.IsSpecialName)
|
if (backingMethod.IsSpecialName)
|
||||||
continue;
|
continue;
|
||||||
var methodName = backingMethod.Name;
|
var methodName = backingMethod.Name;
|
||||||
|
var passScriptReference = false;
|
||||||
var attribute = backingMethod.GetCustomAttribute(typeof(ScriptFunctionAttribute));
|
var attribute = backingMethod.GetCustomAttribute(typeof(ScriptFunctionAttribute));
|
||||||
if (attribute is ScriptFunctionAttribute sfa )
|
if (attribute is ScriptFunctionAttribute sfa )
|
||||||
{
|
{
|
||||||
methodName = sfa.Name;
|
methodName = sfa.Name;
|
||||||
|
passScriptReference = sfa.PassScriptReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
var parameters = backingMethod.GetParameters().Select(parameter => new UserDataBoundFunctionParameter()
|
var parameters = backingMethod.GetParameters().Select(parameter => new UserDataBoundFunctionParameter()
|
||||||
|
@ -115,7 +118,7 @@ namespace Upsilon.BoundTypes
|
||||||
Type = StaticScope.DeriveValidTypes(parameter.ParameterType),
|
Type = StaticScope.DeriveValidTypes(parameter.ParameterType),
|
||||||
IsOptional = parameter.IsOptional
|
IsOptional = parameter.IsOptional
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
var option = new UserDataBoundMethodOption(backingMethod.ReturnType.GetScriptType(), parameters);
|
var option = new UserDataBoundMethodOption(backingMethod.ReturnType.GetScriptType(), parameters, passScriptReference);
|
||||||
if (methods.TryGetValue(methodName, out var func))
|
if (methods.TryGetValue(methodName, out var func))
|
||||||
{
|
{
|
||||||
func.Options.Add(option);
|
func.Options.Add(option);
|
||||||
|
@ -219,29 +222,43 @@ namespace Upsilon.BoundTypes
|
||||||
|
|
||||||
public class UserDataBoundMethodOption
|
public class UserDataBoundMethodOption
|
||||||
{
|
{
|
||||||
public UserDataBoundMethodOption(TypeContainer resultType, UserDataBoundFunctionParameter[] parameters)
|
public UserDataBoundMethodOption(TypeContainer resultType, UserDataBoundFunctionParameter[] parameters,
|
||||||
|
bool passScriptReference)
|
||||||
{
|
{
|
||||||
ResultType = resultType;
|
ResultType = resultType;
|
||||||
Parameters = parameters;
|
Parameters = parameters;
|
||||||
|
PassScriptReference = passScriptReference;
|
||||||
NonOptionalParameterCount = Parameters.Count(x => !x.IsOptional);
|
NonOptionalParameterCount = Parameters.Count(x => !x.IsOptional);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeContainer ResultType { get; }
|
public TypeContainer ResultType { get; }
|
||||||
public UserDataBoundFunctionParameter[] Parameters { get; }
|
public UserDataBoundFunctionParameter[] Parameters { get; }
|
||||||
|
public bool PassScriptReference { get; }
|
||||||
private int NonOptionalParameterCount { get; }
|
private int NonOptionalParameterCount { get; }
|
||||||
|
|
||||||
public bool ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
|
public bool ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
|
||||||
{
|
{
|
||||||
if (callingParameters.Length < NonOptionalParameterCount
|
var effectiveLength = callingParameters.Length;
|
||||||
|| callingParameters.Length > Parameters.Length)
|
if (PassScriptReference)
|
||||||
|
effectiveLength++;
|
||||||
|
|
||||||
|
if (effectiveLength < NonOptionalParameterCount
|
||||||
|
|| effectiveLength > Parameters.Length)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var callingIndexOffset = 0;
|
||||||
for (var i = 0; i < callingParameters.Length; i++)
|
for (var i = 0; i < callingParameters.Length; i++)
|
||||||
{
|
{
|
||||||
var functionParameter = Parameters[i];
|
var functionParameter = Parameters[i];
|
||||||
var callingParameter = callingParameters[i];
|
if (i == 0 && PassScriptReference)
|
||||||
|
{
|
||||||
|
callingIndexOffset++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var callingParameter = callingParameters[i + callingIndexOffset];
|
||||||
if (callingParameter.ValueType == Type.Unknown || callingParameter.ValueType == Type.Nil ||
|
if (callingParameter.ValueType == Type.Unknown || callingParameter.ValueType == Type.Nil ||
|
||||||
functionParameter.Type == Type.Unknown)
|
functionParameter.Type == Type.Unknown)
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue