Handling for type checking parameters of internal functions
This commit is contained in:
parent
f08d1c2541
commit
00178cfa82
|
@ -24,9 +24,9 @@ namespace Upsilon.BaseTypes.ScriptFunction
|
|||
private readonly bool _passScriptReference;
|
||||
public System.Type ReturnType { get; }
|
||||
|
||||
public IEnumerable<System.Type> GetParameterTypes()
|
||||
public IEnumerable<UserDataMethod.UserDataMethodParameter> GetParameterInfo()
|
||||
{
|
||||
return _method.GetMethods().First().Parameters.Select(x => x.Type);
|
||||
return _method.GetMethods().First().Parameters;
|
||||
}
|
||||
|
||||
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script)
|
||||
|
|
|
@ -5,8 +5,8 @@ namespace Upsilon.BaseTypes
|
|||
[Flags]
|
||||
public enum Type : byte
|
||||
{
|
||||
Unknown = 0,
|
||||
Nil = 1,
|
||||
Nil = 0,
|
||||
Unknown = 1,
|
||||
Boolean = 2,
|
||||
Number = 4,
|
||||
String = 8,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Type = Upsilon.BaseTypes.Type;
|
||||
|
||||
namespace Upsilon.Binder.VariableSymbols
|
||||
|
@ -8,46 +9,52 @@ namespace Upsilon.Binder.VariableSymbols
|
|||
{
|
||||
public class InternalFunctionParameter
|
||||
{
|
||||
public InternalFunctionParameter(Type t)
|
||||
public InternalFunctionParameter(Type type, bool isOptional)
|
||||
{
|
||||
ValidTypes = t;
|
||||
ValidTypes = type;
|
||||
IsOptional = isOptional;
|
||||
}
|
||||
|
||||
public Type ValidTypes { get; set; }
|
||||
public Type ValidTypes { get; }
|
||||
public bool IsOptional { get; }
|
||||
}
|
||||
|
||||
public InternalFunctionParameter[] FunctionParameters { get; }
|
||||
private InternalFunctionParameter[] FunctionParameters { get; }
|
||||
private int MinimalParametersRequired { get; }
|
||||
|
||||
public InternalFunctionVariableSymbol(string name, bool local, Type resultType, InternalFunctionParameter[] functionParameters)
|
||||
: base(name, local, resultType)
|
||||
{
|
||||
FunctionParameters = functionParameters;
|
||||
MinimalParametersRequired = functionParameters.Count(x => !x.IsOptional);
|
||||
}
|
||||
|
||||
public override (bool IsValid, string Error,
|
||||
BoundExpression WrongParameter) ValidateParameters(ImmutableArray<BoundExpression> callingParameters)
|
||||
{
|
||||
if (FunctionParameters.Length != callingParameters.Length)
|
||||
if (FunctionParameters.Length < MinimalParametersRequired
|
||||
|| callingParameters.Length > FunctionParameters.Length)
|
||||
{
|
||||
return (false,
|
||||
$"Invalid number of parameters for function '{Name}'. Expected {FunctionParameters.Length}, got {callingParameters.Length}",
|
||||
null);
|
||||
}
|
||||
|
||||
for (var i = 0; i < FunctionParameters.Length; i++)
|
||||
for (var i = 0; i < callingParameters.Length; i++)
|
||||
{
|
||||
var functionParameter = FunctionParameters[i];
|
||||
var callingParameter = callingParameters[i];
|
||||
if (callingParameter.Type != Type.Unknown && callingParameter.Type != Type.Nil)
|
||||
{
|
||||
if ((functionParameter.ValidTypes ^ callingParameter.Type) != 0)
|
||||
if (callingParameter.Type == Type.Unknown || callingParameter.Type == Type.Nil)
|
||||
continue;
|
||||
|
||||
if (!functionParameter.ValidTypes.HasFlag(callingParameter.Type))
|
||||
{
|
||||
return (false,
|
||||
$"Unexpected variable passed to internal function '{functionParameter}'.",
|
||||
$"Unexpected variable passed to internal function '{functionParameter}'." +
|
||||
$"Expected one of the following: {functionParameter.ValidTypes.ToString()}, got: '{callingParameter.Type}'",
|
||||
callingParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (true, null, null);
|
||||
}
|
||||
|
|
|
@ -54,8 +54,12 @@ namespace Upsilon.StandardLibraries
|
|||
funcs.Add(func.Key, func.Value.MethodInfoFunction);
|
||||
var functionSymbol = new InternalFunctionVariableSymbol(func.Key, true,
|
||||
func.Value.MethodInfoFunction.ReturnType.GetScriptType(),
|
||||
func.Value.MethodInfoFunction.GetParameterTypes().Select(x =>
|
||||
new InternalFunctionVariableSymbol.InternalFunctionParameter(DeriveValidTypes(x))).ToArray())
|
||||
func.Value.MethodInfoFunction.GetParameterInfo().Select(typeInfo =>
|
||||
{
|
||||
var derivedType = DeriveValidTypes(typeInfo.Type);
|
||||
return new InternalFunctionVariableSymbol.InternalFunctionParameter(derivedType,
|
||||
typeInfo.IsOptional);
|
||||
}).ToArray())
|
||||
{
|
||||
CommentValue = func.Value.CommentValue?.Split('\n')
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue