Skip to content

Commit

Permalink
Fix Kotlin type not directly using javaType
Browse files Browse the repository at this point in the history
  • Loading branch information
seongahjo committed Mar 5, 2025
1 parent 8db84b4 commit b935a6a
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ import com.navercorp.fixturemonkey.api.property.PropertySelector
import com.navercorp.fixturemonkey.api.type.TypeReference
import com.navercorp.fixturemonkey.api.type.Types
import com.navercorp.fixturemonkey.kotlin.KotlinTypeDefaultArbitraryBuilder
import com.navercorp.fixturemonkey.kotlin.giveMeBuilder
import com.navercorp.fixturemonkey.kotlin.giveMeKotlinBuilder
import com.navercorp.fixturemonkey.kotlin.giveMeOne
import com.navercorp.fixturemonkey.kotlin.propertyExpressionGenerator
import com.navercorp.fixturemonkey.kotlin.type.actualType
import com.navercorp.fixturemonkey.kotlin.type.toTypeReference
import io.kotest.property.Arb
import io.kotest.property.arbitrary.arbitrary
import io.kotest.property.arbitrary.single
Expand All @@ -38,7 +39,6 @@ import java.lang.reflect.Type
import java.util.function.Supplier
import kotlin.reflect.KProperty1
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.jvm.javaType
import kotlin.reflect.typeOf

