Files
codeql/java/ql/src/Performance/InefficientKeySetIterator.ql
Ian Lynagh 6566f7b69f Kotlin: Add types for the different kinds of casts that Kotlin has
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.
2022-05-10 19:51:13 +01:00

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."