mirror of
https://github.com/github/codeql.git
synced 2025-12-27 06:06:32 +01:00
We might want to unify some of these in future, but doing that correctly is easier than splitting them up correctly, so I've given each one its own QL class for now. I am not familiar with many of the libraries/queries that use CastExpr. I've briefly looked at them and updated them in a way that looks superficially reasonable, but some of the uses will probably want to be refined later.
66 lines
1.8 KiB
Plaintext
66 lines
1.8 KiB
Plaintext
/**
|
|
* @name Inefficient use of key set iterator
|
|
* @description Iterating through the values of a map using the key set is inefficient.
|
|
* @kind problem
|
|
* @problem.severity recommendation
|
|
* @precision high
|
|
* @id java/inefficient-key-set-iterator
|
|
* @tags efficiency
|
|
* maintainability
|
|
*/
|
|
|
|
import java
|
|
|
|
/** A local variable that is initialized using a key-set iterator. */
|
|
class KeySetIterator extends LocalVariableDecl {
|
|
KeySetIterator() {
|
|
exists(LocalVariableDeclExpr lvde, MethodAccess init |
|
|
lvde.getVariable() = this and
|
|
lvde.getInit() = init and
|
|
init.getMethod().hasName("iterator") and
|
|
init.getQualifier().(MethodAccess).getMethod().hasName("keySet")
|
|
)
|
|
}
|
|
|
|
LocalVariableDecl getBase() {
|
|
exists(LocalVariableDeclExpr lvde, MethodAccess init |
|
|
lvde.getVariable() = this and
|
|
lvde.getInit() = init and
|
|
init.getQualifier().(MethodAccess).getQualifier().(VarAccess).getVariable() = result
|
|
)
|
|
}
|
|
}
|
|
|
|
predicate isKeyNext(Expr e, KeySetIterator it) {
|
|
exists(MethodAccess ma | ma = e |
|
|
ma.getMethod().hasName("next") and
|
|
ma.getQualifier().(VarAccess).getVariable() = it
|
|
)
|
|
or
|
|
isKeyNext(e.(CastingExpr).getExpr(), it)
|
|
}
|
|
|
|
class Key extends LocalVariableDecl {
|
|
Key() {
|
|
exists(LocalVariableDeclExpr lvde, KeySetIterator it |
|
|
lvde.getVariable() = this and
|
|
isKeyNext(lvde.getInit(), it)
|
|
)
|
|
}
|
|
|
|
KeySetIterator getBase() {
|
|
exists(LocalVariableDeclExpr lvde |
|
|
lvde.getVariable() = this and
|
|
isKeyNext(lvde.getInit(), result)
|
|
)
|
|
}
|
|
}
|
|
|
|
from MethodAccess ma, Method get
|
|
where
|
|
ma.getMethod() = get and
|
|
get.hasName("get") and
|
|
ma.getAnArgument().(VarAccess).getVariable().(Key).getBase().getBase() =
|
|
ma.getQualifier().(VarAccess).getVariable()
|
|
select ma, "Inefficient use of key set iterator instead of entry set iterator."
|