Skip to content

Commit 8a1749a

Browse files
committed
Add Thread-used-as-Runnable.ql
1 parent 204ca08 commit 8a1749a

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Finds code which uses a `Thread` as `Runnable`. The class `Thread` implements `Runnable`,
3+
* but the actual scheduling of the thread is done by the `start()` method. Therefore
4+
* using a `Thread` where a `Runnable` is expected most likely provides no advantage and
5+
* only leads to confusion.
6+
*
7+
* For example:
8+
* ```java
9+
* executor.execute(new Thread(...));
10+
* ```
11+
* Should be replaced with:
12+
* ```java
13+
* executor.execute(new MyRunnable(...));
14+
* ```
15+
*
16+
* @kind problem
17+
* @id todo
18+
*/
19+
20+
// Note: This is a more generic variant of `likely-bugs/Thread-as-Runnable-argument-for-Thread-constructor.ql`
21+
import java
22+
import semmle.code.java.Conversions
23+
24+
class TypeThread extends Class {
25+
TypeThread() { hasQualifiedName("java.lang", "Thread") }
26+
}
27+
28+
class TypeRunnable extends Interface {
29+
TypeRunnable() { hasQualifiedName("java.lang", "Runnable") }
30+
}
31+
32+
from ConversionSite threadConversion
33+
where
34+
// Source is of type Thread (or subtype)
35+
threadConversion.getConversionSource().(RefType).getASourceSupertype*() instanceof TypeThread and
36+
// Target is of type Runnable (or subtype, which is not Thread)
37+
threadConversion.getConversionTarget().(RefType).getASourceSupertype*() instanceof TypeRunnable and
38+
not threadConversion.getConversionTarget().(RefType).getASourceSupertype*() instanceof TypeThread
39+
select threadConversion, "Thread used as Runnable"

0 commit comments

Comments
 (0)