Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ArrayPrimitive rule honor the RequiresTypeResolution annotation #5175

Merged
merged 2 commits into from Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
Expand Down Expand Up @@ -51,9 +52,13 @@ class ArrayPrimitive(config: Config = Config.empty) : Rule(config) {
Debt.FIVE_MINS
)

override fun visitKtFile(file: KtFile) {
if (bindingContext == BindingContext.EMPTY) return
super.visitKtFile(file)
}

override fun visitCallExpression(expression: KtCallExpression) {
super.visitCallExpression(expression)
if (bindingContext == BindingContext.EMPTY) return
if (expression.calleeExpression?.text !in factoryMethodNames) return

val descriptor = expression.getResolvedCall(bindingContext)?.resultingDescriptor
Expand Down
@@ -1,7 +1,6 @@
package io.gitlab.arturbosch.detekt.rules.performance

import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest
import io.gitlab.arturbosch.detekt.test.compileAndLint
import io.gitlab.arturbosch.detekt.test.compileAndLintWithContext
import org.assertj.core.api.Assertions.assertThat
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
Expand All @@ -19,49 +18,49 @@ class ArrayPrimitiveSpec(val env: KotlinCoreEnvironment) {
@Test
fun `is an array of primitive type`() {
val code = "fun function(array: Array<Int>) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

@Test
fun `is not an array`() {
val code = "fun function(i: Int) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is a specialized array`() {
val code = "fun function(array: ByteArray) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is a star-projected array`() {
val code = "fun function(array: Array<*>) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is not present`() {
val code = "fun function() {}"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is an array of a non-primitive type`() {
val code = "fun function(array: Array<String>) {}"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is an array of an array of a primitive type`() {
val code = "fun function(array: Array<Array<Int>>) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

@Test
fun `is a dictionary with an array of a primitive type as key`() {
val code = "fun function(dict: java.util.Dictionary<Int, Array<Int>>) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}
}

Expand All @@ -71,13 +70,13 @@ class ArrayPrimitiveSpec(val env: KotlinCoreEnvironment) {
@DisplayName("one is Array<Primitive> and the other is not")
fun oneArrayPrimitive() {
val code = "fun function(array: Array<Int>, array2: IntArray) {}"
assertThat(subject.compileAndLint(code)).hasSize(1)
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1)
}

@Test
fun `both are arrays of primitive types`() {
val code = "fun function(array: Array<Int>, array2: Array<Double>) {}"
assertThat(subject.compileAndLint(code)).hasSize(2)
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(2)
}
}

Expand All @@ -87,31 +86,31 @@ class ArrayPrimitiveSpec(val env: KotlinCoreEnvironment) {
@DisplayName("is Array<Primitive>")
fun isArrayPrimitive() {
val code = "fun returningFunction(): Array<Float> { return emptyArray() }"
assertThat(subject.compileAndLint(code)).hasSize(1)
assertThat(subject.compileAndLintWithContext(env, code)).hasSize(2)
}

@Test
fun `is not an array`() {
val code = "fun returningFunction(): Int { return 1 }"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is a specialized array`() {
val code = "fun returningFunction(): CharArray { return CharArray(0) }"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is a star-projected array`() {
val code = "fun returningFunction(): Array<*> { return emptyArray<Any>() }"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}

@Test
fun `is not explicitly set`() {
val code = "fun returningFunction() {}"
assertThat(subject.compileAndLint(code)).isEmpty()
assertThat(subject.compileAndLintWithContext(env, code)).isEmpty()
}
}

Expand Down