@@ -31,7 +31,7 @@ public partial class ExpressionEvaluator
31
31
32
32
protected const string primaryTypesRegexPattern = @"(?<=^|[^\p{L}_])(?<primaryType>object|string|bool[?]?|byte[?]?|char[?]?|decimal[?]?|double[?]?|short[?]?|int[?]?|long[?]?|sbyte[?]?|float[?]?|ushort[?]?|uint[?]?|ulong[?]?|void)(?=[^a-zA-Z_]|$)" ;
33
33
34
- protected static readonly Regex varOrFunctionRegEx = new Regex ( @"^((?<sign>[+-])|(?<prefixOperator>[+][+]|--)|(?<varKeyword>var)\s+|(?<dynamicKeyword>dynamic)\s+|(?<inObject> (?<nullConditional>[?])?\. )?)(?<name>[\p{L}_](?>[\p{L}_0-9]*))(?>\s*)((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>|\?\?)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![\p{L}_0-9]))|((?<isgeneric>[<](?>([\p{L}_](?>[\p{L}_0-9]*)|(?>\s+)|[,\.])+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
34
+ protected static readonly Regex varOrFunctionRegEx = new Regex ( @"^((?<sign>[+-])|(?<prefixOperator>[+][+]|--)|(?<varKeyword>var)\s+|(?<dynamicKeyword>dynamic)\s+|((?<nullConditional>[?])?(?<inObject>\.) )?)(?<name>[\p{L}_](?>[\p{L}_0-9]*))(?>\s*)((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>|\?\?)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![\p{L}_0-9]))|((?<isgeneric>[<](?>([\p{L}_](?>[\p{L}_0-9]*)|(?>\s+)|[,\.])+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
35
35
36
36
protected const string numberRegexOrigPattern = @"^(?<sign>[+-])?([0-9][0-9_{1}]*[0-9]|\d)(?<hasdecimal>{0}?([0-9][0-9_]*[0-9]|\d)(e[+-]?([0-9][0-9_]*[0-9]|\d))?)?(?<type>ul|[fdulm])?" ;
37
37
protected string numberRegexPattern ;
@@ -55,8 +55,7 @@ public partial class ExpressionEvaluator
55
55
protected static readonly Regex initInNewBeginningRegex = new Regex ( @"^(?>\s*){" , RegexOptions . Compiled ) ;
56
56
protected static readonly Regex functionArgKeywordsRegex = new Regex ( @"^\s*(?<keyword>out|ref|in)\s+((?<typeName>[\p{L}_][\p{L}_0-9\.\[\]<>]*[?]?)\s+(?=[\p{L}_]))?(?<toEval>(?<varName>[\p{L}_](?>[\p{L}_0-9]*))\s*(=.*)?)$" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
57
57
58
- // Depending on OptionInlineNamespacesEvaluationActive. Initialized in constructor
59
- protected string InstanceCreationWithNewKeywordRegexPattern { get { return @"^new(?>\s*)((?<isAnonymous>[{{])|((?<name>[\p{L}_][\p{L}_0-9" + ( OptionInlineNamespacesEvaluationActive ? @"\." : string . Empty ) + @"]*)(?>\s*)(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?>\s*)((?<isfunction>[(])|(?<isArray>\[)|(?<isInit>[{{]))?))" ; } }
58
+ protected static readonly Regex instanceCreationWithNewKeywordRegex = new Regex ( @"^new(?>\s*)((?<isAnonymous>[{{])|((?<name>[\p{L}_][\p{L}_0-9\.]*)(?>\s*)(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?>\s*)((?<isfunction>[(])|(?<isArray>\[)|(?<isInit>[{{]))?))" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
60
59
protected string CastRegexPattern { get { return @"^\((?>\s*)(?<typeName>[\p{L}_][\p{L}_0-9" + ( OptionInlineNamespacesEvaluationActive ? @"\." : string . Empty ) + @"\[\]<>]*[?]?)(?>\s*)\)" ; } }
61
60
62
61
// To remove comments in scripts based on https://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689
@@ -1724,7 +1723,7 @@ protected virtual bool EvaluateInstanceCreationWithNewKeyword(string expression,
1724
1723
if ( ! OptionNewKeywordEvaluationActive )
1725
1724
return false ;
1726
1725
1727
- Match instanceCreationMatch = Regex . Match ( expression . Substring ( i ) , InstanceCreationWithNewKeywordRegexPattern , optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ;
1726
+ Match instanceCreationMatch = instanceCreationWithNewKeywordRegex . Match ( expression . Substring ( i ) ) ;
1728
1727
1729
1728
if ( instanceCreationMatch . Success
1730
1729
&& ( stack . Count == 0
@@ -1769,9 +1768,11 @@ void InitSimpleObjet(object element, List<string> initArgs)
1769
1768
{
1770
1769
string completeName = instanceCreationMatch . Groups [ "name" ] . Value ;
1771
1770
string genericTypes = instanceCreationMatch . Groups [ "isgeneric" ] . Value ;
1772
- Type type = GetTypeByFriendlyName ( completeName , genericTypes ) ;
1773
1771
1774
- if ( type == null )
1772
+ int typeIndex = 0 ;
1773
+ Type type = EvaluateType ( completeName + genericTypes , ref typeIndex ) ;
1774
+
1775
+ if ( type == null || typeIndex > 0 && typeIndex < completeName . Length )
1775
1776
throw new ExpressionEvaluatorSyntaxErrorException ( $ "Type or class { completeName } { genericTypes } is unknown") ;
1776
1777
1777
1778
void Init ( object element , List < string > initArgs )
@@ -2439,73 +2440,7 @@ where method.GetParameters()[0].ParameterType == objType // static extMethod(thi
2439
2440
}
2440
2441
else
2441
2442
{
2442
- string typeName = $ "{ varFuncName } { ( ( i < expression . Length && expression . Substring ( i ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2443
- Type staticType = GetTypeByFriendlyName ( typeName , genericsTypes ) ;
2444
-
2445
- // For inline namespace parsing
2446
- if ( staticType == null && OptionInlineNamespacesEvaluationActive )
2447
- {
2448
- int subIndex = 0 ;
2449
- Match namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2450
-
2451
- while ( staticType == null
2452
- && namespaceMatch . Success
2453
- && ! namespaceMatch . Groups [ "sign" ] . Success
2454
- && ! namespaceMatch . Groups [ "assignationOperator" ] . Success
2455
- && ! namespaceMatch . Groups [ "postfixOperator" ] . Success
2456
- && ! namespaceMatch . Groups [ "isfunction" ] . Success
2457
- && i + subIndex < expression . Length
2458
- && ! typeName . EndsWith ( "?" ) )
2459
- {
2460
- subIndex += namespaceMatch . Length ;
2461
- typeName += $ ".{ namespaceMatch . Groups [ "name" ] . Value } { ( ( i + subIndex < expression . Length && expression . Substring ( i + subIndex ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2462
-
2463
- staticType = GetTypeByFriendlyName ( typeName , namespaceMatch . Groups [ "isgeneric" ] . Value ) ;
2464
-
2465
- if ( staticType != null )
2466
- {
2467
- i += subIndex ;
2468
- break ;
2469
- }
2470
-
2471
- namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2472
- }
2473
- }
2474
-
2475
- // For nested type parsing
2476
- if ( staticType != null )
2477
- {
2478
- int subIndex = 0 ;
2479
- Match nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2480
- Type nestedType = null ;
2481
-
2482
- while ( nestedTypeMatch . Success
2483
- && ! nestedTypeMatch . Groups [ "sign" ] . Success
2484
- && ! nestedTypeMatch . Groups [ "assignationOperator" ] . Success
2485
- && ! nestedTypeMatch . Groups [ "postfixOperator" ] . Success
2486
- && ! nestedTypeMatch . Groups [ "isfunction" ] . Success
2487
- && i + nestedTypeMatch . Length < expression . Length )
2488
- {
2489
- typeName += $ "+{ nestedTypeMatch . Groups [ "name" ] . Value } ";
2490
-
2491
- nestedType = GetTypeByFriendlyName ( typeName , nestedTypeMatch . Groups [ "isgeneric" ] . Value ) ;
2492
-
2493
- if ( nestedType != null )
2494
- {
2495
- i += nestedTypeMatch . Length ;
2496
- staticType = nestedType ;
2497
- }
2498
- else
2499
- {
2500
- break ;
2501
- }
2502
-
2503
- nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2504
- }
2505
- }
2506
-
2507
- if ( typeName . EndsWith ( "?" ) && staticType != null )
2508
- i ++ ;
2443
+ Type staticType = EvaluateType ( expression , ref i , varFuncName , genericsTypes ) ;
2509
2444
2510
2445
if ( staticType != null )
2511
2446
{
@@ -2547,6 +2482,79 @@ where method.GetParameters()[0].ParameterType == objType // static extMethod(thi
2547
2482
}
2548
2483
}
2549
2484
2485
+ protected virtual Type EvaluateType ( string expression , ref int i , string currentName = "" , string genericsTypes = "" )
2486
+ {
2487
+ string typeName = $ "{ currentName } { ( ( i < expression . Length && expression . Substring ( i ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2488
+ Type staticType = GetTypeByFriendlyName ( typeName , genericsTypes ) ;
2489
+
2490
+ // For inline namespace parsing
2491
+ if ( staticType == null && OptionInlineNamespacesEvaluationActive )
2492
+ {
2493
+ int subIndex = 0 ;
2494
+ Match namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2495
+
2496
+ while ( staticType == null
2497
+ && namespaceMatch . Success
2498
+ && ! namespaceMatch . Groups [ "sign" ] . Success
2499
+ && ! namespaceMatch . Groups [ "assignationOperator" ] . Success
2500
+ && ! namespaceMatch . Groups [ "postfixOperator" ] . Success
2501
+ && ! namespaceMatch . Groups [ "isfunction" ] . Success
2502
+ && i + subIndex < expression . Length
2503
+ && ! typeName . EndsWith ( "?" ) )
2504
+ {
2505
+ subIndex += namespaceMatch . Length ;
2506
+ typeName += $ "{ namespaceMatch . Groups [ "inObject" ] . Value } { namespaceMatch . Groups [ "name" ] . Value } { ( ( i + subIndex < expression . Length && expression . Substring ( i + subIndex ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2507
+
2508
+ staticType = GetTypeByFriendlyName ( typeName , namespaceMatch . Groups [ "isgeneric" ] . Value ) ;
2509
+
2510
+ if ( staticType != null )
2511
+ {
2512
+ i += subIndex ;
2513
+ break ;
2514
+ }
2515
+
2516
+ namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2517
+ }
2518
+ }
2519
+
2520
+ if ( typeName . EndsWith ( "?" ) && staticType != null )
2521
+ i ++ ;
2522
+
2523
+ // For nested type parsing
2524
+ if ( staticType != null )
2525
+ {
2526
+ int subIndex = 0 ;
2527
+ Match nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2528
+ while ( nestedTypeMatch . Success
2529
+ && ! nestedTypeMatch . Groups [ "sign" ] . Success
2530
+ && ! nestedTypeMatch . Groups [ "assignationOperator" ] . Success
2531
+ && ! nestedTypeMatch . Groups [ "postfixOperator" ] . Success
2532
+ && ! nestedTypeMatch . Groups [ "isfunction" ] . Success )
2533
+ {
2534
+ subIndex = nestedTypeMatch . Length ;
2535
+ typeName += $ "+{ nestedTypeMatch . Groups [ "name" ] . Value } { ( ( i + subIndex < expression . Length && expression . Substring ( i + subIndex ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2536
+
2537
+ Type nestedType = GetTypeByFriendlyName ( typeName , nestedTypeMatch . Groups [ "isgeneric" ] . Value ) ;
2538
+ if ( nestedType != null )
2539
+ {
2540
+ i += subIndex ;
2541
+ staticType = nestedType ;
2542
+
2543
+ if ( typeName . EndsWith ( "?" ) )
2544
+ i ++ ;
2545
+ }
2546
+ else
2547
+ {
2548
+ break ;
2549
+ }
2550
+
2551
+ nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i ) ) ;
2552
+ }
2553
+ }
2554
+
2555
+ return staticType ;
2556
+ }
2557
+
2550
2558
protected virtual bool EvaluateChar ( string expression , Stack < object > stack , ref int i )
2551
2559
{
2552
2560
if ( ! OptionCharEvaluationActive )
0 commit comments