From 284ba2cf546219040467f3ecd95096949b353923 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 22 Jan 2019 12:28:21 +0100 Subject: [PATCH] Better error handling --- .../ScriptMethodInfoFunction.cs | 2 +- .../ScriptFunction/ScriptRuntimeFunction.cs | 3 ++- Upsilon/BaseTypes/UserData/ListUserData.cs | 2 +- Upsilon/Binder/Binder.cs | 16 ++++++++----- Upsilon/Evaluator/EvaluationException.cs | 12 ---------- Upsilon/Evaluator/Evaluator.cs | 4 ++-- Upsilon/Exceptions/EvaluationException.cs | 23 +++++++++++++++++++ Upsilon/Exceptions/ScriptRuntimeException.cs | 6 +++-- 8 files changed, 43 insertions(+), 25 deletions(-) delete mode 100644 Upsilon/Evaluator/EvaluationException.cs create mode 100644 Upsilon/Exceptions/EvaluationException.cs diff --git a/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs b/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs index 93f6613..248feb2 100644 --- a/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs +++ b/Upsilon/BaseTypes/ScriptFunction/ScriptMethodInfoFunction.cs @@ -107,7 +107,7 @@ namespace Upsilon.BaseTypes.ScriptFunction // if we haven't found a method, we throw an exception if (method == null) { - throw new ScriptRuntimeException( + throw new ScriptRuntimeException(script.FileName, $"Can't find method {Method.Name} with parameter types {string.Join(", ", convertedTypes.Select(x => x.Name))} on type {_object.GetType().Name}", span, diagnostics.ScriptString.GetSpan(span)); } diff --git a/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs b/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs index d409cef..161790b 100644 --- a/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs +++ b/Upsilon/BaseTypes/ScriptFunction/ScriptRuntimeFunction.cs @@ -6,6 +6,7 @@ using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.Binder; using Upsilon.Binder.VariableSymbols; using Upsilon.Evaluator; +using Upsilon.Exceptions; using Upsilon.Text; namespace Upsilon.BaseTypes.ScriptFunction @@ -25,7 +26,7 @@ namespace Upsilon.BaseTypes.ScriptFunction var option = GetValidOption(variables); if (option == null) { - throw new EvaluationException( + throw new EvaluationException(script.FileName, $"No valid function found"); } return option.Run(diagnostics, variables, script, scope, span); diff --git a/Upsilon/BaseTypes/UserData/ListUserData.cs b/Upsilon/BaseTypes/UserData/ListUserData.cs index cc7c5a3..11ed6de 100644 --- a/Upsilon/BaseTypes/UserData/ListUserData.cs +++ b/Upsilon/BaseTypes/UserData/ListUserData.cs @@ -64,7 +64,7 @@ namespace Upsilon.BaseTypes.UserData } else { - throw new ScriptRuntimeException( + throw new ScriptRuntimeException(null, $"Tried indexing a CSharp list with a value that's not an integer. Value: {scriptIndex.ToCSharpObject()}", span, diagnostics.ScriptString.GetSpan(span)); } diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index fed2e71..3e689c6 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -375,6 +375,8 @@ namespace Upsilon.Binder { return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, true, parent); } + diagnostics?.LogWarning($"Can't resolve type '{bDefProperty.ToString()}'", fullStopIndexExpression.Span); + return new VariableSymbol(fullStopIndexExpression.Index, Type.Unknown, true); } } else if (indexerVariable.TypeContainer == Type.Unknown) @@ -887,14 +889,16 @@ namespace Upsilon.Binder } else { - var functionParameter = (UserDataVariableSymbol) variableSymbol; - var udBoundDef = (UserDataBoundTypeDefinition)functionParameter.BoundTypeDefinition; - if (udBoundDef.Properties.TryGetValue(index.ToLowerInvariant(), out var property)) + if (variableSymbol is UserDataVariableSymbol functionParameter) { - return new BoundFullStopIndexExpression(expression, index, property.Type, e.Span); + var udBoundDef = (UserDataBoundTypeDefinition)functionParameter.BoundTypeDefinition; + if (udBoundDef.Properties.TryGetValue(index.ToLowerInvariant(), out var property)) + { + return new BoundFullStopIndexExpression(expression, index, property.Type, e.Span); + } + _diagnostics.LogError($"No variable '{index}' found on type '{udBoundDef.Name}'.", + e.Span); } - _diagnostics.LogError($"No variable '{index}' found on type '{udBoundDef.Name}'.", - e.Span); } return new BoundFullStopIndexExpression(expression, index, Type.Unknown, e.Span); case Type.Unknown: diff --git a/Upsilon/Evaluator/EvaluationException.cs b/Upsilon/Evaluator/EvaluationException.cs deleted file mode 100644 index d7623fa..0000000 --- a/Upsilon/Evaluator/EvaluationException.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Upsilon.Evaluator -{ - public class EvaluationException : Exception - { - public EvaluationException(string message) : base(message) - { - - } - } -} \ No newline at end of file diff --git a/Upsilon/Evaluator/Evaluator.cs b/Upsilon/Evaluator/Evaluator.cs index d8de77b..3df1e8e 100644 --- a/Upsilon/Evaluator/Evaluator.cs +++ b/Upsilon/Evaluator/Evaluator.cs @@ -88,7 +88,7 @@ namespace Upsilon.Evaluator var function = (ScriptRuntimeFunction) statement; var option = function.GetValidOption(parameters); if (option == null) - throw new EvaluationException( + throw new EvaluationException(_script.FileName, $"No function found with name '{functionName}' and available parameters {string.Join(", ", parameters.Select(x => $"{x.GetType().Name}"))}"); var result = option.Run(_diagnostics, parameters?.Select(x => x.ToScriptType()).ToArray(), _script, Scope, new TextSpan()); @@ -399,7 +399,7 @@ namespace Upsilon.Evaluator private void ThrowException(string message, TextSpan location) { - throw new ScriptRuntimeException(message, location, _diagnostics.ScriptString.GetSpan(location)); + throw new ScriptRuntimeException(_script.FileName, message, location, _diagnostics.ScriptString.GetSpan(location)); } private void EvaluateAssignmentStatement(BoundVariableAssignment e) diff --git a/Upsilon/Exceptions/EvaluationException.cs b/Upsilon/Exceptions/EvaluationException.cs new file mode 100644 index 0000000..8de2ab1 --- /dev/null +++ b/Upsilon/Exceptions/EvaluationException.cs @@ -0,0 +1,23 @@ +using System; + +namespace Upsilon.Exceptions +{ + public class EvaluationException : Exception + { + public string FileName { get; } + public string ErrorMessage { get; } + + public EvaluationException(string fileName, string message) + { + FileName = fileName; + ErrorMessage = message; + } + + public override string ToString() + { + return $"[{FileName}] {ErrorMessage}"; + } + + public override string Message => ToString(); + } +} \ No newline at end of file diff --git a/Upsilon/Exceptions/ScriptRuntimeException.cs b/Upsilon/Exceptions/ScriptRuntimeException.cs index 3767cfb..9f326ba 100644 --- a/Upsilon/Exceptions/ScriptRuntimeException.cs +++ b/Upsilon/Exceptions/ScriptRuntimeException.cs @@ -5,13 +5,15 @@ namespace Upsilon.Exceptions { public class ScriptRuntimeException : Exception { + public string FileName { get; } public string ErrorMessage { get; } public int Line { get; } public int Character { get; } public string ErrorLine { get; } - public ScriptRuntimeException(string errorMessage, TextSpan position, string errorLine) + public ScriptRuntimeException(string fileName, string errorMessage, TextSpan position, string errorLine) { + FileName = fileName; ErrorMessage = errorMessage; Line = position.StartLine; Character = position.StartPosition; @@ -20,7 +22,7 @@ namespace Upsilon.Exceptions public override string ToString() { - return $"{ErrorMessage} at ({Line}, {Character})\n{ErrorLine}"; + return $"[{FileName}] {ErrorMessage} at ({Line}, {Character})\n{ErrorLine}"; } public override string Message => ToString();