dev.youshallnotpass.inspections.setterfree.setters.SetterViolations Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-inspections Show documentation
Show all versions of java-inspections Show documentation
Java inspections library for youshallnotpass
The newest version!
package dev.youshallnotpass.inspections.setterfree.setters;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.body.TypeDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.AssignExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.Statement;
import org.cactoos.BiFunc;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Applying to methods by pattern:
* non private, method with only one parameter and only one statement
* (exclusive return statements) - assign statement, which consists of class
* field access target and parameter name value.
*/
public final class SetterViolations implements BiFunc, List> {
@Override
public List apply(
final CompilationUnit unit,
final TypeDeclaration> root
) {
final List setters = new ArrayList<>();
final List declarations = unit.findAll(ClassOrInterfaceDeclaration.class);
for (final ClassOrInterfaceDeclaration declaration : declarations) {
final List classFields = new ArrayList<>();
final List classMethods = new ArrayList<>();
for (final Node childNode : declaration.getChildNodes()) {
if (childNode instanceof FieldDeclaration) {
final FieldDeclaration field = (FieldDeclaration) childNode;
if (!field.isFinal()) {
classFields.addAll(field.getVariables());
}
}
if (childNode instanceof MethodDeclaration) {
final MethodDeclaration method = (MethodDeclaration) childNode;
classMethods.add(method);
}
}
for (final MethodDeclaration method : classMethods) {
final boolean isPrivate = method.isPrivate();
final NodeList parameters = method.getParameters();
final Optional assignExprOpt = method.getBody()
.map(BlockStmt::getStatements)
.map((final List statements) -> {
return statements.stream()
.filter((final Statement statement) -> !statement.isReturnStmt())
.collect(Collectors.toList());
})
.filter((final List statements) -> statements.size() == 1)
.map((final List statements) -> statements.get(0))
.filter(Statement::isExpressionStmt)
.map((final Statement statement) -> statement.asExpressionStmt().getExpression())
.filter(Expression::isAssignExpr)
.map(Expression::asAssignExpr);
if (!isPrivate && parameters.size() == 1 && assignExprOpt.isPresent()) {
final Parameter methodArg = parameters.get(0);
final AssignExpr assignExpr = assignExprOpt.get();
final Expression target = assignExpr.getTarget();
final Expression value = assignExpr.getValue();
if (value.isNameExpr() && value.asNameExpr().getNameAsString().equals(methodArg.getNameAsString())) {
if (target.isFieldAccessExpr()) {
final FieldAccessExpr fieldAccessExpr = target.asFieldAccessExpr();
final Expression scope = fieldAccessExpr.getScope();
if (scope.isThisExpr()) {
final String fieldName = fieldAccessExpr.getNameAsString();
for (final VariableDeclarator classField : classFields) {
if (classField.getNameAsString().equals(fieldName)) {
setters.add(new JavaSetter(method, root));
}
}
}
} else if (target.isNameExpr()) {
final String fieldName = target.asNameExpr().getNameAsString();
for (final VariableDeclarator classField : classFields) {
if (classField.getNameAsString().equals(fieldName)) {
setters.add(new JavaSetter(method, root));
}
}
}
}
}
}
}
return setters;
}
}