Better error handling for setting userdata values

This commit is contained in:
Deukhoofd 2018-11-21 14:04:43 +01:00
parent 605b98284d
commit 8dd2be8c67
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
3 changed files with 45 additions and 7 deletions

View File

@ -37,10 +37,10 @@ namespace Upsilon.BaseTypes.UserData
public void Set(Diagnostics diagnostics, TextSpan span, string s, LuaType value)
{
var failed = _typeInfo.Set(Value, s, value);
var (failed, error) = _typeInfo.Set(Value, s, value);
if (failed)
{
diagnostics.LogError($"Cannot find member '{s}' on type '{Value.GetType()}'", span);
diagnostics.LogError(error, span);
}
}

View File

@ -53,23 +53,27 @@ namespace Upsilon.BaseTypes.UserData
return (null, true);
}
public bool Set(object value, string member, LuaType newValue)
public (bool failed, string error) Set(object value, string member, LuaType newValue)
{
member = member.ToLowerInvariant();
if (value.GetType() != Type)
return true;
return (true, "Invalid Type");
if (Variables.TryGetValue(member, out var info))
{
info.SetValue(value, newValue.ToCSharpObject());
return false;
return (false, null);
}
if (Properties.TryGetValue(member, out var property))
{
if (property.SetMethod == null || property.SetMethod.IsPrivate)
{
return (true, $"Property '{member}' on type '{Type}' does not have a publicly available setter.");
}
property.SetValue(value, newValue.ToCSharpObject());
return false;
return (false, null);
}
return true;
return (true, $"Cannot find member '{member}' on type '{Type}'");
}
public (LuaType Type, bool Failed) BinaryOperator(object value, LuaType par1, OperatorType op, LuaType par2)

View File

@ -26,6 +26,8 @@ namespace UpsilonTests
public string FieldString = "TestField";
public string FieldStringSet;
private string _privateTestField = "hidden";
public bool GetOnly { get; } = false;
public bool PrivateSet { get; private set; } = false;
public bool TestMethodHasRun { get; private set; }
public void TestMethod()
@ -121,5 +123,37 @@ end
Assert.Single(script.Diagnostics.Messages);
}
[Fact]
public void CantSetToFieldsWithNoSetter()
{
var obj = new UserDataHelper();
const string input = @"
function test(o)
o.GetOnly = true
end
";
var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages);
script.EvaluateFunction("test", new[] {obj});
Assert.Single(script.Diagnostics.Messages);
Assert.False(obj.GetOnly);
}
[Fact]
public void CantSetToFieldsWithPrivateSetter()
{
var obj = new UserDataHelper();
const string input = @"
function test(o)
o.PrivateSet = true
end
";
var script = new Script(input);
Assert.Empty(script.Diagnostics.Messages);
script.EvaluateFunction("test", new[] {obj});
Assert.Single(script.Diagnostics.Messages);
Assert.False(obj.PrivateSet);
}
}
}