-
Notifications
You must be signed in to change notification settings - Fork 434
Add expression type in JavaTemplate #5384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
447e28a
e761b16
9557062
b32e1fc
58be75b
3553a0d
7d640cc
4103683
8431a70
f67075d
cd7ccf0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
package org.openrewrite.java; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.junitpioneer.jupiter.ExpectedToFail; | ||
import org.openrewrite.ExecutionContext; | ||
import org.openrewrite.java.tree.Expression; | ||
import org.openrewrite.java.tree.J; | ||
|
@@ -163,6 +164,88 @@ void test() { | |
); | ||
} | ||
|
||
@Test | ||
void setsDifferenceMultimapRecipe() { | ||
rewriteRun( | ||
spec -> spec.parser(JavaParser.fromJavaVersion().classpath("guava")) | ||
.recipe(toRecipe(() -> new JavaIsoVisitor<>() { | ||
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())") | ||
.bindType("com.google.common.collect.ImmutableSet<T>") | ||
.genericTypes("T", "K", "V") | ||
.javaParser(JavaParser.fromJavaVersion().classpath("guava")) | ||
.build(); | ||
|
||
@Override | ||
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) { | ||
return template.matches(getCursor()) ? SearchResult.found(method) : super.visitMethodInvocation(method, executionContext); | ||
} | ||
})), | ||
java( | ||
""" | ||
import com.google.common.collect.ImmutableSet; | ||
import com.google.common.collect.ImmutableSetMultimap; | ||
|
||
import java.util.function.Predicate; | ||
|
||
class Test { | ||
void test() { | ||
ImmutableSet.of(1).stream().filter(Predicate.not(ImmutableSetMultimap.of(2, 3)::containsKey)).collect(ImmutableSet.toImmutableSet()); | ||
} | ||
} | ||
""", | ||
""" | ||
import com.google.common.collect.ImmutableSet; | ||
import com.google.common.collect.ImmutableSetMultimap; | ||
|
||
import java.util.function.Predicate; | ||
|
||
class Test { | ||
void test() { | ||
/*~~>*/ImmutableSet.of(1).stream().filter(Predicate.not(ImmutableSetMultimap.of(2, 3)::containsKey)).collect(ImmutableSet.toImmutableSet()); | ||
} | ||
} | ||
""" | ||
) | ||
); | ||
} | ||
|
||
@Test | ||
void emptyStreamRecipe() { | ||
rewriteRun( | ||
spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() { | ||
final JavaTemplate template = JavaTemplate.builder("java.util.stream.Stream.of()") | ||
.bindType("java.util.stream.Stream<T>") | ||
.genericTypes("T") | ||
.build(); | ||
|
||
@Override | ||
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) { | ||
return template.matches(getCursor()) ? SearchResult.found(method) : super.visitMethodInvocation(method, executionContext); | ||
} | ||
})), | ||
java( | ||
""" | ||
import java.util.stream.Stream; | ||
|
||
class Test { | ||
Stream<String> test() { | ||
return Stream.of(); | ||
} | ||
} | ||
""", | ||
""" | ||
import java.util.stream.Stream; | ||
|
||
class Test { | ||
Stream<String> test() { | ||
return /*~~>*/Stream.of(); | ||
} | ||
} | ||
""" | ||
) | ||
); | ||
} | ||
|
||
@Test | ||
void methodModifiersMismatch() { | ||
rewriteRun( | ||
|
@@ -206,4 +289,118 @@ Stream<Integer> test() { | |
) | ||
); | ||
} | ||
|
||
@Test | ||
@ExpectedToFail | ||
void replaceMemberReferenceToLambda() { | ||
//noinspection Convert2MethodRef | ||
rewriteRun( | ||
spec -> spec | ||
.expectedCyclesThatMakeChanges(1).cycles(1) | ||
.recipe(toRecipe(() -> new JavaVisitor<>() { | ||
final JavaTemplate refTemplate = JavaTemplate.builder("T::toString") | ||
.bindType("java.util.function.Function<T, String>") | ||
.genericTypes("T") | ||
.build(); | ||
final JavaTemplate lambdaTemplate = JavaTemplate.builder("e -> e.toString()") | ||
.bindType("java.util.function.Function<T, String>") | ||
.genericTypes("T") | ||
.build(); | ||
|
||
@Override | ||
public J visitMemberReference(J.MemberReference memberRef, ExecutionContext executionContext) { | ||
JavaTemplate.Matcher matcher = refTemplate.matcher(getCursor()); | ||
if (matcher.find()) { | ||
return lambdaTemplate.apply(getCursor(), memberRef.getCoordinates().replace(), matcher.getMatchResult().getMatchedParameters().toArray()); | ||
} else { | ||
return super.visitMemberReference(memberRef, executionContext); | ||
} | ||
} | ||
})), | ||
//language=java | ||
java( | ||
""" | ||
import java.util.function.Function; | ||
|
||
class Foo { | ||
void test() { | ||
test(Object::toString); | ||
} | ||
|
||
void test(Function<Object, String> fn) { | ||
} | ||
} | ||
""", | ||
""" | ||
import java.util.function.Function; | ||
|
||
class Foo { | ||
void test() { | ||
test(e -> e.toString()); | ||
} | ||
|
||
void test(Function<Object, String> fn) { | ||
} | ||
} | ||
""" | ||
) | ||
); | ||
} | ||
|
||
@Test | ||
@ExpectedToFail | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one it's more to showcase a scenario we are not handling, even if the apply had arguments, T is not really a parameter, and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could have some other kind of argument. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've considered doing exactly this before, but I didn't yet see a use case for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have try this templates in error-prone refaster and they work. But I haven't found any use on the Picnic tests. static final class RefToLambda<T> {
@BeforeTemplate
Function<T, String> before() {
return T::toString;
}
@AfterTemplate
Function<T, String> after() {
return e -> e.toString();
}
}
static final class LambdaToRef<T> {
@BeforeTemplate
Function<T, String> before() {
return e -> e.toString();
}
@AfterTemplate
Function<T, String> after() {
return T::toString;
}
}
---
ImmutableSet<Function<Object, String>> testRefToLambda() {
return ImmutableSet.of(
Object::toString);
}
ImmutableSet<Function<Object, String>> testLambdaToRef() {
return ImmutableSet.of(
e -> e.toString());
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remember the use case now. Having a |
||
void replaceLambdaToMemberReference() { | ||
//noinspection Convert2MethodRef | ||
rewriteRun( | ||
spec -> spec | ||
.expectedCyclesThatMakeChanges(1).cycles(1) | ||
.recipe(toRecipe(() -> new JavaVisitor<>() { | ||
final JavaTemplate lambdaTemplate = JavaTemplate.builder("e -> e.toString()") | ||
.bindType("java.util.function.Function<T, String>") | ||
.genericTypes("T") | ||
.build(); | ||
final JavaTemplate refTemplate = JavaTemplate.builder("T::toString") | ||
.bindType("java.util.function.Function<T, String>") | ||
.genericTypes("T") | ||
.build(); | ||
|
||
@Override | ||
public J visitLambda(J.Lambda lambda, ExecutionContext executionContext) { | ||
JavaTemplate.Matcher matcher = lambdaTemplate.matcher(getCursor()); | ||
if (matcher.find()) { | ||
return refTemplate.apply(getCursor(), lambda.getCoordinates().replace(), matcher.getMatchResult().getMatchedParameters().toArray()); | ||
} else { | ||
return super.visitLambda(lambda, executionContext); | ||
} | ||
} | ||
})), | ||
//language=java | ||
java( | ||
""" | ||
import java.util.function.Function; | ||
|
||
class Foo { | ||
void test() { | ||
test(e -> e.toString()); | ||
} | ||
|
||
void test(Function<Object, String> fn) { | ||
} | ||
} | ||
""", | ||
""" | ||
import java.util.function.Function; | ||
|
||
class Foo { | ||
void test() { | ||
test(Object::toString); | ||
} | ||
|
||
void test(Function<Object, String> fn) { | ||
} | ||
} | ||
""" | ||
) | ||
); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.