annotate Source/Data/Linq/Builder/ExpressionTestGenerator.cs @ 3:1ef98bd70424

!bug 100 +3h Исправление проблемы BLToolkit + mono 3.4
author cin
date Fri, 22 Aug 2014 17:34:46 +0400
parents f990fcb411a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
1 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
2 using System.Collections.Generic;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
3 using System.IO;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
4 using System.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
5 using System.Linq.Expressions;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
6 using System.Reflection;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
7 using System.Runtime.CompilerServices;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
8 using System.Text;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
9
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
10 using BLToolkit.Linq;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
11
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
12 namespace BLToolkit.Data.Linq.Builder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
13 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
14 class ExpressionTestGenerator
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
15 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
16 readonly StringBuilder _exprBuilder = new StringBuilder();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
17
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
18 string _indent = "\t\t\t\t";
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
19
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
20 void PushIndent() { _indent += '\t'; }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
21 void PopIndent () { _indent = _indent.Substring(1); }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
22
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
23 readonly HashSet<Expression> _visitedExprs = new HashSet<Expression>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
24
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
25 bool BuildExpression(Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
26 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
27 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
28 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
29 case ExpressionType.Add:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
30 case ExpressionType.AddChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
31 case ExpressionType.And:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
32 case ExpressionType.AndAlso:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
33 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
34 case ExpressionType.Assign:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
35 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
36 case ExpressionType.Coalesce:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
37 case ExpressionType.Divide:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
38 case ExpressionType.Equal:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
39 case ExpressionType.ExclusiveOr:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
40 case ExpressionType.GreaterThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
41 case ExpressionType.GreaterThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
42 case ExpressionType.LeftShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
43 case ExpressionType.LessThan:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
44 case ExpressionType.LessThanOrEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
45 case ExpressionType.Modulo:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
46 case ExpressionType.Multiply:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
47 case ExpressionType.MultiplyChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
48 case ExpressionType.NotEqual:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
49 case ExpressionType.Or:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
50 case ExpressionType.OrElse:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
51 case ExpressionType.Power:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
52 case ExpressionType.RightShift:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
53 case ExpressionType.Subtract:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
54 case ExpressionType.SubtractChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
55 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
56 var e = (BinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
57
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
58 _exprBuilder.Append("(");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
59
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
60 e.Left.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
61
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
62 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
63 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
64 case ExpressionType.Add :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
65 case ExpressionType.AddChecked : _exprBuilder.Append(" + "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
66 case ExpressionType.And : _exprBuilder.Append(" & "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
67 case ExpressionType.AndAlso : _exprBuilder.Append(" && "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
68 #if FW4 || SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
69 case ExpressionType.Assign : _exprBuilder.Append(" = "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
70 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
71 case ExpressionType.Coalesce : _exprBuilder.Append(" ?? "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
72 case ExpressionType.Divide : _exprBuilder.Append(" / "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
73 case ExpressionType.Equal : _exprBuilder.Append(" == "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
74 case ExpressionType.ExclusiveOr : _exprBuilder.Append(" ^ "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
75 case ExpressionType.GreaterThan : _exprBuilder.Append(" > "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
76 case ExpressionType.GreaterThanOrEqual : _exprBuilder.Append(" >= "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
77 case ExpressionType.LeftShift : _exprBuilder.Append(" << "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
78 case ExpressionType.LessThan : _exprBuilder.Append(" < "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
79 case ExpressionType.LessThanOrEqual : _exprBuilder.Append(" <= "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
80 case ExpressionType.Modulo : _exprBuilder.Append(" % "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
81 case ExpressionType.Multiply :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
82 case ExpressionType.MultiplyChecked : _exprBuilder.Append(" * "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
83 case ExpressionType.NotEqual : _exprBuilder.Append(" != "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
84 case ExpressionType.Or : _exprBuilder.Append(" | "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
85 case ExpressionType.OrElse : _exprBuilder.Append(" || "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
86 case ExpressionType.Power : _exprBuilder.Append(" ** "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
87 case ExpressionType.RightShift : _exprBuilder.Append(" >> "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
88 case ExpressionType.Subtract :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
89 case ExpressionType.SubtractChecked : _exprBuilder.Append(" - "); break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
90 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
91
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
92 e.Right.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
93
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
94 _exprBuilder.Append(")");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
95
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
96 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
97 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
98
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
99 case ExpressionType.ArrayLength:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
100 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
101 var e = (UnaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
102
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
103 e.Operand.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
104 _exprBuilder.Append(".Length");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
105
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
106 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
107 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
108
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
109 case ExpressionType.Convert:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
110 case ExpressionType.ConvertChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
111 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
112 var e = (UnaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
113
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
114 _exprBuilder.AppendFormat("({0})", GetTypeName(e.Type));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
115 e.Operand.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
116
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
117 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
118 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
119
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
120 case ExpressionType.Negate:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
121 case ExpressionType.NegateChecked:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
122 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
123 _exprBuilder.Append("-");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
124 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
125 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
126
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
127 case ExpressionType.Not:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
128 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
129 _exprBuilder.Append("!");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
130 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
131 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
132
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
133 case ExpressionType.Quote:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
134 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
135
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
136 case ExpressionType.TypeAs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
137 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
138 var e = (UnaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
139
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
140 _exprBuilder.Append("(");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
141 e.Operand.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
142 _exprBuilder.AppendFormat(" as {0})", GetTypeName(e.Type));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
143
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
144 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
145 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
146
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
147 case ExpressionType.UnaryPlus:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
148 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
149 _exprBuilder.Append("+");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
150 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
151 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
152
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
153 case ExpressionType.ArrayIndex:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
154 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
155 var e = (BinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
156
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
157 e.Left.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
158 _exprBuilder.Append("[");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
159 e.Right.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
160 _exprBuilder.Append("]");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
161
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
162 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
163 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
164
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
165 case ExpressionType.MemberAccess :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
166 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
167 var e = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
168
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
169 e.Expression.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
170 _exprBuilder.AppendFormat(".{0}", e.Member.Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
171
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
172 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
173 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
174
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
175 case ExpressionType.Parameter :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
176 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
177 var e = (ParameterExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
178 _exprBuilder.Append(e.Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
179 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
180 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
181
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
182 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
183 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
184 var ex = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
185 var mi = ex.Method;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
186
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
187 var attrs = mi.GetCustomAttributes(typeof(ExtensionAttribute), false);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
188
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
189 if (attrs.Length != 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
190 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
191 ex.Arguments[0].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
192 PushIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
193 _exprBuilder.AppendLine().Append(_indent);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
194 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
195 else if (ex.Object != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
196 ex.Object.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
197 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
198 _exprBuilder.Append(GetTypeName(mi.DeclaringType));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
199
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
200 _exprBuilder.Append(".").Append(mi.Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
201
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
202 if (mi.IsGenericMethod && mi.GetGenericArguments().Select(GetTypeName).All(t => t != null))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
203 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
204 _exprBuilder
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
205 .Append("<")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
206 .Append(GetTypeNames(mi.GetGenericArguments(), ","))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
207 .Append(">");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
208 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
209
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
210 _exprBuilder.Append("(");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
211
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
212 PushIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
213
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
214 var n = attrs.Length != 0 ? 1 : 0;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
215
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
216 for (var i = n; i < ex.Arguments.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
217 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
218 if (i != n)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
219 _exprBuilder.Append(",");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
220
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
221 _exprBuilder.AppendLine().Append(_indent);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
222
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
223 ex.Arguments[i].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
224 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
225
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
226 PopIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
227
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
228 _exprBuilder.Append(")");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
229
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
230 if (attrs.Length != 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
231 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
232 PopIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
233 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
234
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
235 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
236 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
237
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
238 case ExpressionType.Constant:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
239 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
240 var c = (ConstantExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
241
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
242 if (c.Value is IQueryable)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
243 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
244 var e = ((IQueryable)c.Value).Expression;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
245
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
246 if (_visitedExprs.Add(e))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
247 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
248 e.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
249 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
250 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
251 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
252
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
253 _exprBuilder.Append(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
254
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
255 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
256 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
257
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
258 case ExpressionType.Lambda:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
259 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
260 var le = (LambdaExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
261 var ps = le.Parameters
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
262 .Select(p => (GetTypeName(p.Type) + " " + p.Name).TrimStart())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
263 .Aggregate("", (p1, p2) => p1 + ", " + p2, p => p.TrimStart(',', ' '));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
264
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
265 _exprBuilder.Append("(").Append(ps).Append(") => ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
266
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
267 le.Body.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
268 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
269 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
270
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
271 case ExpressionType.Conditional:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
272 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
273 var e = (ConditionalExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
274
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
275 _exprBuilder.Append("(");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
276 e.Test.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
277 _exprBuilder.Append(" ? ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
278 e.IfTrue.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
279 _exprBuilder.Append(" : ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
280 e.IfFalse.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
281 _exprBuilder.Append(")");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
282
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
283 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
284 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
285
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
286 case ExpressionType.New:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
287 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
288 var ne = (NewExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
289
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
290 if (IsAnonymous(ne.Type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
291 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
292 if (ne.Members.Count == 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
293 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
294 _exprBuilder.AppendFormat("new {{ {0} = ", ne.Members[0].Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
295 ne.Arguments[0].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
296 _exprBuilder.Append(" }}");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
297 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
298 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
299 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
300 _exprBuilder.AppendLine("new").Append(_indent).Append("{");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
301
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
302 PushIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
303
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
304 for (var i = 0; i < ne.Members.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
305 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
306 _exprBuilder.AppendLine().Append(_indent).AppendFormat("{0} = ", ne.Members[i].Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
307 ne.Arguments[i].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
308
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
309 if (i + 1 < ne.Members.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
310 _exprBuilder.Append(",");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
311 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
312
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
313 PopIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
314 _exprBuilder.AppendLine().Append(_indent).Append("}");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
315 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
316 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
317 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
318 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
319 _exprBuilder.AppendFormat("new {0}(", GetTypeName(ne.Type));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
320
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
321 for (var i = 0; i < ne.Arguments.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
322 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
323 ne.Arguments[i].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
324 if (i + 1 < ne.Arguments.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
325 _exprBuilder.Append(", ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
326 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
327
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
328 _exprBuilder.Append(")");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
329 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
330
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
331 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
332 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
333
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
334 case ExpressionType.MemberInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
335 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
336 Func<MemberBinding,bool> modify = b =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
337 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
338 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
339 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
340 case MemberBindingType.Assignment :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
341 var ma = (MemberAssignment)b;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
342 _exprBuilder.AppendFormat("{0} = ", ma.Member.Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
343 ma.Expression.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
344 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
345 default:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
346 _exprBuilder.Append(b.ToString());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
347 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
348 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
349
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
350 return true;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
351 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
352
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
353 var e = (MemberInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
354
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
355 e.NewExpression.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
356
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
357 if (e.Bindings.Count == 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
358 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
359 _exprBuilder.Append(" { ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
360 modify(e.Bindings[0]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
361 _exprBuilder.Append(" }");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
362 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
363 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
364 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
365 _exprBuilder.AppendLine().Append(_indent).Append("{");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
366
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
367 PushIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
368
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
369 for (var i = 0; i < e.Bindings.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
370 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
371 _exprBuilder.AppendLine().Append(_indent);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
372 modify(e.Bindings[i]);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
373 if (i + 1 < e.Bindings.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
374 _exprBuilder.Append(",");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
375 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
376
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
377 PopIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
378 _exprBuilder.AppendLine().Append(_indent).Append("}");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
379 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
380
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
381 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
382 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
383
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
384 case ExpressionType.NewArrayInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
385 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
386 var e = (NewArrayExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
387
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
388 _exprBuilder.AppendFormat("new {0}[]", GetTypeName(e.Type.GetElementType()));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
389
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
390 if (e.Expressions.Count == 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
391 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
392 _exprBuilder.Append(" { ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
393 e.Expressions[0].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
394 _exprBuilder.Append(" }");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
395 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
396 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
397 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
398 _exprBuilder.AppendLine().Append(_indent).Append("{");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
399
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
400 PushIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
401
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
402 for (var i = 0; i < e.Expressions.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
403 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
404 _exprBuilder.AppendLine().Append(_indent);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
405 e.Expressions[i].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
406 if (i + 1 < e.Expressions.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
407 _exprBuilder.Append(",");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
408 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
409
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
410 PopIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
411 _exprBuilder.AppendLine().Append(_indent).Append("}");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
412 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
413
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
414 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
415 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
416
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
417 case ExpressionType.TypeIs:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
418 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
419 var e = (TypeBinaryExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
420
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
421 _exprBuilder.Append("(");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
422 e.Expression.Visit(new Func<Expression, bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
423 _exprBuilder.AppendFormat(" is {0})", e.TypeOperand);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
424
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
425 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
426 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
427
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
428 case ExpressionType.ListInit:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
429 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
430 var e = (ListInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
431
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
432 e.NewExpression.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
433
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
434 if (e.Initializers.Count == 1)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
435 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
436 _exprBuilder.Append(" { ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
437 e.Initializers[0].Arguments[0].Visit(new Func<Expression, bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
438 _exprBuilder.Append(" }");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
439 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
440 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
441 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
442 _exprBuilder.AppendLine().Append(_indent).Append("{");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
443
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
444 PushIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
445
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
446 for (var i = 0; i < e.Initializers.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
447 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
448 _exprBuilder.AppendLine().Append(_indent);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
449 e.Initializers[i].Arguments[0].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
450 if (i + 1 < e.Initializers.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
451 _exprBuilder.Append(",");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
452 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
453
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
454 PopIndent();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
455 _exprBuilder.AppendLine().Append(_indent).Append("}");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
456 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
457
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
458 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
459 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
460
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
461 case ExpressionType.Invoke:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
462 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
463 var e = (InvocationExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
464
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
465 _exprBuilder.Append("Expression.Invoke(");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
466 e.Expression.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
467 _exprBuilder.Append(", (");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
468
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
469 for (var i = 0; i < e.Arguments.Count; i++)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
470 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
471 e.Arguments[i].Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
472 if (i + 1 < e.Arguments.Count)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
473 _exprBuilder.Append(", ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
474 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
475 _exprBuilder.Append("))");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
476
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
477 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
478 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
479
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
480 default:
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
481 _exprBuilder.AppendLine("// Unknown expression.").Append(_indent).Append(expr);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
482 return false;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
483 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
484 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
485
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
486 readonly Dictionary<Type,string> _typeNames = new Dictionary<Type,string>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
487 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
488 { typeof(object), "object" },
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
489 { typeof(bool), "bool" },
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
490 { typeof(int), "int" },
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
491 { typeof(string), "string" },
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
492 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
493
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
494 readonly StringBuilder _typeBuilder = new StringBuilder();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
495
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
496 void BuildType(Type type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
497 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
498 if (type.Namespace != null && type.Namespace.StartsWith("System") ||
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
499 IsAnonymous(type) ||
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
500 type.Assembly == GetType().Assembly ||
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
501 type.IsGenericType && type.GetGenericTypeDefinition() != type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
502 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
503
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
504 var name = type.Name;//.Replace('<', '_').Replace('>', '_').Replace('`', '_').Replace("__f__", "");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
505
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
506 var idx = name.LastIndexOf("`");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
507
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
508 if (idx > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
509 name = name.Substring(0, idx);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
510
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
511 if (type.IsGenericType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
512 type = type.GetGenericTypeDefinition();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
513
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
514 var baseClasses = new[] { type.BaseType }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
515 .Where(t => t != null && t != typeof(object))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
516 .Concat(type.GetInterfaces()).ToArray();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
517
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
518 var ctors = type.GetConstructors().Select(c =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
519 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
520 #if SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
521 var attrs = c.GetCustomAttributes(false).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
522 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
523 var attrs = c.GetCustomAttributesData();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
524 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
525 var ps = c.GetParameters().Select(p => GetTypeName(p.ParameterType) + " " + p.Name).ToArray();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
526 return string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
527 "{0}\n\t\tpublic {1}({2})\n\t\t{{\n\t\t\tthrow new NotImplementedException();\n\t\t}}",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
528 attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
529 name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
530 ps.Length == 0 ? "" : ps.Aggregate((s,t) => s + ", " + t));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
531 }).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
532
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
533 if (ctors.Count == 1 && ctors[0].IndexOf("()") >= 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
534 ctors.Clear();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
535
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
536 var members = type.GetFields().Intersect(_usedMembers.OfType<FieldInfo>()).Select(f =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
537 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
538 #if SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
539 var attrs = f.GetCustomAttributes(false).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
540 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
541 var attrs = f.GetCustomAttributesData();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
542 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
543 return string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
544 "{0}\n\t\tpublic {1} {2};",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
545 attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
546 GetTypeName(f.FieldType),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
547 f.Name);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
548 })
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
549 .Concat(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
550 type.GetProperties().Intersect(_usedMembers.OfType<PropertyInfo>()).Select(p =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
551 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
552 #if SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
553 var attrs = p.GetCustomAttributes(false).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
554 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
555 var attrs = p.GetCustomAttributesData();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
556 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
557 return string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
558 "{0}\n\t\t{3}{1} {2} {{ get; set; }}",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
559 attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
560 GetTypeName(p.PropertyType),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
561 p.Name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
562 type.IsInterface ? "" : "public ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
563 }))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
564 .Concat(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
565 type.GetMethods().Intersect(_usedMembers.OfType<MethodInfo>()).Select(m =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
566 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
567 #if SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
568 var attrs = m.GetCustomAttributes(false).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
569 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
570 var attrs = m.GetCustomAttributesData();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
571 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
572 var ps = m.GetParameters().Select(p => GetTypeName(p.ParameterType) + " " + p.Name).ToArray();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
573 return string.Format(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
574 "{0}\n\t\t{5}{4}{1} {2}({3})\n\t\t{{\n\t\t\tthrow new NotImplementedException();\n\t\t}}",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
575 attrs.Count > 0 ? attrs.Select(a => "\n\t\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
576 GetTypeName(m.ReturnType),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
577 m.Name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
578 ps.Length == 0 ? "" : ps.Aggregate((s,t) => s + ", " + t),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
579 m.IsStatic ? "static " :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
580 m.IsVirtual ? "virtual " :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
581 m.IsAbstract ? "abstract " :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
582 "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
583 type.IsInterface ? "" : "public ");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
584 }))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
585 .ToArray();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
586
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
587 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
588 #if SILVERLIGHT
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
589 var attrs = type.GetCustomAttributes(false).ToList();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
590 #else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
591 var attrs = type.GetCustomAttributesData();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
592 #endif
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
593
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
594 _typeBuilder.AppendFormat(
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
595 type.IsGenericType ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
596 @"
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
597 namespace {0}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
598 {{{8}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
599 {6}{7}{1} {2}<{3}>{5}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
600 {{{4}{9}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
601 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
602 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
603 "
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
604 :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
605 @"
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
606 namespace {0}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
607 {{{8}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
608 {6}{7}{1} {2}{5}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
609 {{{4}{9}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
610 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
611 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
612 ",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
613 type.Namespace,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
614 type.IsInterface ? "interface" : type.IsClass ? "class" : "struct",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
615 name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
616 type.IsGenericType ? GetTypeNames(type.GetGenericArguments(), ",") : null,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
617 ctors.Count == 0 ? "" : ctors.Aggregate((s,t) => s + "\n" + t),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
618 baseClasses.Length == 0 ? "" : " : " + GetTypeNames(baseClasses),
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
619 type.IsPublic ? "public " : "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
620 type.IsAbstract && !type.IsInterface ? "abstract " : "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
621 attrs.Count > 0 ? attrs.Select(a => "\n\t" + a.ToString()).Aggregate((a1,a2) => a1 + a2) : "",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
622 members.Length > 0 ?
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
623 (ctors.Count != 0 ? "\n" : "") + members.Aggregate((f1,f2) => f1 + "\n" + f2) :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
624 "");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
625 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
626 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
627
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
628 string GetTypeNames(IEnumerable<Type> types, string separator = ", ")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
629 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
630 return types.Select(GetTypeName).Aggregate("", (t1,t2) => t1 + separator + t2, p => p.TrimStart(separator.ToCharArray()));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
631 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
632
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
633 bool IsAnonymous(Type type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
634 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
635 return type.Name.StartsWith("<>f__AnonymousType");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
636 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
637
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
638 string GetTypeName(Type type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
639 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
640 if (type == null || type == typeof(object))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
641 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
642
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
643 if (type.IsGenericParameter)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
644 return type.ToString();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
645
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
646 string name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
647
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
648 if (_typeNames.TryGetValue(type, out name))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
649 return name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
650
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
651 if (IsAnonymous(type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
652 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
653 _typeNames[type] = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
654 return null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
655 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
656
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
657 if (type.IsGenericType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
658 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
659 var args = type.GetGenericArguments();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
660
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
661 name = "";
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
662
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
663 if (type.Namespace != "System")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
664 name = type.Namespace + ".";
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
665
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
666 name += type.Name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
667
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
668 var idx = name.LastIndexOf("`");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
669
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
670 if (idx > 0)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
671 name = name.Substring(0, idx);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
672
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
673 if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
674 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
675 name = string.Format("{0}?", GetTypeName(args[0]));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
676 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
677 else
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
678 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
679 name = string.Format("{0}<{1}>",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
680 name,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
681 args.Select(GetTypeName).Aggregate("", (s,t) => s + "," + t, p => p.TrimStart(',')));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
682 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
683
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
684 _typeNames[type] = name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
685
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
686 return name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
687 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
688
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
689 if (type.Namespace == "System")
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
690 return type.Name;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
691
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
692 return type.ToString();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
693 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
694
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
695 readonly HashSet<MemberInfo> _usedMembers = new HashSet<MemberInfo>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
696
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
697 void VisitMembers(Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
698 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
699 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
700 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
701 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
702 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
703 var ex = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
704 _usedMembers.Add(ex.Method);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
705
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
706 if (ex.Method.IsGenericMethod)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
707 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
708 var gmd = ex.Method.GetGenericMethodDefinition();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
709
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
710 if (gmd != ex.Method)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
711 _usedMembers.Add(gmd);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
712
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
713 var ga = ex.Method.GetGenericArguments();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
714
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
715 foreach (var type in ga)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
716 _usedMembers.Add(type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
717 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
718
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
719 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
720 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
721
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
722 case ExpressionType.MemberAccess :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
723 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
724 var ex = (MemberExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
725 _usedMembers.Add(ex.Member);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
726 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
727 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
728
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
729 case ExpressionType.MemberInit :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
730 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
731 var ex = (MemberInitExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
732
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
733 Action<IEnumerable<MemberBinding>> visit = null; visit = bs =>
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
734 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
735 foreach (var b in bs)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
736 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
737 _usedMembers.Add(b.Member);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
738
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
739 switch (b.BindingType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
740 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
741 case MemberBindingType.MemberBinding :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
742 visit(((MemberMemberBinding)b).Bindings);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
743 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
744 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
745 };
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
746
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
747 visit(ex.Bindings);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
748 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
749 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
750 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
751 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
752
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
753 readonly HashSet<Type> _usedTypes = new HashSet<Type>();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
754
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
755 void AddType(Type type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
756 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
757 if (type == null || type == typeof(object) || type.IsGenericParameter || _usedTypes.Contains(type))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
758 return;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
759
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
760 _usedTypes.Add(type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
761
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
762 if (type.IsGenericType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
763 foreach (var arg in type.GetGenericArguments())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
764 AddType(arg);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
765
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
766 if (type.IsGenericType && type.GetGenericTypeDefinition() != type)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
767 AddType(type.GetGenericTypeDefinition());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
768
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
769 AddType(type.BaseType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
770
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
771 foreach (var i in type.GetInterfaces())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
772 AddType(i);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
773 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
774
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
775 void VisitTypes(Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
776 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
777 AddType(expr.Type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
778
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
779 switch (expr.NodeType)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
780 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
781 case ExpressionType.Call :
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
782 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
783 var ex = (MethodCallExpression)expr;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
784 var mi = ex.Method;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
785
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
786 AddType(mi.DeclaringType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
787 AddType(mi.ReturnType);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
788
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
789 foreach (var arg in mi.GetGenericArguments())
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
790 AddType(arg);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
791
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
792 break;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
793 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
794 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
795 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
796
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
797 public string GenerateSource(Expression expr)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
798 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
799 string fileName = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
800 StreamWriter sw = null;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
801
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
802 try
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
803 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
804 var dir = Path.Combine(Path.GetTempPath(), "bltookit\\");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
805
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
806 if (!Directory.Exists(dir))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
807 Directory.CreateDirectory(dir);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
808
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
809 var number = 0;//DateTime.Now.Ticks;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
810
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
811 fileName = Path.Combine(dir, "ExpressionTest." + number + ".cs");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
812
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
813 expr.Visit(new Action<Expression>(VisitMembers));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
814 expr.Visit(new Action<Expression>(VisitTypes));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
815
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
816 foreach (var type in _usedTypes.OrderBy(t => t.Namespace).ThenBy(t => t.Name))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
817 BuildType(type);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
818
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
819 expr.Visit(new Func<Expression,bool>(BuildExpression));
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
820
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
821 _exprBuilder.Replace("<>h__TransparentIdentifier", "tp");
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
822
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
823 sw = File.CreateText(fileName);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
824
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
825 sw.WriteLine(@"//---------------------------------------------------------------------------------------------------
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
826 // This code was generated by BLToolkit.
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
827 //---------------------------------------------------------------------------------------------------
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
828 using System;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
829 using System.Linq.Expressions;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
830
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
831 using NUnit.Framework;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
832 {0}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
833 namespace Data.Linq.UserTests
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
834 {{
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
835 [TestFixture]
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
836 public class UserTest : TestBase
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
837 {{
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
838 [Test]
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
839 public void Test([DataContexts] string context)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
840 {{
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
841 // {1}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
842 using (var db = GetDataContext(context))
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
843 {{
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
844 {2};
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
845 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
846 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
847 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
848 }}
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
849 ",
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
850 _typeBuilder,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
851 expr,
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
852 _exprBuilder);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
853 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
854 catch(Exception ex)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
855 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
856 if (sw != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
857 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
858 sw.WriteLine();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
859 sw.WriteLine(ex.GetType());
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
860 sw.WriteLine(ex.Message);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
861 sw.WriteLine(ex.StackTrace);
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
862 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
863 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
864 finally
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
865 {
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
866 if (sw != null)
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
867 sw.Close();
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
868 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
869
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
870 return fileName;
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
871 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
872 }
f990fcb411a9 Копия текущей версии из github
cin
parents:
diff changeset
873 }