Skip to content

Commit dc3bed1

Browse files
committed
Move methods to util classes
1 parent 9e8c582 commit dc3bed1

File tree

3 files changed

+81
-35
lines changed

3 files changed

+81
-35
lines changed

spotbugs/src/main/java/edu/umd/cs/findbugs/detect/ResourceInMultipleThreadsDetector.java

+6-35
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
package edu.umd.cs.findbugs.detect;
2020

21-
import java.util.Arrays;
2221
import java.util.HashMap;
2322
import java.util.HashSet;
2423
import java.util.Map;
@@ -37,16 +36,15 @@
3736
import edu.umd.cs.findbugs.BugInstance;
3837
import edu.umd.cs.findbugs.BugReporter;
3938
import edu.umd.cs.findbugs.OpcodeStack;
40-
import edu.umd.cs.findbugs.ba.ClassMember;
4139
import edu.umd.cs.findbugs.ba.XField;
4240
import edu.umd.cs.findbugs.ba.XMethod;
4341
import edu.umd.cs.findbugs.bcel.BCELUtil;
4442
import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;
4543
import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
46-
import edu.umd.cs.findbugs.classfile.Global;
4744
import edu.umd.cs.findbugs.classfile.MethodDescriptor;
48-
import edu.umd.cs.findbugs.classfile.engine.bcel.FinallyDuplicatesInfoFactory;
4945
import edu.umd.cs.findbugs.util.BootstrapMethodsUtil;
46+
import edu.umd.cs.findbugs.util.CollectionAnalysis;
47+
import edu.umd.cs.findbugs.util.MethodAnalysis;
5048
import edu.umd.cs.findbugs.util.MutableClasses;
5149

