Don't report NonFinalStaticField findings for fields modified in `@Be… · google/error-prone@d78dd6d (original) (raw)

`@@ -38,15 +38,16 @@

`

38

38

`import com.google.errorprone.bugpatterns.BugChecker.VariableTreeMatcher;

`

39

39

`import com.google.errorprone.fixes.SuggestedFix;

`

40

40

`import com.google.errorprone.matchers.Description;

`

``

41

`+

import com.google.errorprone.util.ASTHelpers;

`

41

42

`import com.sun.source.tree.AssignmentTree;

`

42

43

`import com.sun.source.tree.CompoundAssignmentTree;

`

``

44

`+

import com.sun.source.tree.MethodTree;

`

43

45

`import com.sun.source.tree.Tree.Kind;

`

44

46

`import com.sun.source.tree.UnaryTree;

`

45

47

`import com.sun.source.tree.VariableTree;

`

46

48

`import com.sun.source.util.TreeScanner;

`

47

49

`import com.sun.tools.javac.code.Symbol.VarSymbol;

`

48

50

`import java.util.Objects;

`

49

``

`-

import java.util.concurrent.atomic.AtomicBoolean;

`

50

51

`import javax.lang.model.element.Modifier;

`

51

52

``

52

53

`/** A BugPattern; see the summary. */

`

`@@ -71,7 +72,11 @@ public Description matchVariable(VariableTree tree, VisitorState state) {

`

71

72

` .anyMatch(anno -> hasDirectAnnotationWithSimpleName(tree, anno))) {

`

72

73

`return NO_MATCH;

`

73

74

` }

`

74

``

`-

if (!canBeRemoved(symbol, state) || isEverMutatedInSameCompilationUnit(symbol, state)) {

`

``

75

`+

IsMutated everMutatedInSameCompilationUnit = isEverMutatedInSameCompilationUnit(symbol, state);

`

``

76

`+

if (everMutatedInSameCompilationUnit == IsMutated.IN_BEFORE_METHOD) {

`

``

77

`+

return NO_MATCH;

`

``

78

`+

}

`

``

79

`+

if (!canBeRemoved(symbol, state) || everMutatedInSameCompilationUnit == IsMutated.TRUE) {

`

75

80

`return describeMatch(tree);

`

76

81

` }

`

77

82

`return describeMatch(

`

`@@ -117,45 +122,77 @@ private static String getDefaultInitializer(VariableTree tree, VisitorState stat

`

117

122

`return "null";

`

118

123

` }

`

119

124

``

120

``

`-

private static boolean isEverMutatedInSameCompilationUnit(VarSymbol symbol, VisitorState state) {

`

121

``

`-

AtomicBoolean seen = new AtomicBoolean(false);

`

122

``

`-

new TreeScanner<Void, Void>() {

`

123

``

`-

@Override

`

124

``

`-

public Void visitAssignment(AssignmentTree tree, Void unused) {

`

125

``

`-

if (Objects.equals(getSymbol(tree.getVariable()), symbol)) {

`

126

``

`-

seen.set(true);

`

127

``

`-

}

`

128

``

`-

return super.visitAssignment(tree, null);

`

129

``

`-

}

`

130

``

-

131

``

`-

@Override

`

132

``

`-

public Void visitCompoundAssignment(CompoundAssignmentTree tree, Void unused) {

`

133

``

`-

if (Objects.equals(getSymbol(tree.getVariable()), symbol)) {

`

134

``

`-

seen.set(true);

`

135

``

`-

}

`

136

``

`-

return super.visitCompoundAssignment(tree, null);

`

137

``

`-

}

`

138

``

-

139

``

`-

@Override

`

140

``

`-

public Void visitUnary(UnaryTree tree, Void unused) {

`

141

``

`-

if (Objects.equals(getSymbol(tree.getExpression()), symbol) && isMutating(tree.getKind())) {

`

142

``

`-

seen.set(true);

`

143

``

`-

}

`

144

``

`-

return super.visitUnary(tree, null);

`

145

``

`-

}

`

146

``

-

147

``

`-

private boolean isMutating(Kind kind) {

`

148

``

`-

switch (kind) {

`

