30
30
31
31
import javax .lang .model .element .Modifier ;
32
32
import java .util .ArrayList ;
33
- import java .util .HashSet ;
33
+ import java .util .LinkedHashSet ;
34
34
import java .util .List ;
35
35
import java .util .Set ;
36
36
@@ -44,8 +44,8 @@ final class LambdaExpressionWriter extends AbstractStatementAwareExpressionWrite
44
44
private static final String METAFACTORY_METHOD = "metafactory" ;
45
45
private static final String METAFACTORY_DESCRIPTOR =
46
46
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;" +
47
- "Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;" +
48
- "Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;" ;
47
+ "Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;" +
48
+ "Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;" ;
49
49
50
50
private final Lambda lambda ;
51
51
@@ -55,12 +55,12 @@ public LambdaExpressionWriter(Lambda lambda) {
55
55
56
56
@ Override
57
57
public void write (GeneratorAdapter generatorAdapter , MethodContext context ) {
58
- List <VariableDef > capturedVariables = captureVariables (lambda .method ());
58
+ List <VariableDef > capturedVariables = captureVariables (lambda .implementation ());
59
59
MethodDef implementationMethodDef = createLambdaMethodDef (context , lambda , capturedVariables );
60
60
context .lambdaMethods ().add (implementationMethodDef );
61
61
62
62
// The captured variables are the parameters to the called bootstrap method
63
- for (VariableDef variable : capturedVariables ) {
63
+ for (VariableDef variable : capturedVariables ) {
64
64
new VariableExpressionWriter (variable ).write (generatorAdapter , context );
65
65
}
66
66
@@ -87,19 +87,19 @@ public void write(GeneratorAdapter generatorAdapter, MethodContext context) {
87
87
);
88
88
89
89
generatorAdapter .visitInvokeDynamicInsn (
90
- lambda .method ().getName (),
90
+ lambda .implementation ().getName (),
91
91
createDynamicInvocationDescriptor (capturedVariables , context ),
92
92
bootstrapMethodHandle ,
93
- Type .getType (TypeUtils .getMethodDescriptor (context .objectDef (), lambda .overriddenMethod ())),
93
+ Type .getType (TypeUtils .getMethodDescriptor (context .objectDef (), lambda .target ())),
94
94
lambdaMethodHandle ,
95
- Type .getType (TypeUtils .getMethodDescriptor (context .objectDef (), lambda .method ()))
95
+ Type .getType (TypeUtils .getMethodDescriptor (context .objectDef (), lambda .implementation ()))
96
96
);
97
97
popValueIfNeeded (generatorAdapter , lambda .type ());
98
98
}
99
99
100
100
private String createDynamicInvocationDescriptor (List <VariableDef > capturedVariables , MethodContext context ) {
101
101
StringBuilder dynamicDescriptor = new StringBuilder ("(" );
102
- for (VariableDef variable : capturedVariables ) {
102
+ for (VariableDef variable : capturedVariables ) {
103
103
dynamicDescriptor .append (TypeUtils .getType (variable .type (), context .objectDef ()));
104
104
}
105
105
dynamicDescriptor .append (")" );
@@ -108,11 +108,11 @@ private String createDynamicInvocationDescriptor(List<VariableDef> capturedVaria
108
108
}
109
109
110
110
private MethodDef createLambdaMethodDef (MethodContext context , Lambda lambda , List <VariableDef > capturedVariables ) {
111
- MethodDef original = lambda .method ();
111
+ MethodDef original = lambda .implementation ();
112
112
List <ParameterDef > parameters = new ArrayList <>();
113
113
114
114
// The captured variables are parameters
115
- for (VariableDef variable : capturedVariables ) {
115
+ for (VariableDef variable : capturedVariables ) {
116
116
if (variable instanceof VariableDef .Local local ) {
117
117
parameters .add (ParameterDef .builder (local .name (), local .type ()).build ());
118
118
} else if (variable instanceof VariableDef .MethodParameter parameter ) {
@@ -130,7 +130,7 @@ private MethodDef createLambdaMethodDef(MethodContext context, Lambda lambda, Li
130
130
131
131
parameters .addAll (original .getParameters ());
132
132
return MethodDef .builder ("lambda$" + context .methodDef ().getName () + "$" +
133
- context .lambdaMethods ().size ())
133
+ context .lambdaMethods ().size ())
134
134
.addModifiers (Modifier .PRIVATE , Modifier .STATIC )
135
135
.addParameters (parameters )
136
136
.returns (original .getReturnType ())
@@ -139,59 +139,19 @@ private MethodDef createLambdaMethodDef(MethodContext context, Lambda lambda, Li
139
139
}
140
140
141
141
private List <VariableDef > captureVariables (MethodDef method ) {
142
- Set <String > variables = new HashSet <>(
142
+ Set <String > variables = new LinkedHashSet <>(
143
143
method .getParameters ().stream ().map (v -> v .getName ()).toList ()
144
144
);
145
145
List <VariableDef > capturedVariables = new ArrayList <>();
146
- for (StatementDef statement : method .getStatements ()) {
146
+ for (StatementDef statement : method .getStatements ()) {
147
147
captureVariables (statement , variables , capturedVariables );
148
148
}
149
149
return capturedVariables ;
150
150
}
151
151
152
152
private void captureVariables (StatementDef statement , Set <String > variables , List <VariableDef > capturedVariables ) {
153
- if (statement instanceof StatementDef .Multi multi ) {
154
- for (StatementDef s : multi .statements ()) {
155
- captureVariables (s , variables , capturedVariables );
156
- }
157
- } else if (statement instanceof StatementDef .Return returnStatement ) {
158
- captureVariables (returnStatement .expression (), variables , capturedVariables );
159
- } else if (statement instanceof StatementDef .Synchronized sync ) {
160
- captureVariables (sync .monitor (), variables , capturedVariables );
161
- captureVariables (sync .statement (), variables , capturedVariables );
162
- } else if (statement instanceof StatementDef .Throw throwStatement ) {
163
- captureVariables (throwStatement .expression (), variables , capturedVariables );
164
- } else if (statement instanceof StatementDef .Assign assign ) {
165
- captureVariables (assign .variable (), variables , capturedVariables );
166
- captureVariables (assign .expression (), variables , capturedVariables );
167
- } else if (statement instanceof StatementDef .DefineAndAssign assign ) {
168
- variables .add (assign .variable ().name ());
169
- captureVariables (assign .expression (), variables , capturedVariables );
170
- } else if (statement instanceof StatementDef .While w ) {
171
- captureVariables (w .expression (), variables , capturedVariables );
172
- captureVariables (w .statement (), variables , capturedVariables );
173
- } else if (statement instanceof StatementDef .If ifStatement ) {
174
- captureVariables (ifStatement .condition (), variables , capturedVariables );
175
- captureVariables (ifStatement .statement (), variables , capturedVariables );
176
- } else if (statement instanceof StatementDef .Try tryStatement ) {
177
- captureVariables (tryStatement .statement (), variables , capturedVariables );
178
- captureVariables (tryStatement .finallyStatement (), variables , capturedVariables );
179
- for (StatementDef .Try .Catch cat : tryStatement .catches ()) {
180
- captureVariables (cat .statement (), variables , capturedVariables );
181
- }
182
- } else if (statement instanceof StatementDef .IfElse ifElse ) {
183
- captureVariables (ifElse .condition (), variables , capturedVariables );
184
- captureVariables (ifElse .statement (), variables , capturedVariables );
185
- captureVariables (ifElse .elseStatement (), variables , capturedVariables );
186
- } else if (statement instanceof StatementDef .PutField putField ) {
187
- capturedVariables .add (putField .field ());
188
- variables .add (putField .field ().name ());
189
- captureVariables (putField .expression (), variables , capturedVariables );
190
- } else if (statement instanceof StatementDef .PutStaticField putStaticField ) {
191
- captureVariables (putStaticField .expression (), variables , capturedVariables );
192
- } else {
193
- throw new IllegalStateException ("Unsupported statement type in lambda: " + statement .getClass ().getName ());
194
- }
153
+ statement .nestedExpressionsStream ()
154
+ .forEach (expressionDef -> captureVariables (expressionDef , variables , capturedVariables ));
195
155
}
196
156
197
157
private void captureVariables (ExpressionDef expression , Set <String > variables , List <VariableDef > capturedVariables ) {
@@ -225,9 +185,8 @@ private void captureVariables(ExpressionDef expression, Set<String> variables, L
225
185
}
226
186
}
227
187
} else {
228
- for (ExpressionDef operand : expression .operands ()) {
229
- captureVariables (operand , variables , capturedVariables );
230
- }
188
+ expression .nestedExpressionsStream ()
189
+ .forEach (expressionDef -> captureVariables (expressionDef , variables , capturedVariables ));
231
190
}
232
191
}
233
192
0 commit comments