Skip to content

Commit

Permalink
Add functions to ExitOutsideMain rule (#5963)
Browse files Browse the repository at this point in the history
  • Loading branch information
schalkms committed Apr 5, 2023
1 parent 8507ea5 commit 9c86a81
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull

/**
* Reports use of `System.exit()` and Kotlin's `exitProcess()` when used outside the `main` function.
* Reports the usage of `System.exit()`, `Runtime.exit()`, `Runtime.halt()` and Kotlin's `exitProcess()`
* when used outside the `main` function.
* This makes code more difficult to test, causes unexpected behaviour on Android, and is a poor way to signal a
* failure in the program. In almost all cases it is more appropriate to throw an exception.
*
Expand Down Expand Up @@ -59,8 +60,17 @@ class ExitOutsideMain(config: Config = Config.empty) : Rule(config) {
if (expression.getStrictParentOfType<KtNamedFunction>()?.isMainFunction() == true) return
val fqName = expression.getResolvedCall(bindingContext)?.resultingDescriptor?.fqNameOrNull() ?: return

if (fqName.asString() in setOf("kotlin.system.exitProcess", "java.lang.System.exit")) {
if (fqName.asString() in exitCalls) {
report(CodeSmell(issue, Entity.from(expression), issue.description))
}
}

companion object {
val exitCalls = setOf(
"kotlin.system.exitProcess",
"java.lang.System.exit",
"java.lang.Runtime.exit",
"java.lang.Runtime.halt"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ class ExitOutsideMainSpec(private val env: KotlinCoreEnvironment) {
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

@Test
fun `reports Runtime_exit used outside main()`() {
val code = """
fun f() {
Runtime.getRuntime().exit(0)
}
""".trimIndent()
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

@Test
fun `reports Runtime_halt used outside main()`() {
val code = """
fun f() {
Runtime.getRuntime().halt(0)
}
""".trimIndent()
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

@Test
fun `does not report exitProcess used in main()`() {
val code = """
Expand Down

0 comments on commit 9c86a81

Please sign in to comment.