16
16
package org .openrewrite .java ;
17
17
18
18
import org .junit .jupiter .api .Test ;
19
+ import org .junitpioneer .jupiter .ExpectedToFail ;
19
20
import org .openrewrite .DocumentExample ;
20
21
import org .openrewrite .ExecutionContext ;
21
22
import org .openrewrite .java .tree .Expression ;
@@ -50,7 +51,7 @@ void genericTypes() {
50
51
rewriteRun (
51
52
spec -> spec .recipe (toRecipe (() -> new JavaVisitor <>() {
52
53
@ Override
53
- public J visitVariableDeclarations (J .VariableDeclarations multiVariable , ExecutionContext executionContext ) {
54
+ public J visitVariableDeclarations (J .VariableDeclarations multiVariable , ExecutionContext ctx ) {
54
55
J .VariableDeclarations .NamedVariable variable = multiVariable .getVariables ().getFirst ();
55
56
if ("o" .equals (variable .getSimpleName ())) {
56
57
Expression exp = Objects .requireNonNull (variable .getInitializer ());
@@ -64,7 +65,7 @@ public J visitVariableDeclarations(J.VariableDeclarations multiVariable, Executi
64
65
assertThat (res4 .getMethodType ()).isNotNull ();
65
66
return res3 ;
66
67
}
67
- return super .visitVariableDeclarations (multiVariable , executionContext );
68
+ return super .visitVariableDeclarations (multiVariable , ctx );
68
69
}
69
70
})),
70
71
java (
@@ -134,8 +135,8 @@ void recursiveType() {
134
135
rewriteRun (
135
136
spec -> spec .recipe (toRecipe (() -> new JavaIsoVisitor <>() {
136
137
@ Override
137
- public J .MethodInvocation visitMethodInvocation (J .MethodInvocation method , ExecutionContext executionContext ) {
138
- return template .matches (getCursor ()) ? SearchResult .found (method ) : super .visitMethodInvocation (method , executionContext );
138
+ public J .MethodInvocation visitMethodInvocation (J .MethodInvocation method , ExecutionContext ctx ) {
139
+ return template .matches (getCursor ()) ? SearchResult .found (method ) : super .visitMethodInvocation (method , ctx );
139
140
}
140
141
})),
141
142
java (
@@ -165,6 +166,88 @@ void test() {
165
166
);
166
167
}
167
168
169
+ @ Test
170
+ void setsDifferenceMultimapRecipe () {
171
+ rewriteRun (
172
+ spec -> spec .parser (JavaParser .fromJavaVersion ().classpath ("guava" ))
173
+ .recipe (toRecipe (() -> new JavaIsoVisitor <>() {
174
+ final JavaTemplate template = JavaTemplate .builder ("#{set:any(java.util.Set<T>)}.stream().filter(java.util.function.Predicate.not(#{multimap:any(com.google.common.collect.Multimap<K, V>)}::containsKey)).collect(com.google.common.collect.ImmutableSet.toImmutableSet())" )
175
+ .bindType ("com.google.common.collect.ImmutableSet<T>" )
176
+ .genericTypes ("T" , "K" , "V" )
177
+ .javaParser (JavaParser .fromJavaVersion ().classpath ("guava" ))
178
+ .build ();
179
+
180
+ @ Override
181
+ public J .MethodInvocation visitMethodInvocation (J .MethodInvocation method , ExecutionContext ctx ) {
182
+ return template .matches (getCursor ()) ? SearchResult .found (method ) : super .visitMethodInvocation (method , ctx );
183
+ }
184
+ })),
185
+ java (
186
+ """
187
+ import com.google.common.collect.ImmutableSet;
188
+ import com.google.common.collect.ImmutableSetMultimap;
189
+
190
+ import java.util.function.Predicate;
191
+
192
+ class Test {
193
+ void test() {
194
+ ImmutableSet.of(1).stream().filter(Predicate.not(ImmutableSetMultimap.of(2, 3)::containsKey)).collect(ImmutableSet.toImmutableSet());
195
+ }
196
+ }
197
+ """ ,
198
+ """
199
+ import com.google.common.collect.ImmutableSet;
200
+ import com.google.common.collect.ImmutableSetMultimap;
201
+
202
+ import java.util.function.Predicate;
203
+
204
+ class Test {
205
+ void test() {
206
+ /*~~>*/ImmutableSet.of(1).stream().filter(Predicate.not(ImmutableSetMultimap.of(2, 3)::containsKey)).collect(ImmutableSet.toImmutableSet());
207
+ }
208
+ }
209
+ """
210
+ )
211
+ );
212
+ }
213
+
214
+ @ Test
215
+ void emptyStreamRecipe () {
216
+ rewriteRun (
217
+ spec -> spec .recipe (toRecipe (() -> new JavaIsoVisitor <>() {
218
+ final JavaTemplate template = JavaTemplate .builder ("java.util.stream.Stream.of()" )
219
+ .bindType ("java.util.stream.Stream<T>" )
220
+ .genericTypes ("T" )
221
+ .build ();
222
+
223
+ @ Override
224
+ public J .MethodInvocation visitMethodInvocation (J .MethodInvocation method , ExecutionContext ctx ) {
225
+ return template .matches (getCursor ()) ? SearchResult .found (method ) : super .visitMethodInvocation (method , ctx );
226
+ }
227
+ })),
228
+ java (
229
+ """
230
+ import java.util.stream.Stream;
231
+
232
+ class Test {
233
+ Stream<String> test() {
234
+ return Stream.of();
235
+ }
236
+ }
237
+ """ ,
238
+ """
239
+ import java.util.stream.Stream;
240
+
241
+ class Test {
242
+ Stream<String> test() {
243
+ return /*~~>*/Stream.of();
244
+ }
245
+ }
246
+ """
247
+ )
248
+ );
249
+ }
250
+
168
251
@ Test
169
252
void methodModifiersMismatch () {
170
253
rewriteRun (
@@ -174,8 +257,8 @@ void methodModifiersMismatch() {
174
257
.build ();
175
258
176
259
@ Override
177
- public J .MethodInvocation visitMethodInvocation (J .MethodInvocation method , ExecutionContext executionContext ) {
178
- return template .matches (getCursor ()) ? SearchResult .found (method ) : super .visitMethodInvocation (method , executionContext );
260
+ public J .MethodInvocation visitMethodInvocation (J .MethodInvocation method , ExecutionContext ctx ) {
261
+ return template .matches (getCursor ()) ? SearchResult .found (method ) : super .visitMethodInvocation (method , ctx );
179
262
}
180
263
})),
181
264
java (
@@ -208,4 +291,175 @@ Stream<Integer> test() {
208
291
)
209
292
);
210
293
}
294
+
295
+ @ Test
296
+ void replaceMemberReferenceToLambda () {
297
+ //noinspection Convert2MethodRef
298
+ rewriteRun (
299
+ spec -> spec
300
+ .expectedCyclesThatMakeChanges (1 ).cycles (1 )
301
+ .recipe (toRecipe (() -> new JavaVisitor <>() {
302
+ final JavaTemplate refTemplate = JavaTemplate .builder ("T::toString" )
303
+ .bindType ("java.util.function.Function<T, String>" )
304
+ .genericTypes ("T" )
305
+ .build ();
306
+ final JavaTemplate lambdaTemplate = JavaTemplate .builder ("e -> e.toString()" )
307
+ .bindType ("java.util.function.Function<T, String>" )
308
+ .genericTypes ("T" )
309
+ .build ();
310
+
311
+ @ Override
312
+ public J visitMemberReference (J .MemberReference memberRef , ExecutionContext ctx ) {
313
+ JavaTemplate .Matcher matcher = refTemplate .matcher (getCursor ());
314
+ if (matcher .find ()) {
315
+ return lambdaTemplate .apply (getCursor (), memberRef .getCoordinates ().replace (), matcher .getMatchResult ().getMatchedParameters ().toArray ());
316
+ } else {
317
+ return super .visitMemberReference (memberRef , ctx );
318
+ }
319
+ }
320
+ })),
321
+ //language=java
322
+ java (
323
+ """
324
+ import java.util.function.Function;
325
+
326
+ class Foo {
327
+ void test() {
328
+ test(Object::toString);
329
+ }
330
+
331
+ void test(Function<Object, String> fn) {
332
+ }
333
+ }
334
+ """ ,
335
+ """
336
+ import java.util.function.Function;
337
+
338
+ class Foo {
339
+ void test() {
340
+ test(e -> e.toString());
341
+ }
342
+
343
+ void test(Function<Object, String> fn) {
344
+ }
345
+ }
346
+ """
347
+ )
348
+ );
349
+ }
350
+
351
+ @ Test
352
+ @ ExpectedToFail
353
+ void replaceLambdaToMemberReference () {
354
+ //noinspection Convert2MethodRef
355
+ rewriteRun (
356
+ spec -> spec
357
+ .expectedCyclesThatMakeChanges (1 ).cycles (1 )
358
+ .recipe (toRecipe (() -> new JavaVisitor <>() {
359
+ final JavaTemplate lambdaTemplate = JavaTemplate .builder ("e -> e.toString()" )
360
+ .bindType ("java.util.function.Function<T, String>" )
361
+ .genericTypes ("T" )
362
+ .build ();
363
+ final JavaTemplate refTemplate = JavaTemplate .builder ("T::toString" )
364
+ .bindType ("java.util.function.Function<T, String>" )
365
+ .genericTypes ("T" )
366
+ .build ();
367
+
368
+ @ Override
369
+ public J visitLambda (J .Lambda lambda , ExecutionContext ctx ) {
370
+ JavaTemplate .Matcher matcher = lambdaTemplate .matcher (getCursor ());
371
+ if (matcher .find ()) {
372
+ return refTemplate .apply (getCursor (), lambda .getCoordinates ().replace (), matcher .getMatchResult ().getMatchedParameters ().toArray ());
373
+ } else {
374
+ return super .visitLambda (lambda , ctx );
375
+ }
376
+ }
377
+ })),
378
+ //language=java
379
+ java (
380
+ """
381
+ import java.util.function.Function;
382
+
383
+ class Foo {
384
+ void test() {
385
+ test(e -> e.toString());
386
+ }
387
+
388
+ void test(Function<Object, String> fn) {
389
+ }
390
+ }
391
+ """ ,
392
+ """
393
+ import java.util.function.Function;
394
+
395
+ class Foo {
396
+ void test() {
397
+ test(Object::toString);
398
+ }
399
+
400
+ void test(Function<Object, String> fn) {
401
+ }
402
+ }
403
+ """
404
+ )
405
+ );
406
+ }
407
+
408
+ @ Test
409
+ void memberReferenceToLambda () {
410
+ //noinspection Convert2MethodRef
411
+ rewriteRun (
412
+ spec -> spec
413
+ .expectedCyclesThatMakeChanges (1 ).cycles (1 )
414
+ .recipe (toRecipe (() -> new JavaVisitor <>() {
415
+ final JavaTemplate refTemplate = JavaTemplate .builder ("#{any(java.util.Set<T>)}::contains" )
416
+ .bindType ("java.util.function.Predicate<T>" )
417
+ .genericTypes ("T" )
418
+ .build ();
419
+ final JavaTemplate lambdaTemplate = JavaTemplate .builder ("e -> #{any(java.util.Set<T>)}.contains(e)" )
420
+ .bindType ("java.util.function.Predicate<T>" )
421
+ .genericTypes ("T" )
422
+ .build ();
423
+
424
+ @ Override
425
+ public J visitMemberReference (J .MemberReference memberRef , ExecutionContext ctx ) {
426
+ JavaTemplate .Matcher matcher = refTemplate .matcher (getCursor ());
427
+ if (matcher .find ()) {
428
+ return lambdaTemplate .apply (getCursor (), memberRef .getCoordinates ().replace (), matcher .getMatchResult ().getMatchedParameters ().toArray ());
429
+ } else {
430
+ return super .visitMemberReference (memberRef , ctx );
431
+ }
432
+ }
433
+ })),
434
+ //language=java
435
+ java (
436
+ """
437
+ import java.util.*;
438
+ import java.util.function.*;
439
+
440
+ class Foo {
441
+ List<Integer> test(List<Integer> list) {
442
+ Set<Integer> set = Set.of(1, 2, 3);
443
+ return list.stream()
444
+ .filter(set::contains)
445
+ .toList();
446
+ }
447
+ }
448
+ """ ,
449
+ """
450
+ import java.util.*;
451
+ import java.util.function.*;
452
+
453
+ class Foo {
454
+ List<Integer> test(List<Integer> list) {
455
+ Set<Integer> set = Set.of(1, 2, 3);
456
+ return list.stream()
457
+ .filter(e -> set.contains(e))
458
+ .toList();
459
+ }
460
+ }
461
+ """
462
+ )
463
+ );
464
+ }
211
465
}
0 commit comments