11namespace AgileObjects . ReadableExpressions . Translators
22{
33 using System ;
4- using System . Collections . Generic ;
54 using System . Globalization ;
65 using System . Linq . Expressions ;
76#if NET_STANDARD
@@ -32,9 +31,7 @@ public override string Translate(Expression expression, TranslationContext conte
3231 return constant . Type . GetFriendlyName ( ) + "." + constant . Value ;
3332 }
3433
35- string translation ;
36-
37- if ( TryTranslateByTypeCode ( constant , out translation ) )
34+ if ( TryTranslateByTypeCode ( constant , out var translation ) )
3835 {
3936 return translation ;
4037 }
@@ -214,17 +211,17 @@ private static bool TryGetFactoryMethodCall(
214211
215212 private static string FormatNumeric ( decimal value )
216213 {
217- return ( value % 1 ) . Equals ( 0 ) ? value . ToString ( "0" ) : value . ToString ( ) ;
214+ return ( value % 1 ) . Equals ( 0 ) ? value . ToString ( "0" ) : value . ToString ( CultureInfo . CurrentCulture ) ;
218215 }
219216
220217 private static string FormatNumeric ( double value )
221218 {
222- return ( value % 1 ) . Equals ( 0 ) ? value . ToString ( "0" ) : value . ToString ( ) ;
219+ return ( value % 1 ) . Equals ( 0 ) ? value . ToString ( "0" ) : value . ToString ( CultureInfo . CurrentCulture ) ;
223220 }
224221
225222 private static string FormatNumeric ( float value )
226223 {
227- return ( value % 1 ) . Equals ( 0 ) ? value . ToString ( "0" ) : value . ToString ( ) ;
224+ return ( value % 1 ) . Equals ( 0 ) ? value . ToString ( "0" ) : value . ToString ( CultureInfo . CurrentCulture ) ;
228225 }
229226
230227 private static bool IsType ( ConstantExpression constant , out string translation )
@@ -239,116 +236,116 @@ private static bool IsType(ConstantExpression constant, out string translation)
239236 return false ;
240237 }
241238
242- private static readonly Regex _funcMatcher = new Regex ( @"^System\.(?<Type> Func|Action)`\d+\[(?<Arguments>.+) \]$" ) ;
239+ private static readonly Regex _funcMatcher = new Regex ( @"^System\.(?: Func|Action)`\d+\[.+ \]$" ) ;
243240
244241 private static bool IsFunc ( ConstantExpression constant , out string translation )
245242 {
246243 var match = _funcMatcher . Match ( constant . Value . ToString ( ) ) ;
247244
248- if ( ! match . Success )
245+ if ( match . Success )
249246 {
250- translation = null ;
251- return false ;
247+ translation = ParseFuncFrom ( match . Value ) ;
248+ return true ;
252249 }
253250
254- var funcType = match . Groups [ "Type" ] . Value ;
255- var argumentTypes = ParseArgumentNames ( match . Groups [ "Arguments" ] . Value . Split ( ',' ) ) ;
256-
257- translation = GetGenericTypeName ( funcType , argumentTypes ) ;
258- return true ;
251+ translation = null ;
252+ return false ;
259253 }
260254
261255 #region IsFunc Helpers
262256
263- private static IEnumerable < string > ParseArgumentNames ( params string [ ] arguments )
257+ private static string ParseFuncFrom ( string funcString )
264258 {
265- for ( var i = 0 ; i < arguments . Length ; i ++ )
259+ var symbols = new [ ] { '`' , ',' , '[' , ']' } ;
260+ var parseIndex = 0 ;
261+ var parsedFunc = string . Empty ;
262+
263+ while ( true )
266264 {
267- var argument = arguments [ i ] ;
268- var genericArgumentsIndex = argument . IndexOf ( '`' ) ;
265+ var nextSymbolIndex = funcString . IndexOfAny ( symbols , parseIndex ) ;
269266
270- if ( genericArgumentsIndex == - 1 )
267+ if ( nextSymbolIndex == - 1 )
271268 {
272- yield return GetTypeName ( argument ) ;
273- continue ;
274- }
269+ var substring = funcString . Substring ( parseIndex ) ;
275270
276- if ( argument . StartsWith ( "System.Nullable`" ) )
277- {
278- yield return GetNullableTypeName ( argument ) ;
279- continue ;
271+ if ( substring . Length > 0 )
272+ {
273+ var typeName = GetTypeName ( substring ) ;
274+
275+ parsedFunc += typeName ;
276+ }
277+ break ;
280278 }
281279
282- var genericTypeName = GetTypeName ( argument . Substring ( 0 , genericArgumentsIndex ) ) ;
283- var genericTypeArgumentsStart = argument . IndexOf ( '[' , genericArgumentsIndex ) + 1 ;
284- argument = argument . Substring ( genericTypeArgumentsStart ) ;
285- var genericTypeArgumentsClosesNeeded = 1 ;
286- var genericTypeArgumentsString = argument ;
280+ var substringLength = nextSymbolIndex - parseIndex ;
287281
288- if ( i == arguments . Length - 1 )
282+ if ( substringLength > 0 )
289283 {
290- genericTypeArgumentsString = RemoveFinalGenericArgumentsClose ( genericTypeArgumentsString ) ;
284+ var substring = funcString . Substring ( parseIndex , substringLength ) ;
285+
286+ if ( substring == "System.Nullable" )
287+ {
288+ var nullableTypeIndex = parseIndex + "System.Nullable`1[" . Length ;
289+ var nullableTypeEndIndex = funcString . IndexOf ( ']' , nullableTypeIndex ) ;
290+ var nullableTypeLength = nullableTypeEndIndex - nullableTypeIndex ;
291+ substring = funcString . Substring ( nullableTypeIndex , nullableTypeLength ) ;
292+
293+ var typeName = GetTypeName ( substring ) ;
294+
295+ parsedFunc += typeName + "?" ;
296+ parseIndex = nullableTypeEndIndex + 1 ;
297+ continue ;
298+ }
299+ else
300+ {
301+ var typeName = GetTypeName ( substring ) ;
302+
303+ parsedFunc += typeName ;
304+ parseIndex = nextSymbolIndex + 1 ;
305+ }
291306 }
292- else
307+
308+ switch ( funcString [ nextSymbolIndex ] )
293309 {
294- while ( i < arguments . Length - 1 )
295- {
296- if ( argument . IndexOf ( '`' ) != - 1 )
297- {
298- ++ genericTypeArgumentsClosesNeeded ;
299- }
310+ case '`' :
311+ parsedFunc += "<" ;
312+ parseIndex = funcString . IndexOf ( '[' , parseIndex ) + 1 ;
313+ continue ;
300314
301- argument = arguments [ ++ i ] ;
302- genericTypeArgumentsString += "," + argument ;
315+ case ',' :
316+ parsedFunc += ", " ;
303317
304- if ( argument . EndsWith ( ']' ) && ( argument [ argument . Length - 2 ] != '[' ) )
318+ if ( substringLength == 0 )
305319 {
306- -- genericTypeArgumentsClosesNeeded ;
320+ ++ parseIndex ;
307321 }
322+ continue ;
323+
324+ case '[' :
325+ parsedFunc += "[]" ;
326+ ++ parseIndex ;
327+ continue ;
328+
329+ case ']' :
330+ parsedFunc += ">" ;
308331
309- if ( genericTypeArgumentsClosesNeeded == 0 )
332+ if ( substringLength == 0 )
310333 {
311- genericTypeArgumentsString = RemoveFinalGenericArgumentsClose ( genericTypeArgumentsString ) ;
312- break ;
334+ ++ parseIndex ;
313335 }
314- }
336+ break ;
315337 }
316-
317- var genericTypeArguments = ParseArgumentNames ( genericTypeArgumentsString . Split ( ',' ) ) ;
318-
319- yield return GetGenericTypeName ( genericTypeName , genericTypeArguments ) ;
320338 }
339+
340+ return parsedFunc ;
321341 }
322342
323343 private static string GetTypeName ( string typeFullName )
324344 {
325- if ( typeFullName . EndsWith ( "[]" , StringComparison . Ordinal ) )
326- {
327- return GetTypeName ( typeFullName . Substring ( 0 , typeFullName . Length - 2 ) ) + "[]" ;
328- }
329-
330345 return typeFullName . GetSubstitutionOrNull ( ) ??
331346 typeFullName . Substring ( typeFullName . LastIndexOf ( '.' ) + 1 ) ;
332347 }
333348
334- private static readonly int _nullableTypeArgumentStart = "System.Nullable`1[" . Length ;
335-
336- private static string GetNullableTypeName ( string typeFullName )
337- {
338- var nullableTypeNameLength = typeFullName . Length - _nullableTypeArgumentStart - 1 ;
339- var nullableTypeName = typeFullName . Substring ( _nullableTypeArgumentStart , nullableTypeNameLength ) ;
340-
341- return GetTypeName ( nullableTypeName ) + "?" ;
342- }
343-
344- private static string RemoveFinalGenericArgumentsClose ( string genericTypeArgumentsString )
345- {
346- return genericTypeArgumentsString . Substring ( 0 , genericTypeArgumentsString . Length - 1 ) ;
347- }
348-
349- private static string GetGenericTypeName ( string typeName , IEnumerable < string > arguments )
350- => $ "{ typeName } <{ string . Join ( ", " , arguments ) } >";
351-
352349 #endregion
353350
354351 private static bool IsDefault < T > ( ConstantExpression constant , out string translation )
0 commit comments