Message reporting if indexable value does not exist
This commit is contained in:
parent
2f8c295675
commit
fe4a8d25ad
|
@ -1,11 +1,12 @@
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes
|
namespace Upsilon.BaseTypes
|
||||||
{
|
{
|
||||||
internal interface IIndexable
|
internal interface IIndexable
|
||||||
{
|
{
|
||||||
LuaType Get(string s, EvaluationScope scope);
|
LuaType Get(Diagnostics diagnostics, TextSpan span, string s, EvaluationScope scope);
|
||||||
void Set(string s, LuaType value);
|
void Set(Diagnostics diagnostics, TextSpan span, string s, LuaType value);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal interface IScopeOwner
|
internal interface IScopeOwner
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Upsilon.BaseTypes.Number;
|
using Upsilon.BaseTypes.Number;
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes
|
namespace Upsilon.BaseTypes
|
||||||
{
|
{
|
||||||
|
@ -78,13 +79,13 @@ namespace Upsilon.BaseTypes
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaType Get(string s, EvaluationScope scope)
|
public LuaType Get(Diagnostics diagnostics, TextSpan span, string s, EvaluationScope scope)
|
||||||
{
|
{
|
||||||
var i = int.Parse(s);
|
var i = int.Parse(s);
|
||||||
return new LuaString(Value[i - 1].ToString());
|
return new LuaString(Value[i - 1].ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(string s, LuaType value)
|
public void Set(Diagnostics diagnostics, TextSpan span, string s, LuaType value)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Upsilon.Binder;
|
using Upsilon.Binder;
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes
|
namespace Upsilon.BaseTypes
|
||||||
{
|
{
|
||||||
|
@ -20,19 +21,19 @@ namespace Upsilon.BaseTypes
|
||||||
return EvaluationScope.Variables.ToDictionary(x => x.Key, x => x.Value.ToCSharpObject());
|
return EvaluationScope.Variables.ToDictionary(x => x.Key, x => x.Value.ToCSharpObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LuaType Get(Diagnostics diagnostics, TextSpan span, string s, EvaluationScope scope)
|
||||||
public LuaType Get(string s, EvaluationScope scope)
|
|
||||||
{
|
{
|
||||||
if (EvaluationScope.TryGet(s, out var o))
|
if (EvaluationScope.TryGet(s, out var o))
|
||||||
{
|
{
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
diagnostics.LogError("Cannot find member 's' on Table", span);
|
||||||
return new LuaNull();
|
return new LuaNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(string s, LuaType obj)
|
public void Set(Diagnostics diagnostics, TextSpan span, string s, LuaType value)
|
||||||
{
|
{
|
||||||
EvaluationScope.Set(new VariableSymbol(s, obj.Type, false), obj);
|
EvaluationScope.Set(new VariableSymbol(s, value.Type, false), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using Upsilon.Evaluator;
|
using Upsilon.Evaluator;
|
||||||
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.BaseTypes.UserData
|
namespace Upsilon.BaseTypes.UserData
|
||||||
{
|
{
|
||||||
|
@ -19,14 +20,23 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaType Get(string s, EvaluationScope scope)
|
public LuaType Get(Diagnostics diagnostics, TextSpan span, string s, EvaluationScope scope)
|
||||||
{
|
{
|
||||||
return _typeInfo.Get(Value, s);
|
var (type, failed) = _typeInfo.Get(Value, s);
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
diagnostics.LogError($"Cannot find member '{s}' on type '{Value.GetType()}'", span);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(string s, LuaType value)
|
public void Set(Diagnostics diagnostics, TextSpan span, string s, LuaType value)
|
||||||
{
|
{
|
||||||
_typeInfo.Set(Value, s, value);
|
var failed = _typeInfo.Set(Value, s, value);
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
diagnostics.LogError($"Cannot find member '{s}' on type '{Value.GetType()}'", span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,40 +19,43 @@ namespace Upsilon.BaseTypes.UserData
|
||||||
private Dictionary<string, PropertyInfo> Properties { get; }
|
private Dictionary<string, PropertyInfo> Properties { get; }
|
||||||
private Dictionary<string, MethodInfo> Methods { get; }
|
private Dictionary<string, MethodInfo> Methods { get; }
|
||||||
|
|
||||||
public LuaType Get(object value, string member)
|
public (LuaType Type, bool Failed) Get(object value, string member)
|
||||||
{
|
{
|
||||||
if (value.GetType() != Type)
|
if (value.GetType() != Type)
|
||||||
return null;
|
return (null, true);
|
||||||
member = member.ToLowerInvariant();
|
member = member.ToLowerInvariant();
|
||||||
if (Variables.TryGetValue(member, out var info))
|
if (Variables.TryGetValue(member, out var info))
|
||||||
{
|
{
|
||||||
return info.GetValue(value).ToLuaType();
|
return (info.GetValue(value).ToLuaType(), false);
|
||||||
}
|
}
|
||||||
if (Properties.TryGetValue(member, out var property))
|
if (Properties.TryGetValue(member, out var property))
|
||||||
{
|
{
|
||||||
return property.GetValue(value).ToLuaType();
|
return (property.GetValue(value).ToLuaType(), false);
|
||||||
}
|
}
|
||||||
if (Methods.TryGetValue(member, out var method))
|
if (Methods.TryGetValue(member, out var method))
|
||||||
{
|
{
|
||||||
return new LuaMethodInfoFunction(method, value);
|
return (new LuaMethodInfoFunction(method, value), false);
|
||||||
|
}
|
||||||
|
return (null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
public bool Set(object value, string member, LuaType newValue)
|
||||||
}
|
|
||||||
|
|
||||||
public void Set(object value, string member, LuaType newValue)
|
|
||||||
{
|
{
|
||||||
member = member.ToLowerInvariant();
|
member = member.ToLowerInvariant();
|
||||||
if (value.GetType() != Type)
|
if (value.GetType() != Type)
|
||||||
return;
|
return true;
|
||||||
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;
|
||||||
}
|
}
|
||||||
if (Properties.TryGetValue(member, out var property))
|
if (Properties.TryGetValue(member, out var property))
|
||||||
{
|
{
|
||||||
property.SetValue(value, newValue.ToCSharpObject());
|
property.SetValue(value, newValue.ToCSharpObject());
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
|
using Upsilon.Text;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
public abstract class BoundNode
|
public abstract class BoundNode
|
||||||
{
|
{
|
||||||
public abstract BoundKind Kind { get; }
|
public abstract BoundKind Kind { get; }
|
||||||
|
public TextSpan Span { get; protected set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -304,7 +304,6 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
private LuaType EvaluateTableExpression(BoundTableExpression e)
|
private LuaType EvaluateTableExpression(BoundTableExpression e)
|
||||||
{
|
{
|
||||||
var dic = new Dictionary<VariableSymbol, LuaType>();
|
|
||||||
var tableScope = EvaluationScope.CreateWithGetOnlyParent(Scope);
|
var tableScope = EvaluationScope.CreateWithGetOnlyParent(Scope);
|
||||||
var innerEvaluator = new Evaluator(_diagnostics, tableScope);
|
var innerEvaluator = new Evaluator(_diagnostics, tableScope);
|
||||||
var currentPos = 1;
|
var currentPos = 1;
|
||||||
|
@ -347,7 +346,7 @@ namespace Upsilon.Evaluator
|
||||||
scope = scopeOwner.EvaluationScope;
|
scope = scopeOwner.EvaluationScope;
|
||||||
}
|
}
|
||||||
var indexer = EvaluateExpression(e.Index);
|
var indexer = EvaluateExpression(e.Index);
|
||||||
return indexable.Get(indexer.ToString(), scope);
|
return indexable.Get(_diagnostics, e.Span, indexer.ToString(), scope);
|
||||||
}
|
}
|
||||||
private LuaType EvaluateFullStopIndexExpression(BoundFullStopIndexExpression e)
|
private LuaType EvaluateFullStopIndexExpression(BoundFullStopIndexExpression e)
|
||||||
{
|
{
|
||||||
|
@ -363,7 +362,7 @@ namespace Upsilon.Evaluator
|
||||||
scope = scopeOwner.EvaluationScope;
|
scope = scopeOwner.EvaluationScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
return indexable.Get(e.Index, scope);
|
return indexable.Get(_diagnostics, e.Span, e.Index, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EvaluateTableAssignmentStatement(BoundTableAssigmentStatement e)
|
private void EvaluateTableAssignmentStatement(BoundTableAssigmentStatement e)
|
||||||
|
@ -386,7 +385,7 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
throw new Exception("Cant assign to that");
|
throw new Exception("Cant assign to that");
|
||||||
}
|
}
|
||||||
indexable.Set(index.ToString(), value);
|
indexable.Set(_diagnostics, e.Span, index.ToString(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,8 +54,7 @@ return table[""test""]
|
||||||
var script = new Script(input);
|
var script = new Script(input);
|
||||||
Assert.Empty(script.Diagnostics.Messages);
|
Assert.Empty(script.Diagnostics.Messages);
|
||||||
var evaluated = script.Evaluate();
|
var evaluated = script.Evaluate();
|
||||||
Assert.Empty(script.Diagnostics.Messages);
|
Assert.Single(script.Diagnostics.Messages);
|
||||||
Assert.Null(evaluated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace UpsilonTests
|
||||||
{
|
{
|
||||||
public string FieldString = "TestField";
|
public string FieldString = "TestField";
|
||||||
public string FieldStringSet;
|
public string FieldStringSet;
|
||||||
|
private string _privateTestField = "hidden";
|
||||||
|
|
||||||
public bool TestMethodHasRun { get; private set; }
|
public bool TestMethodHasRun { get; private set; }
|
||||||
public void TestMethod()
|
public void TestMethod()
|
||||||
|
@ -104,5 +105,21 @@ end
|
||||||
Assert.Empty(script.Diagnostics.Messages);
|
Assert.Empty(script.Diagnostics.Messages);
|
||||||
Assert.Equal(result, 120);
|
Assert.Equal(result, 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CantAccessHiddenFields()
|
||||||
|
{
|
||||||
|
var obj = new UserDataHelper();
|
||||||
|
const string input = @"
|
||||||
|
function test(o)
|
||||||
|
return o._privateTestField
|
||||||
|
end
|
||||||
|
";
|
||||||
|
var script = new Script(input);
|
||||||
|
Assert.Empty(script.Diagnostics.Messages);
|
||||||
|
script.EvaluateFunction("test", new[] {obj});
|
||||||
|
Assert.Single(script.Diagnostics.Messages);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue