io.slugstack.rewritejavarecipes.EncapsulateDataVisitor Maven / Gradle / Ivy
Show all versions of rewrite-java-recipes Show documentation
package io.slugstack.rewritejavarecipes;
import org.openrewrite.Tree;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.J.Modifier;
import org.openrewrite.java.tree.Space;
import org.openrewrite.java.tree.Statement;
import org.openrewrite.marker.Markers;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static io.slugstack.rewritejavarecipes.internal.util.TreeUtils.whenType;
public class EncapsulateDataVisitor extends JavaIsoVisitor
{
@Override
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P p) {
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, p);
if (shouldRefactor(cd)) {
var newStatements = cd.getBody().getStatements().stream()
.map(mf -> whenType(J.VariableDeclarations.class, mf).filter(this::shouldRefactor).map(fd -> {
var privatized = new J.Modifier(Tree.randomId(), Space.EMPTY, Markers.EMPTY, J.Modifier.Type.Private, Collections.emptyList());
var mods = ListUtils.map(fd.getModifiers(), m -> m.getType() == J.Modifier.Type.Public ? privatized : m);
var ffd = fd.withModifiers(mods);
return (Statement) ffd;// mf.withElem(ffd); // todo
}).orElse(mf)).collect(Collectors.toList());
// only generate a setter if the field is mutable
// i.e., if a field is final, don't bother generating a setter
getRefactorableFields(cd).forEach(f -> {
var fieldName = f.getVariables().get(0).getSimpleName();
var declaringClass = cd.getType().getFullyQualifiedName();
doAfterVisit(new GenerateGetter(fieldName));
doAfterVisit(new FieldAccessToGetter(declaringClass, fieldName));
if (!(f.hasModifier(Modifier.Type.Final))) {
doAfterVisit(new GenerateSetter(fieldName));
doAfterVisit(new FieldAccessToSetter(declaringClass, fieldName));
}
});
return cd.withBody(cd.getBody().withStatements(newStatements));
}
return cd;
}
private List getRefactorableFields(J.ClassDeclaration cd) {
return cd.getBody().getStatements().stream()
.filter(stat -> whenType(J.VariableDeclarations.class, stat).map(this::shouldRefactor).orElse(false))
.map(J.VariableDeclarations.class::cast).collect(Collectors.toList());
}
private boolean shouldRefactor(J.ClassDeclaration cd) {
return cd.getBody().getStatements().stream()
.anyMatch(mv -> whenType(J.VariableDeclarations.class, mv).map(this::shouldRefactor).orElse(false));
}
private boolean shouldRefactor(J.VariableDeclarations mrf) {
return mrf.hasModifier(Modifier.Type.Public)
&& !(mrf.hasModifier(Modifier.Type.Final) && mrf.hasModifier(Modifier.Type.Static));
}
}