Better handling of C# function parameter type checking

This commit is contained in:
Deukhoofd 2019-01-16 12:07:40 +01:00
parent 2ef06b3fd7
commit b5bfb7997b
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
2 changed files with 48 additions and 1 deletions

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using Upsilon.BoundTypes;
using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder.VariableSymbols
@ -16,8 +17,17 @@ namespace Upsilon.Binder.VariableSymbols
Name = name;
}
public InternalFunctionParameter(string name, Type type, string[] expectedUserData, bool isOptional)
{
ValidTypes = type;
ExpectedUserData = expectedUserData;
IsOptional = isOptional;
Name = name;
}
public string Name { get; }
public Type ValidTypes { get; }
public string[] ExpectedUserData { get; }
public bool IsOptional { get; }
}
@ -56,6 +66,23 @@ namespace Upsilon.Binder.VariableSymbols
$"Expected one of the following: {functionParameter.ValidTypes.ToString()}, got: '{callingParameter.Type}'",
callingParameter);
}
if (functionParameter.ValidTypes.HasFlag(Type.UserData))
{
var variable = Binder.ResolveVariable(callingParameter, null);
if (variable != null && variable.Type == Type.UserData)
{
var parent =
(UserDataBoundTypeDefinition) ((UserDataVariableSymbol) variable).BoundTypeDefinition;
if (functionParameter.ExpectedUserData != null && !functionParameter.ExpectedUserData.Contains(parent.Name))
{
return (false,
$"Unexpected variable passed to internal function at variable {i + 1}. " +
$"Expected to be the following: {string.Join(", ", functionParameter.ExpectedUserData)}, got: '{parent.Name}'",
callingParameter);
}
}
}
}
return (true, null, null);

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Reflection;
using Upsilon.BaseTypes;
using Upsilon.Binder;
using Upsilon.Binder.VariableSymbols;
using Upsilon.StandardLibraries;
using Type = Upsilon.BaseTypes.Type;
@ -135,7 +136,8 @@ namespace Upsilon.BoundTypes
Properties.Add(valueName, new UserDataBoundProperty()
{
Name = valueName,
Type = Type.UserData
Type = Type.UserData,
ActualType = name
});
}
}
@ -185,6 +187,24 @@ namespace Upsilon.BoundTypes
$"Expected one of the following: {functionParameter.Type.ToString()}, got: '{callingParameter.Type}'",
callingParameter);
}
if (functionParameter.Type.HasFlag(Type.UserData))
{
var variable = Binder.Binder.ResolveVariable(callingParameter, null);
if (variable != null && variable.Type == Type.UserData)
{
var parent =
(UserDataBoundTypeDefinition) ((UserDataVariableSymbol) variable).BoundTypeDefinition;
if (functionParameter.ActualType != null &&
!string.Equals(functionParameter.ActualType, parent.Name, StringComparison.InvariantCultureIgnoreCase))
{
return (false,
$"Unexpected variable passed to internal function at variable {i + 1}. " +
$"Expected to be the following: {functionParameter.ActualType}, got: '{parent.Name}'",
callingParameter);
}
}
}
}
return (true, null, null);