Skip to content

Commit 08b6684

Browse files
committed
Merge remote-tracking branch 'origin/dev' into dev
2 parents 0b44092 + c27cbc9 commit 08b6684

File tree

4 files changed

+78
-22
lines changed

4 files changed

+78
-22
lines changed

CodingSeb.ExpressionEvaluator.Tests/CodingSeb.ExpressionEvaluator.Tests.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@
118118
<ItemGroup>
119119
<None Include="Resources\Script0032.txt" />
120120
</ItemGroup>
121+
<ItemGroup>
122+
<Reference Include="System.Net" />
123+
</ItemGroup>
121124
<ItemGroup>
122125
<EmbeddedResource Update="Resources.resx">
123126
<Generator>PublicResXFileCodeGenerator</Generator>

CodingSeb.ExpressionEvaluator.Tests/ExpressionEvaluatorTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,8 @@ public void TypeTesting(string expression, Type type)
867867
[TestCase("List(\"hello\", \"bye\").Select(x => x.ToUpper()).ToList().FluidAdd(\"test\")[0]", ExpectedResult = "HELLO", Category = "Complex expression,Fluid Functions")]
868868
[TestCase("List(\"hello\", \"bye\").Select(x => x.ToUpper()).ToList().FluidAdd(\"test\")[1]", ExpectedResult = "BYE", Category = "Complex expression,Fluid Functions")]
869869
[TestCase("List(\"hello\", \"bye\").Select(x => x.ToUpper()).ToList().FluidAdd(\"test\")[2]", ExpectedResult = "test", Category = "Complex expression,Fluid Functions")]
870+
[TestCase("List(\"hello\", \"bye\").Select(x => x.ToUpper()).ToList().FluidAdd(\"test\")[2]", ExpectedResult = "test", Category = "Complex expression,Fluid Functions")]
871+
[TestCase("$\"https://www.google.ch/search?q={System.Net.WebUtility.UrlEncode(\"test of request with url encode() ?\")}\"", ExpectedResult = "https://www.google.ch/search?q=test+of+request+with+url+encode()+%3F", Category = "Complex expression,Inline namespace")]
870872
#endregion
871873

872874
#endregion

CodingSeb.ExpressionEvaluator/CodingSeb.ExpressionEvaluator.csproj

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
<Product>CodingSeb.ExpressionEvaluator</Product>
66
<Description>A Simple Math and Pseudo C# Expression Evaluator in One C# File. And from version 1.2.0 can execute small C# like scripts</Description>
77
<Copyright>Copyright © Coding Seb 2017</Copyright>
8-
<Version>1.3.1.0</Version>
9-
<AssemblyVersion>1.3.1.0</AssemblyVersion>
10-
<FileVersion>1.3.1.0</FileVersion>
8+
<Version>1.3.2.0</Version>
9+
<AssemblyVersion>1.3.2.0</AssemblyVersion>
10+
<FileVersion>1.3.2.0</FileVersion>
1111
<OutputPath>bin\$(Configuration)\</OutputPath>
1212
<Authors>Coding Seb</Authors>
1313
<PackageId>CodingSeb.ExpressionEvaluator</PackageId>
@@ -18,9 +18,9 @@
1818
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
1919
<PackageIconUrl>https://github.com/codingseb/ExpressionEvaluator/blob/master/Icon.png?raw=true</PackageIconUrl>
2020
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
21-
<PackageReleaseNotes>* Array initialisation with new type[] { x, y, ...} or new type[2]
22-
* Correction of multiple bugs with String interpolation, doublequote char and string escape
23-
* Icon in ReadMe</PackageReleaseNotes>
21+
<PackageReleaseNotes>* Support for inline namespaces (More flexible, but slower)
22+
* Option OptionInlineNamespacesEvaluationActive (To unactive inline namespaces)
23+
* Remove not necessary nugets dependencies</PackageReleaseNotes>
2424
</PropertyGroup>
2525
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
2626
<DebugType>full</DebugType>
@@ -31,9 +31,5 @@
3131
<ItemGroup>
3232
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
3333
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
34-
<PackageReference Include="System.Net.Http" Version="4.3.4" />
35-
</ItemGroup>
36-
<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
37-
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
3834
</ItemGroup>
3935
</Project>

