Files
codeql/java/ql/src/Language Abuse/EmptyMethod.ql
2025-03-14 11:36:14 +01:00

94 lines
2.7 KiB
Plaintext

/**
* @id java/empty-method
* @name Empty method
* @description An empty method serves no purpose and makes code less readable. An empty method may
* indicate an error on the part of the developer.
* @kind problem
* @precision medium
* @problem.severity recommendation
* @tags correctness
* maintainability
* readability
* quality
* external/cwe/cwe-1071
*/
import java
/**
* Represents a likely a test method, which is either a method that is already
* recognized as a `TestMethod` or something that is likely a JUnit test or
* something in the expected test path for Java tests.
*/
class LikelyTestMethod extends Method {
LikelyTestMethod() {
this.getDeclaringType() instanceof TestClass
or
this instanceof TestMethod
or
this instanceof LikelyJunitTest
or
//standard Maven/Gradle test file discovery filepath
this.getFile().getAbsolutePath().matches("%src/test/java%")
or
this.getDeclaringType() instanceof SurefireTest
}
}
/**
* Classes that are likely part of junit tests (more general than `TestMethod` from `UnitTest.qll`)
* A `Method` that is public, has no parameters,
* has a "void" return type, AND either has a name that starts with "test" OR
* has an annotation that ends with "Test"
*/
class LikelyJunitTest extends Method {
LikelyJunitTest() {
this.isPublic() and
this.getReturnType().hasName("void") and
this.hasNoParameters() and
(
this.getName().matches("JUnit%") or
this.getName().matches("test%") or
this.getAnAnnotation().getType().getName().matches("%Test")
)
}
}
/**
* Maven surefire patterns to consider which files are testcases:
* https://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html
*/
class SurefireTest extends Class {
SurefireTest() {
this.getFile().getAbsolutePath().matches("%src/test/java%") and
this.getFile()
.getBaseName()
.matches(["Test%.java", "%Test.java", "%Tests.java", "%TestCase.java"])
}
}
/**
* A `Method` from source that is not abstract
*/
class NonAbstractSource extends Method {
NonAbstractSource() {
this.fromSource() and
not this.isAbstract() and
not this instanceof LikelyTestMethod
}
}
from NonAbstractSource m
where
//empty
not exists(m.getBody().getAChild()) and
//permit comment lines explaining why this is empty
m.getNumberOfCommentLines() = 0 and
//permit a javadoc above as well as sufficient reason to leave empty
not exists(m.getDoc().getJavadoc()) and
//annotated methods are considered compliant
not exists(m.getAnAnnotation()) and
//native methods have no body
not m.isNative()
select m, "Empty method found."