Skip to content

Commit

Permalink
Detect Unused returns (#3)
Browse files Browse the repository at this point in the history
* Detekt Unsued Returns

* Passing tests

* Add default rule stuff

* move to java 17

* Save test logs

* Add some debugging

* Add some debugging

* remove the debugging

---------

Co-authored-by: Joel Dickson <joeldickson@users.noreply.github.com>
  • Loading branch information
joeldickson and joeldickson authored Oct 12, 2024
1 parent 3113733 commit f379ee0
Show file tree
Hide file tree
Showing 18 changed files with 255 additions and 49 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Agoda Kraft CI
on:
push:
env:
JAVA_VERSION: 11
JAVA_VERSION: 17
JAVA_DISTRIBUTION: "adopt"
MAJOR_MINOR_VERSION: 0.1.

Expand All @@ -19,6 +19,13 @@ jobs:
distribution: ${{ env.JAVA_DISTRIBUTION }}
- name: Build
run: ./gradlew clean build
continue-on-error: true
- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: test-reports
path: |
build/reports
- name: Test
run: ./gradlew test

Expand Down
9 changes: 6 additions & 3 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules/agoda-kraft.main.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Add the following to your project's `build.gradle.kts`:

```kotlin
dependencies {
implementation("io.agodadev:kraft-ktlint:1.0.0")
implementation("io.agodadev:kraft-detekt:1.0.0")
implementation("io.agodadev:agoda-kraft:0.1.X")

}
```

Expand Down
11 changes: 7 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ java {
withJavadocJar()
withSourcesJar()
toolchain {
languageVersion.set(JavaLanguageVersion.of(11)) // To be compatible with lib consumers
languageVersion.set(JavaLanguageVersion.of(17)) // To be compatible with lib consumers
}
}

Expand All @@ -28,13 +28,16 @@ repositories {
dependencies {
implementation(kotlin("stdlib"))
implementation("com.pinterest.ktlint:ktlint-core:0.48.2")
implementation("io.gitlab.arturbosch.detekt:detekt-api:1.22.0")
implementation("io.gitlab.arturbosch.detekt:detekt-api:1.23.0")
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")

testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.0")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testImplementation("io.gitlab.arturbosch.detekt:detekt-test:1.22.0")
testImplementation("io.gitlab.arturbosch.detekt:detekt-test:1.23.0")
testImplementation("org.mockito:mockito-core:4.8.1")
testImplementation("org.junit.jupiter:junit-jupiter:5.7.1")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
testImplementation("org.assertj:assertj-core:3.24.2")
}

tasks.test {
Expand Down
2 changes: 1 addition & 1 deletion jreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ project:
homepage: "https://github.com/agoda-com/agoda-kraft"
java:
groupId: io.agodadev
version: "11"
version: "17"
maintainers:
- Agoda
copyright: 2024 Agoda
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.agodadev.kraftdetekt

import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.RuleSet
import io.gitlab.arturbosch.detekt.api.RuleSetProvider

class AgodaKraftDetektExtension : RuleSetProvider {
override val ruleSetId: String = "agoda-kraft"

override fun instance(config: Config): RuleSet {
return RuleSet(
ruleSetId,
listOf(
IgnoredReturnValueRule(config)
// Add other rules here when there is new ones
)
)
}
}
19 changes: 0 additions & 19 deletions src/main/kotlin/io/agodadev/kraftdetekt/CustomDetektRule.kt

This file was deleted.

71 changes: 71 additions & 0 deletions src/main/kotlin/io/agodadev/kraftdetekt/IgnoredReturnValueRule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.agodadev.kraftdetekt

import io.gitlab.arturbosch.detekt.api.*
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit

class IgnoredReturnValueRule(config: Config) : Rule(config) {
override val issue = Issue(
javaClass.simpleName,
Severity.Warning,
"This rule reports when a function call's return value is ignored.",
Debt.FIVE_MINS
)

override fun visitCallExpression(expression: KtCallExpression) {
super.visitCallExpression(expression)

if (expression.calleeExpression is KtConstructorCalleeExpression || isWithinThrowExpression(expression)) {
return
}

val resolvedCall = expression.getResolvedCall(bindingContext) ?: return
val returnType = resolvedCall.resultingDescriptor.returnType ?: return

if (!returnType.isUnit() && !returnType.isNothing()) {
val parent = expression.parent
when {
parent is KtValueArgument -> return
parent is KtProperty -> return
parent is KtReturnExpression -> return
parent is KtBinaryExpression && parent.operationToken.toString() == "EQ" -> return
parent is KtIfExpression && expression == parent.condition -> return
parent is KtWhenConditionWithExpression -> return
parent is KtBinaryExpression && parent.operationToken.toString() in setOf("GT", "LT", "GTEQ", "LTEQ", "EQEQ", "EXCLEQ") -> return
parent is KtDotQualifiedExpression -> return
parent is KtBlockExpression -> {
val isLastStatement = parent.statements.lastOrNull() == expression
val isOnlyStatement = parent.statements.size == 1
if (!isLastStatement && !isOnlyStatement) {
report(CodeSmell(
issue,
Entity.from(expression),
"The return value of this function call is ignored."
))
}
}
else -> {
report(CodeSmell(
issue,
Entity.from(expression),
"The return value of this function call is ignored."
))
}
}
}
}

private fun isWithinThrowExpression(expression: KtExpression): Boolean {
var current: PsiElement? = expression
while (current != null && current !is KtFunction) {
if (current is KtThrowExpression) {
return true
}
current = current.parent
}
return false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.agodadev.kraftdetekt.AgodaKraftDetektExtension
16 changes: 0 additions & 16 deletions src/test/kotlin/io/agodadev/kraftdetekt/CustomDetektRuleTest.kt

This file was deleted.

Loading

0 comments on commit f379ee0

Please sign in to comment.