diff --git a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorScriptEvaluateTests.cs b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorScriptEvaluateTests.cs index e45897b..081d6f3 100644 --- a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorScriptEvaluateTests.cs +++ b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorScriptEvaluateTests.cs @@ -620,7 +620,6 @@ public static IEnumerable TestCasesForScriptEvaluateTests //.SetCategory("=") //.Returns(); - #endregion #region Array content assignation diff --git a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs index ee7bd8e..411894a 100644 --- a/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs +++ b/CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs @@ -990,7 +990,31 @@ public void TypeTesting(string expression, Type type) #region Bugs correction [TestCase("new DateTime(1985,9,11).ToString(\"dd.MM.yyyy\")", ExpectedResult = "11.09.1985", Category = "Complex expression,Static method,Instance method,Lambda function,Cast")] - + + [TestCase("(int)3.6", ExpectedResult = (int)3.6, Category = "Complex expression,Cast,double to int,#130")] + [TestCase("(int)-3.6", ExpectedResult = (int)-3.6, Category = "Complex expression,Cast,double to int,#130")] + [TestCase("(uint)3.6", ExpectedResult = (uint)3.6, Category = "Complex expression,Cast,double to uint,#130")] + [TestCase("(long)3.6", ExpectedResult = (long)3.6, Category = "Complex expression,Cast,double to long,#130")] + [TestCase("(short)3.6", ExpectedResult = (short)3.6, Category = "Complex expression,Cast,double to short,#130")] + + [TestCase("(int)3.6d", ExpectedResult = (int)3.6d, Category = "Complex expression,Cast,double to int,#130")] + [TestCase("(int)-3.6d", ExpectedResult = (int)-3.6d, Category = "Complex expression,Cast,double to int,#130")] + [TestCase("(uint)3.6d", ExpectedResult = (uint)3.6d, Category = "Complex expression,Cast,double to uint,#130")] + [TestCase("(long)3.6d", ExpectedResult = (long)3.6d, Category = "Complex expression,Cast,double to long,#130")] + [TestCase("(short)3.6d", ExpectedResult = (short)3.6d, Category = "Complex expression,Cast,double to short,#130")] + + [TestCase("(int)3.6f", ExpectedResult = (int)3.6f, Category = "Complex expression,Cast,float to int,#130")] + [TestCase("(int)-3.6f", ExpectedResult = (int)-3.6f, Category = "Complex expression,Cast,float to int,#130")] + [TestCase("(uint)3.6f", ExpectedResult = (uint)3.6f, Category = "Complex expression,Cast,float to uint,#130")] + [TestCase("(long)3.6f", ExpectedResult = (long)3.6f, Category = "Complex expression,Cast,float to long,#130")] + [TestCase("(short)3.6f", ExpectedResult = (short)3.6f, Category = "Complex expression,Cast,float to short,#130")] + + [TestCase("(int)3.6m", ExpectedResult = (int)3.6m, Category = "Complex expression,Cast,decimal to int,#130")] + [TestCase("(int)-3.6m", ExpectedResult = (int)-3.6m, Category = "Complex expression,Cast,decimal to int,#130")] + [TestCase("(uint)3.6m", ExpectedResult = (uint)3.6m, Category = "Complex expression,Cast,decimal to uint,#130")] + [TestCase("(long)3.6m", ExpectedResult = (long)3.6m, Category = "Complex expression,Cast,decimal to long,#130")] + [TestCase("(short)3.6m", ExpectedResult = (short)3.6m, Category = "Complex expression,Cast,decimal to short,#130")] + #endregion #endregion @@ -1592,7 +1616,7 @@ public void ExceptionThrowingEvaluation(ExpressionEvaluator evaluator, string ex #region Bug corrections /// - /// To correct #127 Evaluating "new DateTime(2022,1,20)" does not work + /// To correct #127 Evaluating "new DateTime(2022,1,20)" does not work /// unless OptionInlineNamespacesEvaluationActive is turned on /// [Test] @@ -1615,7 +1639,7 @@ public void Evaluate_NewDateTime_When_OptionInlineNamespacesEvaluationActive_is_ } /// - /// To correct #127 Evaluating "new DateTime(2022,1,20)" does not work + /// To correct #127 Evaluating "new DateTime(2022,1,20)" does not work /// unless OptionInlineNamespacesEvaluationActive is turned on /// [Test] @@ -1637,7 +1661,6 @@ public void Evaluate_NewDateTime_When_OptionInlineNamespacesEvaluationActive_is_ dateTime.Value.Day.ShouldBe(20); } - /// /// To correct #81 Exception is assigned to variable /// With simple variable diff --git a/CodingSeb.ExpressionEvaluator.Tests/TestsUtils/ClassStructContainer.cs b/CodingSeb.ExpressionEvaluator.Tests/TestsUtils/ClassStructContainer.cs index c74859b..bc29c0c 100644 --- a/CodingSeb.ExpressionEvaluator.Tests/TestsUtils/ClassStructContainer.cs +++ b/CodingSeb.ExpressionEvaluator.Tests/TestsUtils/ClassStructContainer.cs @@ -8,4 +8,3 @@ public class ClassStructContainer public StructForTest1 NestedStructProperty { get; set; } } } - diff --git a/CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj b/CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj index b89b403..8ad34bc 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.36.0 - 1.4.36.0 - 1.4.36.0 + 1.4.37.0 + 1.4.37.0 + 1.4.37.0 bin\$(Configuration)\ Coding Seb CodingSeb.ExpressionEvaluator @@ -19,10 +19,7 @@ https://github.com/codingseb/ExpressionEvaluator/blob/master/Icon.png?raw=true Icon.png false - - * Correction of creation of instance with new keyword when OptionInlineNamespacesEvaluationActive is set to false - * Add the option OptionVariablesPersistenceCustomComparer to reuse variables outside of the evaluator (In this case OptionCaseSensitiveEvaluationActive is not used anymore for variables) - + * Correction of the explicit cast between primitive types and rounding numbers before (int)3.6 -> 4 now (int)3.6 -> 3 LICENSE.md https://github.com/codingseb/ExpressionEvaluator true diff --git a/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs b/CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs index 0b2ca0b..1d7e062 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.36.0 + Version : 1.4.37.0 (if last digit (the forth) is not a zero, the version is an intermediate version and can be unstable) Author : Coding Seb @@ -14,6 +14,7 @@ using System.Dynamic; using System.Globalization; using System.Linq; +using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -916,7 +917,7 @@ public IDictionary Variables } else { - variables = value == null ? new Dictionary(StringComparerForCasing) : new Dictionary(value, StringComparerForCasing); + variables = value == null ? new Dictionary(StringComparerForCasing) : new Dictionary(value, StringComparerForCasing); } } } @@ -4147,9 +4148,55 @@ protected static object ChangeType(object value, Type conversionType) { return Enum.ToObject(conversionType, value); } + + if (value.GetType().IsPrimitive && conversionType.IsPrimitive) + { + return primitiveExplicitCastMethodInfo + .MakeGenericMethod(conversionType) + .Invoke(null, new object[] {value}); + } + + if (DynamicCast(value, conversionType, out object ret)) + { + return ret; + } + return Convert.ChangeType(value, conversionType); } + protected static MethodInfo primitiveExplicitCastMethodInfo = typeof(ExpressionEvaluator).GetMethod(nameof(PrimitiveExplicitCast), BindingFlags.Static | BindingFlags.NonPublic); + + protected static object PrimitiveExplicitCast(dynamic value) + { + return (T)value; + } + + protected static bool DynamicCast(object source, Type destType, out object result) + { + Type srcType = source.GetType(); + if (srcType == destType) { result = source; return true; } + result = null; + + BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy; + MethodInfo castOperator = destType.GetMethods(bindingFlags) + .Union(srcType.GetMethods(bindingFlags)) + .Where(methodInfo => methodInfo.Name == "op_Explicit" || methodInfo.Name == "op_Implicit") + .Where(methodInfo => + { + var pars = methodInfo.GetParameters(); + return pars.Length == 1 && pars[0].ParameterType == srcType; + }) + .Where(mi => mi.ReturnType == destType) + .FirstOrDefault(); + + if (castOperator != null) + result = castOperator.Invoke(null, new object[] { source }); + else + return false; + + return true; + } + protected virtual string GetCodeUntilEndOfString(string subExpr, Match stringBeginningMatch) { StringBuilder stringBuilder = new StringBuilder();