|
1 | 1 | using System;
|
2 | 2 | using System.Collections.Generic;
|
3 | 3 | using System.Linq.Expressions;
|
| 4 | +using System.Reflection; |
4 | 5 |
|
5 | 6 | namespace QRest.Core.Compilation.TypeConverters
|
6 | 7 | {
|
7 | 8 | public class StringParser
|
8 | 9 | {
|
9 |
| - private static readonly string _parseMethodName = "Parse"; |
| 10 | + private static readonly string _parseMethodName = "Parse"; |
10 | 11 | private static readonly Type[] _parseWithFormatSignature = new[] { typeof(string), typeof(IFormatProvider) };
|
11 | 12 | private static readonly Type[] _parseSignature = new[] { typeof(string) };
|
| 13 | + private static readonly MethodInfo _enumParser = typeof(Enum).GetMethod(nameof(Enum.Parse), new[] { typeof(Type), typeof(string) }); |
12 | 14 |
|
13 | 15 | private static readonly Dictionary<Type, Func<Expression, IFormatProvider, Expression>> _parsers = new Dictionary<Type, Func<Expression, IFormatProvider, Expression>>();
|
14 | 16 |
|
15 | 17 | public static Func<Expression, IFormatProvider, Expression> GetParser(Type type)
|
16 | 18 | {
|
17 | 19 | if (!_parsers.ContainsKey(type))
|
18 | 20 | {
|
19 |
| - var source = Expression.Parameter(typeof(string)); |
20 |
| - |
21 |
| - Func<Expression, IFormatProvider, Expression[]> parameters = null; |
22 |
| - |
23 |
| - var method = type.GetMethod(_parseMethodName, _parseWithFormatSignature); |
24 |
| - if (method != null) parameters = (e, c) => new Expression[] { e, Expression.Constant(c, typeof(IFormatProvider)) }; |
25 |
| - else |
| 21 | + if (type.IsEnum) |
26 | 22 | {
|
27 |
| - method = type.GetMethod(_parseMethodName, _parseSignature); |
28 |
| - if (method != null) |
29 |
| - parameters = (e, c) => new Expression[] { e }; |
| 23 | + _parsers[type] = ParseEnum(type); |
30 | 24 | }
|
31 |
| - |
32 |
| - if (method != null && parameters != null) |
33 |
| - _parsers[type] = (e, c) => Expression.Call(method, parameters(e, c)); |
34 | 25 | else
|
35 |
| - _parsers[type] = null; |
| 26 | + { |
| 27 | + _parsers[type] = ParseOtherTypes(type) ?? throw new CompilationException($"Cannot find parser for type {type}"); |
| 28 | + } |
36 | 29 | }
|
37 | 30 |
|
38 | 31 | return _parsers[type];
|
39 | 32 | }
|
| 33 | + |
| 34 | + private static Func<Expression, IFormatProvider, Expression> ParseOtherTypes(Type type) |
| 35 | + { |
| 36 | + var method = type.GetMethod(_parseMethodName, _parseWithFormatSignature); |
| 37 | + if (method != null) |
| 38 | + return (e, c) => Expression.Call(method, new[] { e, Expression.Constant(c, typeof(IFormatProvider)) }); |
| 39 | + |
| 40 | + method = type.GetMethod(_parseMethodName, _parseSignature); |
| 41 | + if (method != null) |
| 42 | + return (e, c) => Expression.Call(method, new[] { e }); |
| 43 | + |
| 44 | + return null; |
| 45 | + } |
| 46 | + |
| 47 | + private static Func<Expression, IFormatProvider, Expression> ParseEnum(Type type) |
| 48 | + { |
| 49 | + return (e, c) => Expression.Convert(Expression.Call(_enumParser, new[] { Expression.Constant(type), e }), type); |
| 50 | + } |
40 | 51 | }
|
41 | 52 | }
|
0 commit comments