@Suppress("UNCHECKED_CAST")
Expand All @@ -49,7 +49,7 @@ inline fun <reified T> FixtureMonkey.giveMeArb(): Arb<T> {
val typeParameter = type.arguments[0]

arbitrary {
val javaType = typeParameter.type!!.javaType
val javaType = typeParameter.type!!.toTypeReference().type
giveMeBuilder(
object : TypeReference<T>() {
override fun getType(): Type {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ package com.navercorp.fixturemonkey.kotlin
import com.navercorp.fixturemonkey.api.expression.ExpressionGenerator
import com.navercorp.fixturemonkey.api.property.Property
import com.navercorp.fixturemonkey.api.property.PropertyNameResolver
import com.navercorp.fixturemonkey.kotlin.type.actualType
import com.navercorp.fixturemonkey.kotlin.type.getPropertyName
import com.navercorp.fixturemonkey.kotlin.type.toTypeReference
import java.lang.reflect.AnnotatedType
import java.lang.reflect.Field
import java.lang.reflect.ParameterizedType
import kotlin.reflect.KFunction1
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1
import kotlin.reflect.jvm.javaField
import kotlin.reflect.jvm.javaType
import kotlin.reflect.jvm.kotlinProperty

// property
Expand Down Expand Up @@ -488,13 +488,8 @@ private class KotlinProperty<V, R>(private val property: KProperty1<V, R>) : Pro
}

private class KotlinGetterProperty<V, R>(private val getter: KFunction1<V, R>) : Property {
private val callerType = getter.parameters[0].type.javaType as Class<*>
private val returnJavaType = getter.returnType.javaType
private val type: Class<*> = if (returnJavaType is ParameterizedType) {
returnJavaType.rawType as Class<*>
} else {
returnJavaType as Class<*>
}
private val callerType = getter.parameters[0].type.toTypeReference().type.actualType()
private val type: Class<*> = getter.returnType.toTypeReference().type.actualType()
private val propertyName: String = resolvePropertyName()

private fun resolvePropertyName(): String = getter.getPropertyName()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ import com.navercorp.fixturemonkey.api.property.Property
import com.navercorp.fixturemonkey.api.property.PropertyGenerator
import com.navercorp.fixturemonkey.api.type.Types
import com.navercorp.fixturemonkey.kotlin.property.InterfaceKFunctionProperty
import com.navercorp.fixturemonkey.kotlin.type.actualType
import com.navercorp.fixturemonkey.kotlin.type.getPropertyName
import com.navercorp.fixturemonkey.kotlin.type.isKotlinType
import com.navercorp.fixturemonkey.kotlin.type.kotlinMemberFunctions
import com.navercorp.fixturemonkey.kotlin.type.toTypeReference
import org.apiguardian.api.API
import org.apiguardian.api.API.Status
import kotlin.reflect.KParameter.Kind.INSTANCE
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.javaMethod
import kotlin.reflect.jvm.javaType

/**
* A property generator for generating no-argument Kotlin interface method.
Expand All @@ -47,7 +48,7 @@ class InterfaceKFunctionPropertyGenerator : PropertyGenerator {
val methods = type.kotlinMemberFunctions()
.filter { it.parameters.none { parameter -> parameter.kind != INSTANCE } }
.filter { !DATA_CLASS_METHOD_NAMES.contains(it.name) }
.filter { it.returnType.javaType != Void.TYPE }
.filter { it.returnType.toTypeReference().type.actualType() != Void.TYPE }
.map {
InterfaceKFunctionProperty(
it.returnType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ import kotlin.reflect.KParameter
import kotlin.reflect.KProperty
import kotlin.reflect.full.companionObject
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaType

class KotlinInstantiatorProcessor :
InstantiatorProcessor {
Expand All @@ -82,7 +81,7 @@ class KotlinInstantiatorProcessor :

val inputParameterTypes = instantiator.inputParameterTypes
val inputParameterNames = instantiator.inputParameterNames
val parameterTypeReferences = parameters.map { it.type.javaType.toTypeReference() }
val parameterTypeReferences = parameters.map { it.type.toTypeReference() }
val parameterNames = parameters.map { it.name }

val resolveParameterTypes = resolveParameterTypes(parameterTypeReferences, inputParameterTypes)
Expand Down Expand Up @@ -235,7 +234,7 @@ class KotlinInstantiatorProcessor :
private fun hasAnyParameterMatchingFunction(function: KFunction<*>, inputParameterTypes: Array<Class<*>>): Boolean =
function.parameters
.filter { parameter -> parameter.kind != KParameter.Kind.INSTANCE }
.map { parameter -> parameter.type.javaType.actualType() }
.map { parameter -> parameter.type.toTypeReference().type.actualType() }
.let {
inputParameterTypes.isEmpty() || Types.isAssignableTypes(it.toTypedArray(), inputParameterTypes)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
package com.navercorp.fixturemonkey.kotlin.property

import com.navercorp.fixturemonkey.api.property.MethodProperty
import com.navercorp.fixturemonkey.kotlin.type.toTypeReference
import org.apiguardian.api.API
import org.apiguardian.api.API.Status
import java.lang.reflect.AnnotatedType
import java.lang.reflect.Type
import java.util.Optional
import kotlin.reflect.KType
import kotlin.reflect.jvm.javaType

/**
* An interface method property for kotlin.
Expand All @@ -37,7 +37,7 @@ data class InterfaceKFunctionProperty(
private val methodName: String,
private val annotations: List<Annotation>,
) : MethodProperty {
override fun getType(): Type = type.javaType
override fun getType(): Type = type.toTypeReference().type

override fun getAnnotatedType(): AnnotatedType = object : AnnotatedType {
override fun getType(): Type = this@InterfaceKFunctionProperty.getType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package com.navercorp.fixturemonkey.kotlin.type

import com.navercorp.fixturemonkey.api.container.ConcurrentLruCache
import com.navercorp.fixturemonkey.api.type.KotlinTypeDetector
import com.navercorp.fixturemonkey.api.type.TypeReference
import com.navercorp.fixturemonkey.api.type.Types
Expand Down Expand Up @@ -62,22 +63,26 @@ fun Type.toTypeReference(): TypeReference<*> = object : TypeReference<Any?>() {
}
}

fun KType.toTypeReference(): TypeReference<*> = object : TypeReference<Any?>() {
override fun getType(): Type {
return this@toTypeReference.javaType
}
fun KType.toTypeReference(): TypeReference<*> = TYPE_REFERENCES_BY_KOTLIN_TYPE.computeIfAbsent(this@toTypeReference) {
object : TypeReference<Any?>() {
override fun getType(): Type {
return this.annotatedType.type
}

override fun getAnnotatedType(): AnnotatedType {
try {
if (this@toTypeReference.classifier != null && this@toTypeReference.jvmErasure.isValue) { // for Kotlin value class
return this@toTypeReference.classifier!!.createType().javaType.toAnnotatedType()
override fun getAnnotatedType(): AnnotatedType {
try {
if (this@toTypeReference.classifier != null && this@toTypeReference.jvmErasure.isValue) { // for Kotlin value class
return this@toTypeReference.classifier!!.createType().javaType.toAnnotatedType()
}
} catch (ex: KotlinReflectionInternalError) {
// ignored
}
} catch (ex: KotlinReflectionInternalError) {
// ignored
}

return this@toTypeReference.javaType.toAnnotatedType()
return this@toTypeReference.javaType.toAnnotatedType()
}
}
}

fun Class<*>.isKotlinType(): Boolean = KotlinTypeDetector.isKotlinType(this)

private val TYPE_REFERENCES_BY_KOTLIN_TYPE = ConcurrentLruCache<KType, TypeReference<*>>(1024)
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ fun Class<*>.declaredConstructor(
Types.isAssignableTypes(
arguments,
constructor.parameters.filter { it.kind != KParameter.Kind.INSTANCE }
.map { it.type.javaType.actualType() }
.map { it.type.toTypeReference().type.actualType() }
.toTypedArray(),
)
} ?: this.kotlin.constructors.first()
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ class ValueClassTest {
then(actual).isNotNull
}

@Test
fun factoryParameterWithTypeValueClass() {
val actual = SUT.giveMeKotlinBuilder<ConcreteClass>()
.instantiateBy<ConcreteClass> { factory<ConcreteClass>("factory"){
parameter<Foo>("id")
} }
.sample()

then(actual).isNotNull
}

@JvmInline
value class Foo(
val bar: String,
Expand Down

0 comments on commit b935a6a

Please sign in to comment.