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) 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) 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); 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(); member = member.ToLowerInvariant();
if (value.GetType() != Type) if (value.GetType() != Type)
return true; return (true, "Invalid Type");
if (Variables.TryGetValue(member, out var info)) if (Variables.TryGetValue(member, out var info))
{ {
info.SetValue(value, newValue.ToCSharpObject()); info.SetValue(value, newValue.ToCSharpObject());
return false; return (false, null);
} }
if (Properties.TryGetValue(member, out var property)) 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()); 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) 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 FieldString = "TestField";
public string FieldStringSet; public string FieldStringSet;
private string _privateTestField = "hidden"; private string _privateTestField = "hidden";
public bool GetOnly { get; } = false;
public bool PrivateSet { get; private set; } = false;
public bool TestMethodHasRun { get; private set; } public bool TestMethodHasRun { get; private set; }
public void TestMethod() public void TestMethod()
@ -121,5 +123,37 @@ end
Assert.Single(script.Diagnostics.Messages); 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);
}
} }
} }