1
- using System . Linq . Expressions ;
1
+ using System . Collections . ObjectModel ;
2
+ using System . Linq . Expressions ;
2
3
3
4
namespace Hyperbee . Expressions ;
4
5
5
6
public class ForExpression : Expression
6
7
{
8
+ public IEnumerable < ParameterExpression > Variables { get ; }
7
9
public Expression Initialization { get ; }
8
10
public Expression Test { get ; }
9
11
public Expression Iteration { get ; }
@@ -12,33 +14,36 @@ public class ForExpression : Expression
12
14
public LabelTarget BreakLabel { get ; } = Label ( "break" ) ;
13
15
public LabelTarget ContinueLabel { get ; } = Label ( "continue" ) ;
14
16
15
- internal ForExpression ( Expression initialization , Expression test , Expression iteration , Expression body )
17
+ internal ForExpression ( IEnumerable < ParameterExpression > variables , Expression initialization , Expression test , Expression iteration , Expression body )
16
18
{
17
19
ThrowIfInvalid ( test , body ) ;
18
20
21
+ Variables = variables ;
19
22
Initialization = initialization ;
20
23
Test = test ;
21
24
Iteration = iteration ;
22
25
Body = body ;
23
26
}
24
27
25
- internal ForExpression ( Expression initialization , Expression test , Expression iteration , LoopBody body )
28
+ internal ForExpression ( IEnumerable < ParameterExpression > variables , Expression initialization , Expression test , Expression iteration , LoopBody body )
26
29
{
27
30
ThrowIfInvalid ( test , body ) ;
28
31
32
+ Variables = variables ;
29
33
Initialization = initialization ;
30
34
Test = test ;
31
35
Iteration = iteration ;
32
36
Body = body ( BreakLabel , ContinueLabel ) ;
33
37
}
34
38
35
- internal ForExpression ( Expression initialization , Expression test , Expression iteration , Expression body , LabelTarget breakLabel , LabelTarget continueLabel )
39
+ internal ForExpression ( IEnumerable < ParameterExpression > variables , Expression initialization , Expression test , Expression iteration , Expression body , LabelTarget breakLabel , LabelTarget continueLabel )
36
40
{
37
41
ThrowIfInvalid ( test , body ) ;
38
42
39
43
ArgumentNullException . ThrowIfNull ( breakLabel , nameof ( breakLabel ) ) ;
40
44
ArgumentNullException . ThrowIfNull ( continueLabel , nameof ( continueLabel ) ) ;
41
45
46
+ Variables = variables ;
42
47
Initialization = initialization ;
43
48
Test = test ;
44
49
Iteration = iteration ;
@@ -64,6 +69,7 @@ private static void ThrowIfInvalid( Expression test, object body )
64
69
public override Expression Reduce ( )
65
70
{
66
71
return Block (
72
+ Variables ,
67
73
Initialization ,
68
74
Loop (
69
75
IfThenElse (
@@ -82,33 +88,80 @@ public override Expression Reduce()
82
88
83
89
protected override Expression VisitChildren ( ExpressionVisitor visitor )
84
90
{
91
+ var newVariables = VisitCollection ( visitor , Variables . ToArray ( ) ) ;
85
92
var newInitialization = visitor . Visit ( Initialization ) ;
86
93
var newTest = visitor . Visit ( Test ) ;
87
94
var newIteration = visitor . Visit ( Iteration ) ;
88
95
var newBody = visitor . Visit ( Body ) ;
89
96
90
- if ( newInitialization == Initialization && newTest == Test && newIteration == Iteration && newBody == Body )
97
+ if ( newVariables == Variables && newInitialization == Initialization && newTest == Test && newIteration == Iteration && newBody == Body )
91
98
return this ;
92
99
93
- return new ForExpression ( newInitialization , newTest , newIteration , newBody , BreakLabel , ContinueLabel ) ;
100
+ return new ForExpression ( newVariables , newInitialization , newTest , newIteration , newBody , BreakLabel , ContinueLabel ) ;
94
101
95
102
}
103
+
104
+ private static IEnumerable < T > VisitCollection < T > ( ExpressionVisitor visitor , T [ ] nodes ) where T : Expression
105
+ {
106
+ T [ ] newNodes = null ;
107
+
108
+ for ( int i = 0 , n = nodes . Length ; i < n ; i ++ )
109
+ {
110
+ var node = visitor . Visit ( nodes [ i ] ) ;
111
+
112
+ if ( newNodes != null )
113
+ {
114
+ newNodes [ i ] = ( T ) node ;
115
+ }
116
+ else if ( ! ReferenceEquals ( node , nodes [ i ] ) )
117
+ {
118
+ newNodes = new T [ n ] ;
119
+ for ( int j = 0 ; j < i ; j ++ )
120
+ {
121
+ newNodes [ j ] = nodes [ j ] ;
122
+ }
123
+ newNodes [ i ] = ( T ) node ;
124
+ }
125
+ }
126
+
127
+ if ( newNodes == null )
128
+ {
129
+ return nodes ;
130
+ }
131
+
132
+ return newNodes ;
133
+ }
96
134
}
97
135
98
136
public static partial class ExpressionExtensions
99
137
{
100
138
public static ForExpression For ( Expression initialization , Expression test , Expression iteration , Expression body )
101
139
{
102
- return new ForExpression ( initialization , test , iteration , body ) ;
140
+ return new ForExpression ( [ ] , initialization , test , iteration , body ) ;
103
141
}
104
142
105
143
public static ForExpression For ( Expression initialization , Expression test , Expression iteration , Expression body , LabelTarget breakLabel , LabelTarget continueLabel )
106
144
{
107
- return new ForExpression ( initialization , test , iteration , body , breakLabel , continueLabel ) ;
145
+ return new ForExpression ( [ ] , initialization , test , iteration , body , breakLabel , continueLabel ) ;
108
146
}
109
147
110
148
public static ForExpression For ( Expression initialization , Expression test , Expression iteration , LoopBody body )
111
149
{
112
- return new ForExpression ( initialization , test , iteration , body ) ;
150
+ return new ForExpression ( [ ] , initialization , test , iteration , body ) ;
151
+ }
152
+
153
+ public static ForExpression For ( IEnumerable < ParameterExpression > variables , Expression initialization , Expression test , Expression iteration , Expression body )
154
+ {
155
+ return new ForExpression ( variables , initialization , test , iteration , body ) ;
156
+ }
157
+
158
+ public static ForExpression For ( IEnumerable < ParameterExpression > variables , Expression initialization , Expression test , Expression iteration , Expression body , LabelTarget breakLabel , LabelTarget continueLabel )
159
+ {
160
+ return new ForExpression ( variables , initialization , test , iteration , body , breakLabel , continueLabel ) ;
161
+ }
162
+
163
+ public static ForExpression For ( IEnumerable < ParameterExpression > variables , Expression initialization , Expression test , Expression iteration , LoopBody body )
164
+ {
165
+ return new ForExpression ( variables , initialization , test , iteration , body ) ;
113
166
}
114
167
}
0 commit comments