mirror of
https://github.com/github/codeql.git
synced 2026-03-06 15:49:08 +01:00
94 lines
2.7 KiB
Plaintext
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."
|