CodingSeb.ExpressionEvaluator/ExpressionEvaluator.cs

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/******************************************************************************************************
22
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3-
Version : 1.3.1.0
3+
Version : 1.3.2.0
44
(if last digit is not a zero, the version is an intermediate version and can be unstable)
55
66
Author : Coding Seb
@@ -29,11 +29,10 @@ public class ExpressionEvaluator
2929
private static readonly string diactitics = "áàâãåǎăāąæéèêëěēĕėęěìíîïīĭįijóôõöōŏőøðœùúûüǔũūŭůűųýþÿŷıćĉċčçďđĝğġģĥħĵķĺļľŀłńņňŋñŕŗřśŝşšţťŧŵźżžÁÀÂÃÅǍĂĀĄÆÉÈÊËĚĒĔĖĘĚÌÍÎÏĪĬĮIJÓÔÕÖŌŎŐØÐŒÙÚÛÜǓŨŪŬŮŰŲÝÞŸŶIĆĈĊČÇĎĐĜĞĠĢĤĦĴĶĹĻĽĿŁŃŅŇŊÑŔŖŘŚŜŞŠŢŤŦŴŹŻŽß";
3030
private static readonly string diactiticsKeywordsRegexPattern = "a-zA-Z_" + diactitics;
3131

32-
private static readonly Regex varOrFunctionRegEx = new Regex(@"^((?<sign>[+-])|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>["+ diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*)\s*((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![" + diactiticsKeywordsRegexPattern + @"0-9]))|((?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))", RegexOptions.IgnoreCase | RegexOptions.Compiled);
32+
private static readonly Regex varOrFunctionRegEx = new Regex($@"^((?<sign>[+-])|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>[{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern }0-9]*)\s*((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![{ diactiticsKeywordsRegexPattern}0-9]))|((?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))", RegexOptions.IgnoreCase | RegexOptions.Compiled);
3333
private static readonly Regex numberRegex = new Regex(@"^(?<sign>[+-])?\d+(?<hasdecimal>\.?\d+(e[+-]?\d+)?)?(?<type>ul|[fdulm])?", RegexOptions.IgnoreCase);
3434
private static readonly Regex stringBeginningRegex = new Regex("^(?<interpolated>[$])?(?<escaped>[@])?[\"]");
3535
private static readonly Regex internalCharRegex = new Regex(@"^['](\\[']|[^'])*[']");
36-
private static readonly Regex castRegex = new Regex(@"^\(\s*(?<typeName>[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9\.\[\]<>]*[?]?)\s*\)");
3736
private static readonly Regex indexingBeginningRegex = new Regex(@"^[?]?\[");
3837
private static readonly Regex assignationOrPostFixOperatorRegex = new Regex(@"^\s*((?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>])|(?<postfixOperator>([+][+]|--)(?![" + diactiticsKeywordsRegexPattern + @"0-9])))");
3938

@@ -43,13 +42,18 @@ public class ExpressionEvaluator
4342
private static readonly Regex endOfStringWithoutDollarWithAt = new Regex("^[^\"]*[\"]");
4443
private static readonly Regex endOfStringInterpolationRegex = new Regex("^('\"'|[^}\"])*[}\"]");
4544
private static readonly Regex stringBeginningForEndBlockRegex = new Regex("[$]?[@]?[\"]$");
46-
private static readonly Regex lambdaExpressionRegex = new Regex(@"^\s*(?<args>(\s*[(]\s*([" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*\s*([,]\s*[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*\s*)*)?[)])|[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*)\s*=>(?<expression>.*)$", RegexOptions.Singleline);
47-
private static readonly Regex lambdaArgRegex = new Regex(@"[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*");
45+
private static readonly Regex lambdaExpressionRegex = new Regex($@"^\s*(?<args>(\s*[(]\s*([{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern }0-9]*\s*([,]\s*[{diactiticsKeywordsRegexPattern}][{ diactiticsKeywordsRegexPattern}0-9]*\s*)*)?[)])|[{ diactiticsKeywordsRegexPattern}][{ diactiticsKeywordsRegexPattern }0-9]*)\s*=>(?<expression>.*)$", RegexOptions.Singleline);
46+
private static readonly Regex lambdaArgRegex = new Regex($@"[{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern }0-9]*");
4847
private static readonly Regex initInNewBeginningRegex = new Regex(@"^\s*{");
4948
private static readonly Regex OtherDimentionArrayInNewBeginningRegex = new Regex(@"^\s*\[");
5049

51-
private static readonly string instanceCreationWithNewKeywordRegexPattern = @"^new\s+(?<name>[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9.]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?\s*((?<isfunction>[(])|(?<isArray>\[))?";
52-
private Regex instanceCreationWithNewKeywordRegex = new Regex(instanceCreationWithNewKeywordRegexPattern);
50+
51+
// Depending on OptionInlineNamespacesEvaluationActive. Initialized in constructor
52+
private string CastRegexPattern { get { return $@"^\(\s*(?<typeName>[{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern }0-9\{ (OptionInlineNamespacesEvaluationActive ? @"\." : string.Empty) }[\]<>]*[?]?)\s*\)"; } }
53+
private string InstanceCreationWithNewKeywordRegexPattern { get { return $@"^new\s+(?<name>[{ diactiticsKeywordsRegexPattern }][{ diactiticsKeywordsRegexPattern}0-9{ (OptionInlineNamespacesEvaluationActive ? @"\." : string.Empty) }]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?\s*((?<isfunction>[(])|(?<isArray>\[))?"; } }
54+
private Regex instanceCreationWithNewKeywordRegex = null;
55+
private Regex castRegex = null;
56+
5357
private static readonly string primaryTypesRegexPattern = @"(?<=^|[^" + diactiticsKeywordsRegexPattern + @"])(?<primaryType>object|string|bool[?]?|byte[?]?|char[?]?|decimal[?]?|double[?]?|short[?]?|int[?]?|long[?]?|sbyte[?]?|float[?]?|ushort[?]?|uint[?]?|void)(?=[^a-zA-Z_]|$)";
5458
private Regex primaryTypesRegex = new Regex(primaryTypesRegexPattern);
5559

@@ -462,7 +466,7 @@ public bool OptionCaseSensitiveEvaluationActive
462466
simpleDoubleMathFuncsDictionary = new Dictionary<string, Func<double, double>>(simpleDoubleMathFuncsDictionary, StringComparerForCasing);
463467
doubleDoubleMathFuncsDictionary = new Dictionary<string, Func<double, double, double>>(doubleDoubleMathFuncsDictionary, StringComparerForCasing);
464468
complexStandardFuncsDictionary = new Dictionary<string, Func<ExpressionEvaluator, List<string>, object>>(complexStandardFuncsDictionary, StringComparerForCasing);
465-
instanceCreationWithNewKeywordRegex = new Regex(instanceCreationWithNewKeywordRegexPattern, (optionCaseSensitiveEvaluationActive ? RegexOptions.None : RegexOptions.IgnoreCase));
469+
instanceCreationWithNewKeywordRegex = new Regex(InstanceCreationWithNewKeywordRegexPattern, (optionCaseSensitiveEvaluationActive ? RegexOptions.None : RegexOptions.IgnoreCase));
466470
primaryTypesRegex = new Regex(primaryTypesRegexPattern, (optionCaseSensitiveEvaluationActive ? RegexOptions.None : RegexOptions.IgnoreCase));
467471
}
468472
}
@@ -489,6 +493,22 @@ private StringComparer StringComparerForCasing
489493
/// </summary>
490494
public bool OptionNewKeywordEvaluationActive { get; set; } = true;
491495

496+
/// <summary>
497+
/// if <c>true</c> allow the use of inline namespace (Can be slow, and is less secure).
498+
/// if <c>false</c> unactive inline namespace (only namespaces in Namespaces list are available).
499+
/// By default : true
500+
/// </summary>
501+
public bool OptionInlineNamespacesEvaluationActive
502+
{
503+
get { return optionInlineNamespacesEvaluationActive; }
504+
set
505+
{
506+
optionInlineNamespacesEvaluationActive = value;
507+
instanceCreationWithNewKeywordRegex = new Regex(InstanceCreationWithNewKeywordRegexPattern, (optionCaseSensitiveEvaluationActive ? RegexOptions.None : RegexOptions.IgnoreCase));
508+
castRegex = new Regex(CastRegexPattern, (optionCaseSensitiveEvaluationActive ? RegexOptions.None : RegexOptions.IgnoreCase));
509+
}
510+
}
511+
492512
private Func<ExpressionEvaluator, List<string>, object> newMethodMem;
493513

494514
/// <summary>
@@ -673,6 +693,8 @@ public Dictionary<string, object> Variables
673693
public ExpressionEvaluator()
674694
{
675695
Assemblies.AddRange(AppDomain.CurrentDomain.GetAssemblies());
696+
instanceCreationWithNewKeywordRegex = new Regex(InstanceCreationWithNewKeywordRegexPattern);
697+
castRegex = new Regex(CastRegexPattern);
676698
}
677699

678700
/// <summary>
@@ -689,6 +711,7 @@ public ExpressionEvaluator(Dictionary<string, object> variables) : this()
689711
#region Main evaluate methods (Expressions and scripts ==> public)
690712

691713
private bool inScript = false;
714+
private bool optionInlineNamespacesEvaluationActive = true;
692715

693716
/// <summary>
694717
/// Evaluate a script (multiple expressions separated by semicolon)
@@ -1766,6 +1789,35 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
17661789
string typeName = $"{varFuncName}{((i < expr.Length && expr.Substring(i)[0] == '?') ? "?" : "") }";
17671790
Type staticType = GetTypeByFriendlyName(typeName);
17681791

1792+
if(staticType == null && OptionInlineNamespacesEvaluationActive)
1793+
{
1794+
int subIndex = 0;
1795+
Match namespaceMatch = varOrFunctionRegEx.Match(expr.Substring(i + subIndex));
1796+
1797+
while (staticType == null &&
1798+
namespaceMatch.Success &&
1799+
!namespaceMatch.Groups["sign"].Success &&
1800+
!namespaceMatch.Groups["assignationOperator"].Success &&
1801+
!namespaceMatch.Groups["postfixOperator"].Success &&
1802+
!namespaceMatch.Groups["postfixOperator"].Success &&
1803+
!namespaceMatch.Groups["isfunction"].Success &&
1804+
i + subIndex < expr.Length &&
1805+
!typeName.EndsWith("?"))
1806+
{
1807+
subIndex += namespaceMatch.Length;
1808+
typeName += $"{namespaceMatch.Value}{((i + subIndex < expr.Length && expr.Substring(i + subIndex)[0] == '?') ? "?" : "") }";
1809+
staticType = GetTypeByFriendlyName(typeName);
1810+
1811+
if(staticType != null)
1812+
{
1813+
i += subIndex;
1814+
break;
1815+
}
1816+
1817+
namespaceMatch = varOrFunctionRegEx.Match(expr.Substring(i + subIndex));
1818+
}
1819+
}
1820+
17691821
if (typeName.EndsWith("?") && staticType != null)
17701822
i++;
17711823

@@ -2584,11 +2636,14 @@ private Type GetTypeByFriendlyName(string typeName)
25842636

25852637
for (int a = 0; a < Assemblies.Count && result == null; a++)
25862638
{
2587-
result = Type.GetType($"{typeName},{Assemblies[a].FullName}", false, !OptionCaseSensitiveEvaluationActive);
2588-
2589-
for (int i = 0; i < Namespaces.Count && result == null; i++)
2639+
if(typeName.Contains("."))
2640+
result = Type.GetType($"{typeName},{Assemblies[a].FullName}", false, !OptionCaseSensitiveEvaluationActive);
2641+
else
25902642
{
2591-
result = Type.GetType($"{Namespaces[i]}.{typeName},{Assemblies[a].FullName}", false, !OptionCaseSensitiveEvaluationActive);
2643+
for (int i = 0; i < Namespaces.Count && result == null; i++)
2644+
{
2645+
result = Type.GetType($"{Namespaces[i]}.{typeName},{Assemblies[a].FullName}", false, !OptionCaseSensitiveEvaluationActive);
2646+
}
25922647
}
25932648
}
25942649
}

0 commit comments

Comments
 (0)