1
2
3
4
5 package com.qulice.pmd.rules;
6
7 import java.util.List;
8 import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
9 import net.sourceforge.pmd.lang.java.ast.ASTBlock;
10 import net.sourceforge.pmd.lang.java.ast.ASTLoopStatement;
11 import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
12 import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess;
13 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
14 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule;
15
16
17
18
19
20 public final class UnnecessaryLocalRule extends AbstractJavaRulechainRule {
21
22 public UnnecessaryLocalRule() {
23 super(ASTVariableDeclarator.class);
24 }
25
26 @Override
27 public Object visit(
28 final ASTVariableDeclarator variable,
29 final Object data
30 ) {
31 if (variable.getInitializer() != null) {
32 final String name = variableName(variable);
33 if (!name.isEmpty()) {
34 asCtx(data).addViolation(variable, name);
35 }
36 }
37 return data;
38 }
39
40 private static boolean hasReturnOrArguments(
41 final List<ASTVariableAccess> uses
42 ) {
43 boolean result = false;
44 if (uses.size() == 1) {
45 final ASTVariableAccess use = uses.get(0);
46 final boolean loop = use.ancestors(ASTLoopStatement.class)
47 .toStream().findAny().isPresent();
48 if (!loop
49 && (use.ancestors(ASTReturnStatement.class).toStream()
50 .findAny().isPresent()
51 || use.ancestors(ASTArgumentList.class).toStream()
52 .findAny().isPresent())
53 ) {
54 result = true;
55 }
56 }
57 return result;
58 }
59
60 private static String variableName(final ASTVariableDeclarator variable) {
61 String result = "";
62 final ASTBlock block = variable.ancestors(ASTBlock.class).first();
63 if (block != null) {
64 final String name = variable.getName();
65 if (hasReturnOrArguments(
66 block.descendants(ASTVariableAccess.class)
67 .crossFindBoundaries()
68 .filter(ref -> name.equals(ref.getName()))
69 .toList()
70 )) {
71 result = name;
72 }
73 }
74 return result;
75 }
76 }