@@ -60,30 +60,41 @@ Closure CreateClosure(Closure parent, HashSet<Variable> locals)
60
60
if ( parent != null && locals . Count == 0 )
61
61
return parent ;
62
62
63
- var type = new ClassType (
63
+ DataType masterType = new ClassType (
64
64
Source . Unknown ,
65
65
Function . DeclaringType ,
66
66
Function . Name + " lambda closure" ,
67
67
Modifiers . Private | Modifiers . Generated ,
68
68
Function . DeclaringType . GetUniqueIdentifier ( Function . Name + "_$closure" ) ) ;
69
69
70
- type . SetBase ( Essentials . Object ) ;
70
+ masterType . SetBase ( Essentials . Object ) ;
71
71
72
72
var constrBody = new Scope (
73
73
Source . Unknown ,
74
74
new CallConstructor ( Source . Unknown , Essentials . Object . TryGetConstructor ( ) ) ) ;
75
75
76
- type . Constructors . Add (
76
+ masterType . Constructors . Add (
77
77
new Constructor (
78
78
Source . Unknown ,
79
- type ,
79
+ masterType ,
80
80
"" ,
81
81
Modifiers . Public | Modifiers . Generated ,
82
82
ParameterList . Empty ,
83
83
constrBody ) ) ;
84
84
85
- Function . DeclaringType . NestedTypes . Add ( type ) ;
86
- _generatedTypes . Add ( type ) ;
85
+ Function . DeclaringType . NestedTypes . Add ( masterType ) ;
86
+ _generatedTypes . Add ( masterType ) ;
87
+
88
+ var type = TypeBuilder . Parameterize ( masterType ) ;
89
+ var isGenericType = ! type . IsMasterDefinition ;
90
+
91
+ if ( isGenericType )
92
+ {
93
+ var ctor = masterType . Constructors [ 0 ] ;
94
+ var parameterizedCtor = new Constructor ( ctor . Source , type , ctor . DocComment , ctor . Modifiers , ctor . Parameters , ctor . Body ) ;
95
+ parameterizedCtor . SetMasterDefinition ( ctor ) ;
96
+ type . Constructors . Add ( parameterizedCtor ) ;
97
+ }
87
98
88
99
var decl = new VariableDeclaration (
89
100
Source . Unknown ,
@@ -103,44 +114,59 @@ Closure CreateClosure(Closure parent, HashSet<Variable> locals)
103
114
{
104
115
if ( _closureVars . This )
105
116
{
117
+ var thisType = TypeBuilder . Parameterize ( Function . DeclaringType ) ;
106
118
var field = new Field (
107
119
Source . Unknown ,
108
- type ,
109
- type . GetUniqueIdentifier ( "self" ) ,
120
+ masterType ,
121
+ masterType . GetUniqueIdentifier ( "self" ) ,
110
122
"" ,
111
123
Modifiers . Public | Modifiers . Generated ,
112
124
0 ,
113
- Function . DeclaringType ) ;
125
+ thisType ) ;
114
126
115
- type . Fields . Add ( field ) ;
116
-
117
- statements . Add ( result . StoreThis ( new This ( Function . DeclaringType ) ) ) ;
127
+ masterType . Fields . Add ( field ) ;
128
+ statements . Add ( result . StoreThis ( new This ( thisType ) ) ) ;
118
129
}
119
130
120
131
foreach ( var p in _closureVars . Params )
121
132
{
122
133
var field = new Field (
123
134
p . Source ,
124
- type ,
125
- type . GetUniqueIdentifier ( p . Name ) ,
135
+ masterType ,
136
+ masterType . GetUniqueIdentifier ( p . Name ) ,
126
137
"" ,
127
138
Modifiers . Public | Modifiers . Generated ,
128
139
0 ,
129
140
p . Type ) ;
130
141
131
- type . Fields . Add ( field ) ;
132
- result . ParameterFields [ p ] = field ;
142
+ var parameterizedField = field ;
143
+
144
+ if ( isGenericType )
145
+ {
146
+ parameterizedField = new Field (
147
+ field . Source , type ,
148
+ field . Name ,
149
+ field . DocComment ,
150
+ field . Modifiers ,
151
+ field . FieldModifiers ,
152
+ field . ReturnType ) ;
153
+ parameterizedField . SetMasterDefinition ( field ) ;
154
+ type . Fields . Add ( parameterizedField ) ;
155
+ }
156
+
157
+ masterType . Fields . Add ( field ) ;
158
+ result . ParameterFields [ p ] = parameterizedField ;
133
159
statements . Add ( result . Store ( p , new LoadArgument ( Source . Unknown , Function , ParamIndex ( p ) ) ) ) ;
134
160
}
135
161
}
136
162
// Non-root closures get a parent field for the parent closure
137
163
else
138
164
{
139
- type . Fields . Add (
165
+ masterType . Fields . Add (
140
166
new Field (
141
167
Source . Unknown ,
142
- type ,
143
- type . GetUniqueIdentifier ( "parent" ) ,
168
+ masterType ,
169
+ masterType . GetUniqueIdentifier ( "parent" ) ,
144
170
"" ,
145
171
Modifiers . Public | Modifiers . Generated ,
146
172
0 ,
@@ -152,15 +178,30 @@ Closure CreateClosure(Closure parent, HashSet<Variable> locals)
152
178
{
153
179
var field = new Field (
154
180
v . Source ,
155
- type ,
156
- type . GetUniqueIdentifier ( v . Name ) ,
181
+ masterType ,
182
+ masterType . GetUniqueIdentifier ( v . Name ) ,
157
183
"" ,
158
184
Modifiers . Public | Modifiers . Generated ,
159
185
0 ,
160
186
v . ValueType ) ;
161
187
162
- type . Fields . Add ( field ) ;
163
- result . VariableFields [ v ] = field ;
188
+ var parameterizedField = field ;
189
+
190
+ if ( isGenericType )
191
+ {
192
+ parameterizedField = new Field (
193
+ field . Source , type ,
194
+ field . Name ,
195
+ field . DocComment ,
196
+ field . Modifiers ,
197
+ field . FieldModifiers ,
198
+ field . ReturnType ) ;
199
+ parameterizedField . SetMasterDefinition ( field ) ;
200
+ type . Fields . Add ( parameterizedField ) ;
201
+ }
202
+
203
+ masterType . Fields . Add ( field ) ;
204
+ result . VariableFields [ v ] = parameterizedField ;
164
205
}
165
206
166
207
return result ;
@@ -247,7 +288,7 @@ public override void Begin(ref Expression e, ExpressionUsage u)
247
288
248
289
_lambdaMethod = new Method (
249
290
e . Source ,
250
- _closureStack . Peek ( ) . Type ,
291
+ closureType ,
251
292
"Lambda method" ,
252
293
Modifiers . Public | Modifiers . Generated ,
253
294
closureType . GetUniqueIdentifier ( "generated_lambda" ) ,
@@ -257,6 +298,21 @@ public override void Begin(ref Expression e, ExpressionUsage u)
257
298
258
299
closureType . Methods . Add ( _lambdaMethod ) ;
259
300
301
+ if ( ! closureType . IsMasterDefinition )
302
+ {
303
+ var masterMethod = new Method (
304
+ _lambdaMethod . Source ,
305
+ closureType . MasterDefinition ,
306
+ _lambdaMethod . DocComment ,
307
+ _lambdaMethod . Modifiers ,
308
+ _lambdaMethod . Name ,
309
+ _lambdaMethod . ReturnType ,
310
+ _lambdaMethod . Parameters ,
311
+ _lambdaMethod . Body ) ;
312
+ _lambdaMethod . SetMasterDefinition ( masterMethod ) ;
313
+ closureType . MasterDefinition . Methods . Add ( masterMethod ) ;
314
+ }
315
+
260
316
break ;
261
317
}
262
318
}
0 commit comments