18
18
19
19
package edu .umd .cs .findbugs .detect ;
20
20
21
- import java .util .Arrays ;
22
21
import java .util .HashMap ;
23
22
import java .util .HashSet ;
24
23
import java .util .Map ;
37
36
import edu .umd .cs .findbugs .BugInstance ;
38
37
import edu .umd .cs .findbugs .BugReporter ;
39
38
import edu .umd .cs .findbugs .OpcodeStack ;
40
- import edu .umd .cs .findbugs .ba .ClassMember ;
41
39
import edu .umd .cs .findbugs .ba .XField ;
42
40
import edu .umd .cs .findbugs .ba .XMethod ;
43
41
import edu .umd .cs .findbugs .bcel .BCELUtil ;
44
42
import edu .umd .cs .findbugs .bcel .OpcodeStackDetector ;
45
43
import edu .umd .cs .findbugs .classfile .CheckedAnalysisException ;
46
- import edu .umd .cs .findbugs .classfile .Global ;
47
44
import edu .umd .cs .findbugs .classfile .MethodDescriptor ;
48
- import edu .umd .cs .findbugs .classfile .engine .bcel .FinallyDuplicatesInfoFactory ;
49
45
import edu .umd .cs .findbugs .util .BootstrapMethodsUtil ;
46
+ import edu .umd .cs .findbugs .util .CollectionAnalysis ;
47
+ import edu .umd .cs .findbugs .util .MethodAnalysis ;
50
48
import edu .umd .cs .findbugs .util .MutableClasses ;
51
49
52
50
public class ResourceInMultipleThreadsDetector extends OpcodeStackDetector {
@@ -146,17 +144,18 @@ private Optional<MethodDescriptor> getMethodFromBootstrap(JavaClass javaClass, C
146
144
147
145
private void collectFieldsUsedInThreads (int seen ) throws CheckedAnalysisException {
148
146
if ((seen == Const .PUTFIELD || seen == Const .PUTSTATIC ) && getStack ().getStackDepth () > 0
149
- && !isDuplicatedLocation (getMethodDescriptor (), getPC ())
147
+ && !MethodAnalysis . isDuplicatedLocation (getMethodDescriptor (), getPC ())
150
148
&& methodsUsedInThreads .contains (getMethodDescriptor ())) {
151
149
OpcodeStack .Item stackItem = getStack ().getStackItem (0 );
152
- if (stackItem .getReturnValueOf () != null && isSynchronizedCollection (stackItem .getReturnValueOf ())) {
150
+ if (stackItem .getReturnValueOf () != null && CollectionAnalysis . isSynchronizedCollection (stackItem .getReturnValueOf ())) {
153
151
synchronizedCollectionTypedFields .add (getXFieldOperand ());
154
152
} else if (!isAtomicTypedField (getXFieldOperand ())
155
153
&& !(Const .CONSTRUCTOR_NAME .equals (getMethodName ()) || Const .STATIC_INITIALIZER_NAME .equals (getMethodName ()))) {
156
154
createOrUpdateFieldData (getXFieldOperand (), true , getMethod (), getXMethodOperand ());
157
155
}
158
156
} 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 ())
160
159
&& methodsUsedInThreads .contains (getMethodDescriptor ())) {
161
160
// The field is accessed always be the last item in the stack, because the earlier elements are the arguments
162
161
XField xField = getStack ().getStackItem (getStack ().getStackDepth () - 1 ).getXField ();
@@ -166,34 +165,6 @@ && getXMethodOperand() != null && getStack().getStackDepth() > 0 && !isDuplicate
166
165
}
167
166
}
168
167
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
-
197
168
private boolean isAtomicTypedField (XField xField ) {
198
169
return xField .getSignature ().contains ("java/util/concurrent/atomic" ) || synchronizedCollectionTypedFields .contains (xField );
199
170
}
0 commit comments