Skip to content

Commit

Permalink
Allow to forbid constructors with ForbiddenMethodCall
Browse files Browse the repository at this point in the history
  • Loading branch information
BraisGabin committed Aug 7, 2022
1 parent cdd2d71 commit d4fd018
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
Expand Up @@ -61,7 +61,8 @@ class ForbiddenMethodCall(config: Config = Config.empty) : Rule(config) {
"(i.e. `java.time.LocalDate(java.time.Clock)`) which would report only call " +
"with this concrete signature. If you want to forbid an extension function like" +
"`fun String.hello(a: Int)` you should add the receiver parameter as the first parameter like this: " +
"`hello(kotlin.String, kotlin.Int)`"
"`hello(kotlin.String, kotlin.Int)`. To forbid constructor calls you need to define them with `<init>` " +
" for example `java.util.Date.<init>`."
)
private val methods: List<Forbidden> by config(
valuesWithReason(
Expand Down
Expand Up @@ -508,4 +508,73 @@ class ForbiddenMethodCallSpec(val env: KotlinCoreEnvironment) {
)
assertThat(findings).hasSize(1)
}

@Nested
inner class `Forbid constructors` {
@Nested
inner class NameOnly {
@Test
fun `empty constructor`() {
val code = """
import java.util.Date
val a = Date()
""".trimIndent()
val findings =
ForbiddenMethodCall(TestConfig(METHODS to listOf("java.util.Date.<init>"))).compileAndLintWithContext(
env,
code
)
assertThat(findings).hasSize(1)
}

@Test
fun `no-empty constructor`() {
val code = """
import java.util.Date
val a = Date(2022, 8 ,7)
""".trimIndent()
val findings =
ForbiddenMethodCall(TestConfig(METHODS to listOf("java.util.Date.<init>"))).compileAndLintWithContext(
env,
code
)
assertThat(findings).hasSize(1)
}
}

@Nested
inner class WithParameters {
@Test
fun `empty constructor`() {
val code = """
import java.util.Date
val a = Date()
""".trimIndent()
val findings =
ForbiddenMethodCall(TestConfig(METHODS to listOf("java.util.Date.<init>()"))).compileAndLintWithContext(
env,
code
)
assertThat(findings).hasSize(1)
}

@Test
fun `no-empty constructor`() {
val code = """
import java.util.Date
val a = Date(2022, 8 ,7)
""".trimIndent()
val findings =
ForbiddenMethodCall(TestConfig(METHODS to listOf("java.util.Date.<init>(kotlin.Int, kotlin.Int, kotlin.Int)"))).compileAndLintWithContext(
env,
code
)
assertThat(findings).hasSize(1)
}
}
}
}
Expand Up @@ -5,6 +5,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter

Expand All @@ -18,7 +19,7 @@ sealed class FunctionMatcher {
private val fullyQualifiedName: String
) : FunctionMatcher() {
override fun match(callableDescriptor: CallableDescriptor): Boolean {
return callableDescriptor.fqNameOrNull()?.asString() == fullyQualifiedName
return callableDescriptor.fqNameSafe.asString() == fullyQualifiedName
}

override fun match(function: KtNamedFunction, bindingContext: BindingContext): Boolean {
Expand All @@ -36,7 +37,7 @@ sealed class FunctionMatcher {
) : FunctionMatcher() {
override fun match(callableDescriptor: CallableDescriptor): Boolean {
val descriptor = callableDescriptor.original
if (descriptor.fqNameOrNull()?.asString() != fullyQualifiedName) return false
if (descriptor.fqNameSafe.asString() != fullyQualifiedName) return false

val encounteredParamTypes =
(listOfNotNull(descriptor.extensionReceiverParameter) + descriptor.valueParameters)
Expand Down

0 comments on commit d4fd018

Please sign in to comment.