/
ObjectCreateAnalyzer.cs
106 lines (97 loc) · 3.96 KB
/
ObjectCreateAnalyzer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System.Linq.Expressions;
using System.Reflection;
using System;
using System.Collections.Generic;
using LambdicSql.MultiplatformCompatibe;
using LambdicSql.ConverterServices.Inside;
namespace LambdicSql.ConverterServices
{
/// <summary>
/// A class that analyzes the creation part of object. It is used for conversion of Select phrase.
/// </summary>
public static class ObjectCreateAnalyzer
{
static Dictionary<Type, ObjectCreateInfo> _selectedTypeInfo = new Dictionary<Type, ObjectCreateInfo>();
/// <summary>
/// Creation of object generation information.
/// </summary>
/// <param name="type">type.</param>
/// <returns>ObjectCreateInfo.</returns>
public static ObjectCreateInfo MakeObjectCreateInfo(Type type)
{
lock (_selectedTypeInfo)
{
ObjectCreateInfo info;
if (_selectedTypeInfo.TryGetValue(type, out info)) return info;
var properties = type.GetPropertiesEx();
var members = new ObjectCreateMemberInfo[properties.Length];
for (int i = 0; i < members.Length; i++)
{
members[i] = new ObjectCreateMemberInfo(properties[i].Name, null);
}
info = new ObjectCreateInfo(members, null);
_selectedTypeInfo[type] = info;
return info;
}
}
/// <summary>
/// Creation of object generation information.
/// </summary>
/// <param name="exp">expression.</param>
/// <returns>ObjectCreateInfo.</returns>
public static ObjectCreateInfo MakeObjectCreateInfo(Expression exp)
{
var select = new List<ObjectCreateMemberInfo>();
var newExp = exp as NewExpression;
if (newExp != null)
{
for (int i = 0; i < newExp.Arguments.Count; i++)
{
var propInfo = newExp.Members[i] as PropertyInfo;
string name = null;
if (propInfo != null)
{
name = propInfo.Name;
}
else
{
//.net3.5
var method = newExp.Members[i] as MethodInfo;
name = method.GetPropertyName();
}
select.Add(new ObjectCreateMemberInfo(name, newExp.Arguments[i]));
}
return new ObjectCreateInfo(select.ToArray(), exp);
}
var initExp = exp as MemberInitExpression;
if (initExp != null)
{
var elements = new ObjectCreateMemberInfo[initExp.Bindings.Count];
for (int i = 0; i < elements.Length; i++)
{
var e = initExp.Bindings[i] as MemberAssignment;
elements[i] = new ObjectCreateMemberInfo(e.Member.Name, e.Expression);
}
return new ObjectCreateInfo(elements, exp);
}
var member = exp as MemberExpression;
if (member != null)
{
if (SupportedTypeSpec.IsSupported(exp.Type))
{
return new ObjectCreateInfo(new[] { new ObjectCreateMemberInfo(string.Empty, exp) }, exp);
}
Type type = null;
var prop = member.Member as PropertyInfo;
if (prop != null) type = prop.PropertyType;
else type = ((FieldInfo)member.Member).FieldType;
return MakeObjectCreateInfo(type);
}
return new ObjectCreateInfo(new[] { new ObjectCreateMemberInfo(string.Empty, exp )}, exp);
}
static string GetPropertyName(this MethodInfo method)
=> (method.Name.IndexOf("get_") == 0) ?
method.Name.Substring(4) :
method.Name;
}
}