Skip to content

Commit

Permalink
Remove memoize, apply, and matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
jkschneider committed Sep 30, 2023
1 parent 9836002 commit 72383e2
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 208 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,18 @@
import org.openrewrite.Cursor;
import org.openrewrite.ExecutionContext;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.ShortenFullyQualifiedTypeReferences;
import org.openrewrite.java.cleanup.SimplifyBooleanExpressionVisitor;
import org.openrewrite.java.cleanup.UnnecessaryParenthesesVisitor;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaCoordinates;

import java.util.Arrays;
import java.util.EnumSet;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;

@SuppressWarnings("unused")
public abstract class AbstractRefasterJavaVisitor extends JavaVisitor<ExecutionContext> {

protected final <T> Supplier<T> memoize(Supplier<T> delegate) {
AtomicReference<T> value = new AtomicReference<>();
return () -> {
T val = value.get();
if (val == null) {
val = value.updateAndGet(cur -> cur == null ? Objects.requireNonNull(delegate.get()) : cur);
}
return val;
};
}

protected final JavaTemplate.Matcher matcher(Supplier<JavaTemplate> template, Cursor cursor) {
return template.get().matcher(cursor);
}

protected final J apply(Supplier<JavaTemplate> template, Cursor cursor, JavaCoordinates coordinates, Object... parameters) {
return template.get().apply(cursor, coordinates, parameters);
}

@Deprecated
// to be removed as soon as annotation processor generates required options
protected J embed(J j, Cursor cursor, ExecutionContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,24 +194,24 @@ public void visitClassDef(JCTree.JCClassDecl classDecl) {
recipe.append(" public TreeVisitor<?, ExecutionContext> getVisitor() {\n");
recipe.append(" JavaVisitor<ExecutionContext> javaVisitor = new AbstractRefasterJavaVisitor() {\n");
for (Map.Entry<String, JCTree.JCMethodDecl> entry : beforeTemplates.entrySet()) {
recipe.append(" final Supplier<JavaTemplate> ")
recipe.append(" final JavaTemplate ")
.append(entry.getKey())
.append(" = memoize(() -> Semantics.")
.append(" = Semantics.")
.append(statementType(entry.getValue()))
.append("(this, \"")
.append(entry.getKey()).append("\", ")
.append(toLambda(entry.getValue()))
.append(").build());\n");
.append(").build();\n");
}
recipe.append(" final Supplier<JavaTemplate> ")
recipe.append(" final JavaTemplate ")
.append(after)
.append(" = memoize(() -> Semantics.")
.append(" = Semantics.")
.append(statementType(descriptor.afterTemplate))
.append("(this, \"")
.append(after)
.append("\", ")
.append(toLambda(descriptor.afterTemplate))
.append(").build());\n");
.append(").build();\n");
recipe.append("\n");

List<String> lstTypes = LST_TYPE_MAP.get(getType(descriptor.beforeTemplates.get(0)));
Expand All @@ -229,7 +229,7 @@ public void visitClassDef(JCTree.JCClassDecl classDecl) {

recipe.append(" JavaTemplate.Matcher matcher;\n");
for (Map.Entry<String, JCTree.JCMethodDecl> entry : beforeTemplates.entrySet()) {
recipe.append(" if (" + "(matcher = matcher(").append(entry.getKey()).append(", getCursor())).find()").append(") {\n");
recipe.append(" if (" + "(matcher = ").append(entry.getKey()).append(".matcher(getCursor())).find()").append(") {\n");
com.sun.tools.javac.util.List<JCTree.JCVariableDecl> jcVariableDecls = entry.getValue().getParameters();
for (int i = 0; i < jcVariableDecls.size(); i++) {
JCTree.JCVariableDecl param = jcVariableDecls.get(i);
Expand All @@ -254,10 +254,10 @@ public void visitClassDef(JCTree.JCClassDecl classDecl) {
maybeRemoveImports(staticImports, entry, descriptor, recipe);

if (parameters.isEmpty()) {
recipe.append(" return embed(apply(").append(after).append(", getCursor(), elem.getCoordinates().replace()), getCursor(), ctx);\n");
recipe.append(" return embed(").append(after).append(".apply(getCursor(), elem.getCoordinates().replace()), getCursor(), ctx);\n");
} else {
recipe.append(" return embed(\n");
recipe.append(" apply(").append(after).append(", getCursor(), elem.getCoordinates().replace(), ").append(parameters).append("),\n");
recipe.append(" ").append(after).append(".apply(getCursor(), elem.getCoordinates().replace(), ").append(parameters).append("),\n");
recipe.append(" getCursor(),\n");
recipe.append(" ctx\n");
recipe.append(" );\n");
Expand Down Expand Up @@ -307,7 +307,6 @@ public void visitClassDef(JCTree.JCClassDecl classDecl) {
out.write("import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor;\n");
out.write("import org.openrewrite.java.tree.*;\n");
out.write("\n");
out.write("import java.util.function.Supplier;\n");
out.write("import java.util.*;\n");

out.write("\n");
Expand Down
32 changes: 7 additions & 25 deletions src/test/resources/refaster/MatchingRecipes.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package foo;

import org.openrewrite.ExecutionContext;
Expand All @@ -29,12 +14,10 @@
import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor;
import org.openrewrite.java.tree.*;

import java.util.function.Supplier;
import java.util.*;


public final class MatchingRecipes extends Recipe {

@Override
public String getDisplayName() {
return "Static analysis";
Expand All @@ -60,7 +43,6 @@ public List<Recipe> getRecipeList() {
@NonNullApi
public static class StringIsEmptyRecipe extends Recipe {


@Override
public String getDisplayName() {
return "Use String length comparison";
Expand All @@ -79,29 +61,29 @@ public Set<String> getTags() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
JavaVisitor<ExecutionContext> javaVisitor = new AbstractRefasterJavaVisitor() {
final Supplier<JavaTemplate> before = memoize(() -> Semantics.expression(this, "before", (@Primitive Integer i, String s) -> s.substring(i).isEmpty()).build());
final Supplier<JavaTemplate> before2 = memoize(() -> Semantics.expression(this, "before2", (@Primitive Integer i, String s) -> s.substring(i).isEmpty()).build());
final Supplier<JavaTemplate> after = memoize(() -> Semantics.expression(this, "after", (String s) -> s != null && s.length() == 0).build());
final JavaTemplate before = Semantics.expression(this, "before", (@Primitive Integer i, String s) -> s.substring(i).isEmpty()).build();
final JavaTemplate before2 = Semantics.expression(this, "before2", (@Primitive Integer i, String s) -> s.substring(i).isEmpty()).build();
final JavaTemplate after = Semantics.expression(this, "after", (String s) -> s != null && s.length() == 0).build();

@Override
public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) {
JavaTemplate.Matcher matcher;
if ((matcher = matcher(before, getCursor())).find()) {
if ((matcher = before.matcher(getCursor())).find()) {
if (new org.openrewrite.java.template.MethodInvocationMatcher().matches((Expression) matcher.parameter(1))) {
return super.visitMethodInvocation(elem, ctx);
}
return embed(
apply(after, getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
getCursor(),
ctx
);
}
if ((matcher = matcher(before2, getCursor())).find()) {
if ((matcher = before2.matcher(getCursor())).find()) {
if (!new org.openrewrite.java.template.MethodInvocationMatcher().matches((Expression) matcher.parameter(1))) {
return super.visitMethodInvocation(elem, ctx);
}
return embed(
apply(after, getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
getCursor(),
ctx
);
Expand Down
41 changes: 12 additions & 29 deletions src/test/resources/refaster/MultipleDereferencesRecipes.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package foo;

import org.openrewrite.ExecutionContext;
Expand All @@ -29,15 +14,13 @@
import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor;
import org.openrewrite.java.tree.*;

import java.util.function.Supplier;
import java.util.*;

import java.nio.file.Files;
import java.io.IOException;
import java.nio.file.Path;

public final class MultipleDereferencesRecipes extends Recipe {

@Override
public String getDisplayName() {
return "`MultipleDereferences` Refaster recipes";
Expand Down Expand Up @@ -73,15 +56,15 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
JavaVisitor<ExecutionContext> javaVisitor = new AbstractRefasterJavaVisitor() {
final Supplier<JavaTemplate> before = memoize(() -> Semantics.statement(this, "before", (java.nio.file.Path p) -> java.nio.file.Files.delete(p)).build());
final Supplier<JavaTemplate> after = memoize(() -> Semantics.statement(this, "after", (java.nio.file.Path p) -> java.nio.file.Files.delete(p)).build());
final JavaTemplate before = Semantics.statement(this, "before", (java.nio.file.Path p) -> java.nio.file.Files.delete(p)).build();
final JavaTemplate after = Semantics.statement(this, "after", (java.nio.file.Path p) -> java.nio.file.Files.delete(p)).build();

@Override
public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) {
JavaTemplate.Matcher matcher;
if ((matcher = matcher(before, getCursor())).find()) {
if ((matcher = before.matcher(getCursor())).find()) {
return embed(
apply(after, getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
getCursor(),
ctx
);
Expand Down Expand Up @@ -118,15 +101,15 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
JavaVisitor<ExecutionContext> javaVisitor = new AbstractRefasterJavaVisitor() {
final Supplier<JavaTemplate> before = memoize(() -> Semantics.expression(this, "before", (String s) -> s.isEmpty()).build());
final Supplier<JavaTemplate> after = memoize(() -> Semantics.expression(this, "after", (String s) -> s != null && s.length() == 0).build());
final JavaTemplate before = Semantics.expression(this, "before", (String s) -> s.isEmpty()).build();
final JavaTemplate after = Semantics.expression(this, "after", (String s) -> s != null && s.length() == 0).build();

@Override
public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) {
JavaTemplate.Matcher matcher;
if ((matcher = matcher(before, getCursor())).find()) {
if ((matcher = before.matcher(getCursor())).find()) {
return embed(
apply(after, getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
getCursor(),
ctx
);
Expand Down Expand Up @@ -158,14 +141,14 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
JavaVisitor<ExecutionContext> javaVisitor = new AbstractRefasterJavaVisitor() {
final Supplier<JavaTemplate> before = memoize(() -> Semantics.expression(this, "before", (Object o) -> o == o).build());
final Supplier<JavaTemplate> after = memoize(() -> Semantics.expression(this, "after", (Object o) -> true).build());
final JavaTemplate before = Semantics.expression(this, "before", (Object o) -> o == o).build();
final JavaTemplate after = Semantics.expression(this, "after", (Object o) -> true).build();

@Override
public J visitBinary(J.Binary elem, ExecutionContext ctx) {
JavaTemplate.Matcher matcher;
if ((matcher = matcher(before, getCursor())).find()) {
return embed(apply(after, getCursor(), elem.getCoordinates().replace()), getCursor(), ctx);
if ((matcher = before.matcher(getCursor())).find()) {
return embed(after.apply(getCursor(), elem.getCoordinates().replace()), getCursor(), ctx);
}
return super.visitBinary(elem, ctx);
}
Expand Down
30 changes: 7 additions & 23 deletions src/test/resources/refaster/NestedPreconditionsRecipe.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package foo;

import org.openrewrite.ExecutionContext;
Expand All @@ -29,7 +14,6 @@
import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor;
import org.openrewrite.java.tree.*;

import java.util.function.Supplier;
import java.util.*;

import java.util.LinkedHashMap;
Expand All @@ -53,25 +37,25 @@ public String getDescription() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
JavaVisitor<ExecutionContext> javaVisitor = new AbstractRefasterJavaVisitor() {
final Supplier<JavaTemplate> hashMap = memoize(() -> Semantics.expression(this, "hashMap", (@Primitive Integer size) -> new java.util.HashMap(size)).build());
final Supplier<JavaTemplate> linkedHashMap = memoize(() -> Semantics.expression(this, "linkedHashMap", (@Primitive Integer size) -> new java.util.LinkedHashMap(size)).build());
final Supplier<JavaTemplate> hashtable = memoize(() -> Semantics.expression(this, "hashtable", (@Primitive Integer size) -> new java.util.Hashtable(size)).build());
final JavaTemplate hashMap = Semantics.expression(this, "hashMap", (@Primitive Integer size) -> new java.util.HashMap(size)).build();
final JavaTemplate linkedHashMap = Semantics.expression(this, "linkedHashMap", (@Primitive Integer size) -> new java.util.LinkedHashMap(size)).build();
final JavaTemplate hashtable = Semantics.expression(this, "hashtable", (@Primitive Integer size) -> new java.util.Hashtable(size)).build();

@Override
public J visitExpression(Expression elem, ExecutionContext ctx) {
JavaTemplate.Matcher matcher;
if ((matcher = matcher(hashMap, getCursor())).find()) {
if ((matcher = hashMap.matcher(getCursor())).find()) {
maybeRemoveImport("java.util.HashMap");
return embed(
apply(hashtable, getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
hashtable.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
getCursor(),
ctx
);
}
if ((matcher = matcher(linkedHashMap, getCursor())).find()) {
if ((matcher = linkedHashMap.matcher(getCursor())).find()) {
maybeRemoveImport("java.util.LinkedHashMap");
return embed(
apply(hashtable, getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
hashtable.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)),
getCursor(),
ctx
);
Expand Down
Loading

0 comments on commit 72383e2

Please sign in to comment.