5250
public class ResourceInMultipleThreadsDetector extends OpcodeStackDetector {
@@ -146,17 +144,18 @@ private Optional<MethodDescriptor> getMethodFromBootstrap(JavaClass javaClass, C
146144

147145
private void collectFieldsUsedInThreads(int seen) throws CheckedAnalysisException {
148146
if ((seen == Const.PUTFIELD || seen == Const.PUTSTATIC) && getStack().getStackDepth() > 0
149-
&& !isDuplicatedLocation(getMethodDescriptor(), getPC())
147+
&& !MethodAnalysis.isDuplicatedLocation(getMethodDescriptor(), getPC())
150148
&& methodsUsedInThreads.contains(getMethodDescriptor())) {
151149
OpcodeStack.Item stackItem = getStack().getStackItem(0);
152-
if (stackItem.getReturnValueOf() != null && isSynchronizedCollection(stackItem.getReturnValueOf())) {
150+
if (stackItem.getReturnValueOf() != null && CollectionAnalysis.isSynchronizedCollection(stackItem.getReturnValueOf())) {
153151
synchronizedCollectionTypedFields.add(getXFieldOperand());
154152
} else if (!isAtomicTypedField(getXFieldOperand())
155153
&& !(Const.CONSTRUCTOR_NAME.equals(getMethodName()) || Const.STATIC_INITIALIZER_NAME.equals(getMethodName()))) {
156154
createOrUpdateFieldData(getXFieldOperand(), true, getMethod(), getXMethodOperand());
157155
}
158156
} else if ((seen == Const.INVOKEVIRTUAL || seen == Const.INVOKEINTERFACE || seen == Const.INVOKESPECIAL || seen == Const.INVOKESTATIC)
159-
&& getXMethodOperand() != null && getStack().getStackDepth() > 0 && !isDuplicatedLocation(getMethodDescriptor(), getPC())
157+
&& getXMethodOperand() != null && getStack().getStackDepth() > 0
158+
&& !MethodAnalysis.isDuplicatedLocation(getMethodDescriptor(), getPC())
160159
&& methodsUsedInThreads.contains(getMethodDescriptor())) {
161160
// The field is accessed always be the last item in the stack, because the earlier elements are the arguments
162161
XField xField = getStack().getStackItem(getStack().getStackDepth() - 1).getXField();
@@ -166,34 +165,6 @@ && getXMethodOperand() != null && getStack().getStackDepth() > 0 && !isDuplicate
166165
}
167166
}
168167

169-
/**
170-
* Check if the method is a synchronized collection method.
171-
* @todo: This method should be moved to a utility class when VNA03-J detector is merged
172-
*
173-
* @param classMember the class member
174-
* @return {@code true} if the method is a synchronized collection method, {@code false} otherwise
175-
*/
176-
private static boolean isSynchronizedCollection(ClassMember classMember) {
177-
Set<String> interestingCollectionMethodNames = new HashSet<>(Arrays.asList(
178-
"synchronizedCollection", "synchronizedSet", "synchronizedSortedSet",
179-
"synchronizedNavigableSet", "synchronizedList", "synchronizedMap",
180-
"synchronizedSortedMap", "synchronizedNavigableMap"));
181-
return "java.util.Collections".equals(classMember.getClassName()) && interestingCollectionMethodNames.contains(classMember.getName());
182-
}
183-
184-
/**
185-
* Check if the location is duplicated in the method.
186-
* @todo: This method should be moved to a utility class when VNA03-J detector is merged
187-
*
188-
* @return {@code true} if the location is duplicated in the method, {@code false} otherwise
189-
* @throws CheckedAnalysisException if an error occurs during the analysis
190-
*/
191-
private static boolean isDuplicatedLocation(MethodDescriptor methodDescriptor, int pc) throws CheckedAnalysisException {
192-
FinallyDuplicatesInfoFactory.FinallyDuplicatesInfo methodAnalysis = Global.getAnalysisCache().getMethodAnalysis(
193-
FinallyDuplicatesInfoFactory.FinallyDuplicatesInfo.class, methodDescriptor);
194-
return methodAnalysis.getDuplicates(pc).stream().anyMatch(duplicatePc -> duplicatePc < pc);
195-
}
196-
197168
private boolean isAtomicTypedField(XField xField) {
198169
return xField.getSignature().contains("java/util/concurrent/atomic") || synchronizedCollectionTypedFields.contains(xField);
199170
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package edu.umd.cs.findbugs.util;
2+
3+
import java.util.Arrays;
4+
import java.util.HashSet;
5+
import java.util.Set;
6+
7+
import edu.umd.cs.findbugs.ba.ClassMember;
8+
9+
/**
10+
* Utility class for analyzing collections.
11+
*/
12+
public final class CollectionAnalysis {
13+
14+
private CollectionAnalysis() {
15+
}
16+
17+
/**
18+
* Check if a class member is a synchronized collection.
19+
*
20+
* @param classMember the class member
21+
* @return {@code true} if the class member is a synchronized collection, {@code false} otherwise
22+
*/
23+
public static boolean isSynchronizedCollection(ClassMember classMember) {
24+
Set<String> interestingCollectionMethodNames = new HashSet<>(Arrays.asList(
25+
"synchronizedCollection", "synchronizedSet", "synchronizedSortedSet",
26+
"synchronizedNavigableSet", "synchronizedList", "synchronizedMap",
27+
"synchronizedSortedMap", "synchronizedNavigableMap"));
28+
return "java.util.Collections".equals(classMember.getClassName()) && interestingCollectionMethodNames.contains(classMember.getName());
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* SpotBugs - Find bugs in Java programs
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the Free Software
16+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17+
*/
18+
19+
package edu.umd.cs.findbugs.util;
20+
21+
import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
22+
import edu.umd.cs.findbugs.classfile.Global;
23+
import edu.umd.cs.findbugs.classfile.MethodDescriptor;
24+
import edu.umd.cs.findbugs.classfile.engine.bcel.FinallyDuplicatesInfoFactory;
25+
26+
/**
27+
* Utility class for method analysis.
28+
*/
29+
public final class MethodAnalysis {
30+
31+
private MethodAnalysis() {
32+
}
33+
34+
/**
35+
* Check if the location is duplicated in the method.
36+
*
37+
* @return {@code true} if the location is duplicated in the method, {@code false} otherwise
38+
* @throws CheckedAnalysisException if an error occurs during the analysis
39+
*/
40+
public static boolean isDuplicatedLocation(MethodDescriptor methodDescriptor, int pc) throws CheckedAnalysisException {
41+
FinallyDuplicatesInfoFactory.FinallyDuplicatesInfo methodAnalysis =
42+
Global.getAnalysisCache().getMethodAnalysis(FinallyDuplicatesInfoFactory.FinallyDuplicatesInfo.class, methodDescriptor);
43+
return methodAnalysis.getDuplicates(pc).stream().anyMatch(duplicatePc -> duplicatePc < pc);
44+
}
45+
}

0 commit comments

Comments
 (0)