diff --git a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs index 2f857bd..50fef92 100644 --- a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs +++ b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using Microsoft.CSharp.RuntimeBinder; +using Newtonsoft.Json; using NUnit.Framework; using Shouldly; using System; @@ -1837,6 +1838,15 @@ public void Evaluate_DoubleDoubleQuotesInEscapedStringThrowException() evaluator.Evaluate("@\"Hello \"\" Joe\"").ShouldBe(@"Hello "" Joe"); } + + [Test] + [Category("Bug")] + public void Evaluate_NullAdditionShouldThrowExceptionNotReturnString() + { + var evaluator = new ExpressionEvaluator(); + + Should.Throw(() => evaluator.Evaluate("(null + null) + null")); + } //[Test] //[Category("Bug")] diff --git a/CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj b/CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj index 56b2a61..66b6cd9 100644 --- a/CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj +++ b/CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj @@ -5,9 +5,9 @@ CodingSeb.ExpressionEvaluator A Simple Math and Pseudo C# Expression Evaluator in One C# File. Can also execute small C# like scripts Copyright © Coding Seb 2017 - 1.4.40.0 - 1.4.40.0 - 1.4.40.0 + 1.4.41.0 + 1.4.41.0 + 1.4.41.0 bin\$(Configuration)\ Coding Seb CodingSeb.ExpressionEvaluator @@ -20,9 +20,7 @@ https://github.com/codingseb/ExpressionEvaluator/blob/master/Icon.png?raw=true Icon.png false - * Make shared cache for types resolution thread safe -* Add ScriptEvaluating and ScriptEvaluated events -* Add unaryOperatorsDictionary to manage custom operators that are both unaries and binaries better + * fix: addition of null and bubble container LICENSE.md https://github.com/codingseb/ExpressionEvaluator true diff --git a/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs b/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs index dfa1fd9..a17720c 100644 --- a/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs +++ b/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs @@ -1,6 +1,6 @@ /****************************************************************************************************** Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator) - Version : 1.4.40.0 + Version : 1.4.41.0 (if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable) Author : Coding Seb @@ -242,56 +242,56 @@ protected enum TryBlockEvaluatedState { new Dictionary>() { - {ExpressionOperator.UnaryPlus, (dynamic _, dynamic right) => +right }, - {ExpressionOperator.UnaryMinus, (dynamic _, dynamic right) => -right }, - {ExpressionOperator.LogicalNegation, (dynamic _, dynamic right) => !right }, - {ExpressionOperator.BitwiseComplement, (dynamic _, dynamic right) => ~right }, - {ExpressionOperator.Cast, (dynamic left, dynamic right) => ChangeType(right, left) }, + {ExpressionOperator.UnaryPlus, (_, right) => +right }, + {ExpressionOperator.UnaryMinus, (_, right) => -right }, + {ExpressionOperator.LogicalNegation, (_, right) => !right }, + {ExpressionOperator.BitwiseComplement, (_, right) => ~right }, + {ExpressionOperator.Cast, (left, right) => ChangeType(right, left) }, }, new Dictionary>() { - {ExpressionOperator.Multiply, (dynamic left, dynamic right) => left * right }, - {ExpressionOperator.Divide, (dynamic left, dynamic right) => left / right }, - {ExpressionOperator.Modulo, (dynamic left, dynamic right) => left % right }, + {ExpressionOperator.Multiply, (left, right) => left * right }, + {ExpressionOperator.Divide, (left, right) => left / right }, + {ExpressionOperator.Modulo, (left, right) => left % right }, }, new Dictionary>() { - {ExpressionOperator.Plus, (dynamic left, dynamic right) => left + right }, - {ExpressionOperator.Minus, (dynamic left, dynamic right) => left - right }, + {ExpressionOperator.Plus, (left, right) => left + right }, + {ExpressionOperator.Minus, (left, right) => left - right }, }, new Dictionary>() { - {ExpressionOperator.ShiftBitsLeft, (dynamic left, dynamic right) => left << right }, - {ExpressionOperator.ShiftBitsRight, (dynamic left, dynamic right) => left >> right }, + {ExpressionOperator.ShiftBitsLeft, (left, right) => left << right }, + {ExpressionOperator.ShiftBitsRight, (left, right) => left >> right }, }, new Dictionary>() { - {ExpressionOperator.Lower, (dynamic left, dynamic right) => left < right }, - {ExpressionOperator.Greater, (dynamic left, dynamic right) => left > right }, - {ExpressionOperator.LowerOrEqual, (dynamic left, dynamic right) => left <= right }, - {ExpressionOperator.GreaterOrEqual, (dynamic left, dynamic right) => left >= right }, - {ExpressionOperator.Is, (dynamic left, dynamic right) => left != null && (((ClassOrEnumType)right).Type).IsAssignableFrom(left.GetType()) }, + {ExpressionOperator.Lower, (left, right) => left < right }, + {ExpressionOperator.Greater, (left, right) => left > right }, + {ExpressionOperator.LowerOrEqual, (left, right) => left <= right }, + {ExpressionOperator.GreaterOrEqual, (left, right) => left >= right }, + {ExpressionOperator.Is, (left, right) => left != null && (((ClassOrEnumType)right).Type).IsAssignableFrom(left.GetType()) }, }, new Dictionary>() { - {ExpressionOperator.Equal, (dynamic left, dynamic right) => left == right }, - {ExpressionOperator.NotEqual, (dynamic left, dynamic right) => left != right }, + {ExpressionOperator.Equal, (left, right) => left == right }, + {ExpressionOperator.NotEqual, (left, right) => left != right }, }, new Dictionary>() { - {ExpressionOperator.LogicalAnd, (dynamic left, dynamic right) => left & right }, + {ExpressionOperator.LogicalAnd, (left, right) => left & right }, }, new Dictionary>() { - {ExpressionOperator.LogicalXor, (dynamic left, dynamic right) => left ^ right }, + {ExpressionOperator.LogicalXor, (left, right) => left ^ right }, }, new Dictionary>() { - {ExpressionOperator.LogicalOr, (dynamic left, dynamic right) => left | right }, + {ExpressionOperator.LogicalOr, (left, right) => left | right }, }, new Dictionary>() { - {ExpressionOperator.ConditionalAnd, (dynamic left, dynamic right) => { + {ExpressionOperator.ConditionalAnd, (left, right) => { if ( left is BubbleExceptionContainer leftExceptionContainer) { leftExceptionContainer.Throw(); @@ -314,7 +314,7 @@ protected enum TryBlockEvaluatedState }, new Dictionary>() { - {ExpressionOperator.ConditionalOr, (dynamic left, dynamic right) => { + {ExpressionOperator.ConditionalOr, (left, right) => { if ( left is BubbleExceptionContainer leftExceptionContainer) { leftExceptionContainer.Throw(); @@ -337,7 +337,7 @@ protected enum TryBlockEvaluatedState }, new Dictionary>() { - {ExpressionOperator.NullCoalescing, (dynamic left, dynamic right) => left ?? right }, + {ExpressionOperator.NullCoalescing, (left, right) => left ?? right }, }, }; @@ -3206,7 +3206,7 @@ protected virtual object ProcessStack(Stack stack) .Select(e => e is NullConditionalNullValue ? null : e) .ToList(); - OperatorsEvaluations.ToList().ForEach((IDictionary> operatorEvalutationsDict) => + OperatorsEvaluations.ToList().ForEach(operatorEvalutationsDict => { for (int i = list.Count - 1; i >= 0; i--) { @@ -3296,11 +3296,11 @@ void EvaluateFirstPreviousUnaryOp(int j) { list[i] = operatorEvalutationsDict[eOp](left, right); - if (left is BubbleExceptionContainer && right is string) + if (left is BubbleExceptionContainer && (right == null || right is string)) { list[i] = left; //Bubble up the causing error } - else if (right is BubbleExceptionContainer && left is string) + else if (right is BubbleExceptionContainer && (left is string || left is null)) { list[i] = right; //Bubble up the causing error } @@ -3481,7 +3481,7 @@ protected virtual bool GetLambdaExpression(string expression, Stack stac bool inScriptAtDeclaration = inScript; - stack.Push(new InternalDelegate((object[] args) => + stack.Push(new InternalDelegate(args => { var vars = new Dictionary(variables);