149

``

`-

case POSTFIX_DECREMENT:

`

150

``

`-

case POSTFIX_INCREMENT:

`

151

``

`-

case PREFIX_DECREMENT:

`

152

``

`-

case PREFIX_INCREMENT:

`

153

``

`-

return true;

`

154

``

`-

default:

`

155

``

`-

return false;

`

156

``

`-

}

`

157

``

`-

}

`

158

``

`-

}.scan(state.getPath().getCompilationUnit(), null);

`

159

``

`-

return seen.get();

`

``

125

`+

enum IsMutated {

`

``

126

`+

TRUE,

`

``

127

`+

FALSE,

`

``

128

`+

IN_BEFORE_METHOD

`

``

129

`+

}

`

``

130

+

``

131

`+

private static IsMutated isEverMutatedInSameCompilationUnit(

`

``

132

`+

VarSymbol symbol, VisitorState state) {

`

``

133

`+

var scanner =

`

``

134

`+

new TreeScanner<Void, Void>() {

`

``

135

`+

IsMutated isMutated = IsMutated.FALSE;

`

``

136

+

``

137

`+

boolean inBeforeMethod = false;

`

``

138

+

``

139

`+

@Override

`

``

140

`+

public Void visitAssignment(AssignmentTree tree, Void unused) {

`

``

141

`+

if (Objects.equals(getSymbol(tree.getVariable()), symbol)) {

`

``

142

`+

isMutated();

`

``

143

`+

}

`

``

144

`+

return super.visitAssignment(tree, null);

`

``

145

`+

}

`

``

146

+

``

147

`+

@Override

`

``

148

`+

public Void visitCompoundAssignment(CompoundAssignmentTree tree, Void unused) {

`

``

149

`+

if (Objects.equals(getSymbol(tree.getVariable()), symbol)) {

`

``

150

`+

isMutated();

`

``

151

`+

}

`

``

152

`+

return super.visitCompoundAssignment(tree, null);

`

``

153

`+

}

`

``

154

+

``

155

`+

@Override

`

``

156

`+

public Void visitUnary(UnaryTree tree, Void unused) {

`

``

157

`+

if (Objects.equals(getSymbol(tree.getExpression()), symbol)

`

``

158

`+

&& isMutating(tree.getKind())) {

`

``

159

`+

isMutated();

`

``

160

`+

}

`

``

161

`+

return super.visitUnary(tree, null);

`

``

162

`+

}

`

``

163

+

``

164

`+

private void isMutated() {

`

``

165

`+

if (inBeforeMethod) {

`

``

166

`+

isMutated = IsMutated.IN_BEFORE_METHOD;

`

``

167

`+

} else if (isMutated.equals(IsMutated.FALSE)) {

`

``

168

`+

isMutated = IsMutated.TRUE;

`

``

169

`+

}

`

``

170

`+

}

`

``

171

+

``

172

`+

private boolean isMutating(Kind kind) {

`

``

173

`+

switch (kind) {

`

``

174

`+

case POSTFIX_DECREMENT:

`

``

175

`+

case POSTFIX_INCREMENT:

`

``

176

`+

case PREFIX_DECREMENT:

`

``

177

`+

case PREFIX_INCREMENT:

`

``

178

`+

return true;

`

``

179

`+

default:

`

``

180

`+

return false;

`

``

181

`+

}

`

``

182

`+

}

`

``

183

+

``

184

`+

@Override

`

``

185

`+

public Void visitMethod(MethodTree tree, Void unused) {

`

``

186

`+

boolean prev = inBeforeMethod;

`

``

187

`+

try {

`

``

188

`+

inBeforeMethod |= ASTHelpers.hasAnnotation(tree, "org.junit.BeforeClass", state);

`

``

189

`+

return super.visitMethod(tree, null);

`

``

190

`+

} finally {

`

``

191

`+

inBeforeMethod = prev;

`

``

192

`+

}

`

``

193

`+

}

`

``

194

`+

};

`

``

195

`+

scanner.scan(state.getPath().getCompilationUnit(), null);

`

``

196

`+

return scanner.isMutated;

`

160

197

` }

`

161

198

`}

`