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;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using Upsilon.BoundTypes;
using Type = Upsilon.BaseTypes.Type; using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder.VariableSymbols namespace Upsilon.Binder.VariableSymbols
@ -16,8 +17,17 @@ namespace Upsilon.Binder.VariableSymbols
Name = name; 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 string Name { get; }
public Type ValidTypes { get; } public Type ValidTypes { get; }
public string[] ExpectedUserData { get; }
public bool IsOptional { get; } public bool IsOptional { get; }
} }
@ -56,6 +66,23 @@ namespace Upsilon.Binder.VariableSymbols
$"Expected one of the following: {functionParameter.ValidTypes.ToString()}, got: '{callingParameter.Type}'", $"Expected one of the following: {functionParameter.ValidTypes.ToString()}, got: '{callingParameter.Type}'",
callingParameter); 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); return (true, null, null);

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using Upsilon.BaseTypes; using Upsilon.BaseTypes;
using Upsilon.Binder; using Upsilon.Binder;
using Upsilon.Binder.VariableSymbols;
using Upsilon.StandardLibraries; using Upsilon.StandardLibraries;
using Type = Upsilon.BaseTypes.Type; using Type = Upsilon.BaseTypes.Type;
@ -135,7 +136,8 @@ namespace Upsilon.BoundTypes
Properties.Add(valueName, new UserDataBoundProperty() Properties.Add(valueName, new UserDataBoundProperty()
{ {
Name = valueName, 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}'", $"Expected one of the following: {functionParameter.Type.ToString()}, got: '{callingParameter.Type}'",
callingParameter); 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); return (true, null, null);