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

De-duplicate ValueClassSupport #913

Merged
merged 13 commits into from Sep 6, 2022
5 changes: 0 additions & 5 deletions modules/mockk-agent-android/api/mockk-agent-android.api
@@ -1,8 +1,3 @@
public final class io/mockk/ValueClassSupportAndroidKt {
public static final fun getBoxedClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass;
public static final fun getBoxedValue (Ljava/lang/Object;)Ljava/lang/Object;
}

public final class io/mockk/proxy/android/AndroidMockKAgentFactory : io/mockk/proxy/MockKAgentFactory {
public static final field Companion Lio/mockk/proxy/android/AndroidMockKAgentFactory$Companion;
public field constructorProxyMaker Lio/mockk/proxy/MockKConstructorProxyMaker;
Expand Down
2 changes: 2 additions & 0 deletions modules/mockk-agent-android/build.gradle.kts
Expand Up @@ -45,6 +45,8 @@ dependencies {
api(projects.modules.mockkAgentApi)
api(projects.modules.mockkAgent)

implementation(projects.modules.mockkPlatformTools)

implementation(kotlin("reflect"))
implementation("com.linkedin.dexmaker:dexmaker:${buildsrc.config.Deps.Versions.dexmaker}")
implementation("org.objenesis:objenesis:${buildsrc.config.Deps.Versions.objenesis}")
Expand Down

This file was deleted.

Expand Up @@ -5,7 +5,7 @@

package io.mockk.proxy.android.advice

import io.mockk.boxedValue
import io.mockk.platform.ValueClassSupport.boxedValue
import io.mockk.proxy.MockKAgentException
import io.mockk.proxy.android.AndroidMockKMap
import io.mockk.proxy.android.MethodDescriptor
Expand Down
5 changes: 0 additions & 5 deletions modules/mockk-agent/api/mockk-agent.api
@@ -1,8 +1,3 @@
public final class io/mockk/ValueClassSupportKt {
public static final fun getBoxedClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass;
public static final fun getBoxedValue (Ljava/lang/Object;)Ljava/lang/Object;
}

public class io/mockk/proxy/jvm/ClassLoadingStrategyChooser {
public fun <init> ()V
public static fun chooseClassLoadingStrategy (Ljava/lang/Class;)Lnet/bytebuddy/dynamic/loading/ClassLoadingStrategy;
Expand Down
1 change: 1 addition & 0 deletions modules/mockk-agent/build.gradle.kts
Expand Up @@ -24,6 +24,7 @@ kotlin {
dependencies {
api(projects.modules.mockkAgentApi)
implementation(kotlin("reflect"))
implementation(projects.modules.mockkPlatformTools)
}
}
val commonTest by getting {
Expand Down

This file was deleted.

@@ -1,6 +1,6 @@
package io.mockk.proxy.jvm.advice

import io.mockk.boxedValue
import io.mockk.platform.ValueClassSupport.boxedValue
import io.mockk.proxy.MockKInvocationHandler
import java.lang.reflect.Method
import java.util.concurrent.Callable
Expand Down
1 change: 1 addition & 0 deletions modules/mockk-dsl/build.gradle.kts
Expand Up @@ -20,6 +20,7 @@ kotlin {
implementation(dependencies.platform(Deps.Libs.kotlinCoroutinesBom))
implementation(Deps.Libs.kotlinCoroutinesCore)
implementation(kotlin("reflect"))
implementation(projects.modules.mockkPlatformTools)
}
}
val commonTest by getting {
Expand Down
@@ -1,27 +1,22 @@
package io.mockk

import io.mockk.ValueClassSupportDsl.boxedClass
import io.mockk.platform.ValueClassSupport.boxedClass
import kotlinx.coroutines.runBlocking
import java.lang.reflect.AccessibleObject
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import java.util.concurrent.atomic.AtomicLong
import kotlin.coroutines.Continuation
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty1
import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter
import kotlin.reflect.*
import kotlin.reflect.full.allSuperclasses
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.functions
import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaMethod
import kotlinx.coroutines.runBlocking

actual object InternalPlatformDsl {

actual fun identityHashCode(obj: Any): Int = System.identityHashCode(obj)

actual fun <T> runCoroutine(block: suspend () -> T): T {
Expand Down Expand Up @@ -128,8 +123,10 @@ actual object InternalPlatformDsl {
return@firstOrNull true

}
?: throw MockKException("can't find function $methodName(${args.joinToString(", ")}) of class ${self.javaClass.name} for dynamic call.\n" +
"If you were trying to verify a private function, make sure to provide type information to exactly match the functions signature.")
?: throw MockKException(
"can't find function $methodName(${args.joinToString(", ")}) of class ${self.javaClass.name} for dynamic call.\n" +
"If you were trying to verify a private function, make sure to provide type information to exactly match the functions signature."
)

func.javaMethod?.let { makeAccessible(it) }
return if (func.isSuspend) {
Expand Down
6 changes: 6 additions & 0 deletions modules/mockk-platform-tools/api/mockk-platform-tools.api
@@ -0,0 +1,6 @@
public final class io/mockk/platform/ValueClassSupport {
public static final field INSTANCE Lio/mockk/platform/ValueClassSupport;
public final fun getBoxedClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass;
public final fun getBoxedValue (Ljava/lang/Object;)Ljava/lang/Object;
}

39 changes: 39 additions & 0 deletions modules/mockk-platform-tools/build.gradle.kts
@@ -0,0 +1,39 @@
import buildsrc.config.Deps

plugins {
buildsrc.convention.`kotlin-multiplatform`

buildsrc.convention.`mockk-publishing`
}

description = "MockK tools that are used by other MockK modules"

val mavenName: String by extra("MockK Platform Tools")
val mavenDescription: String by extra("${project.description}")

kotlin {
jvm()

sourceSets {
val commonMain by getting {
dependencies {
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val jvmMain by getting {
dependencies {
implementation(kotlin("reflect"))
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test-junit5"))
implementation(Deps.Libs.junitJupiter)
}
}
}
}
@@ -0,0 +1,22 @@
package io.mockk.platform

import kotlin.reflect.KClass


expect object ValueClassSupport {

/**
* Underlying property value of a **`value class`** or self.
*
* The type of the return might also be a `value class`!
*/
val <T : Any> T.boxedValue: Any?

/**
* Underlying property class of a **`value class`** or self.
*
* The returned class might also be a `value class`!
*/
val KClass<*>.boxedClass: KClass<*>

}
@@ -1,26 +1,20 @@
package io.mockk
package io.mockk.platform

import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.javaField

/**
* Provides value class support in the `mockk-dsl-jvm` subproject.
*
* This is marked as internal so that it won't clash with the other class in `mockk-agent-jvm`.
*
* TODO this class is copy-pasted and should be de-duplicated, see https://github.com/mockk/mockk/issues/857
*/
internal object ValueClassSupportDsl {

actual object ValueClassSupport {

/**
* Underlying property value of a **`value class`** or self.
*
* The type of the return might also be a `value class`!
*/
val <T : Any> T.boxedValue: Any?
actual val <T : Any> T.boxedValue: Any?
@Suppress("UNCHECKED_CAST")
get() = if (!this::class.isValue_safe) {
this
Expand All @@ -33,7 +27,7 @@ internal object ValueClassSupportDsl {
*
* The returned class might also be a `value class`!
*/
val KClass<*>.boxedClass: KClass<*>
actual val KClass<*>.boxedClass: KClass<*>
get() = if (!this.isValue_safe) {
this
} else {
Expand Down
1 change: 1 addition & 0 deletions modules/mockk/build.gradle.kts
Expand Up @@ -22,6 +22,7 @@ kotlin {
api(projects.modules.mockkDsl)
api(projects.modules.mockkAgent)
api(projects.modules.mockkAgentApi)
api(projects.modules.mockkPlatformTools)

implementation(dependencies.platform(Deps.Libs.kotlinCoroutinesBom))
implementation(Deps.Libs.kotlinCoroutinesCore)
Expand Down
Expand Up @@ -25,4 +25,4 @@ annotation class MockK(
val name: String = "",
val relaxed: Boolean = false,
val relaxUnitFun: Boolean = false
)
)
Expand Up @@ -3,16 +3,15 @@ package io.mockk.impl
import io.mockk.InternalPlatformDsl
import io.mockk.MockKException
import io.mockk.StackElement
import io.mockk.boxedClass
import io.mockk.boxedValue
import io.mockk.impl.platform.CommonIdentityHashMapOf
import io.mockk.impl.platform.CommonRef
import io.mockk.impl.platform.JvmWeakConcurrentMap
import io.mockk.platform.ValueClassSupport.boxedClass
import io.mockk.platform.ValueClassSupport.boxedValue
import java.lang.ref.WeakReference
import java.lang.reflect.Modifier
import java.util.Collections
import java.util.*
import java.util.Collections.synchronizedList
import java.util.Locale
import kotlin.reflect.KClass
import kotlin.reflect.full.cast

Expand Down Expand Up @@ -83,6 +82,7 @@ actual object InternalPlatform {
"test {\n" +
" jvmArgs '-XX:-OmitStackTraceInFastThrow'\n" +
"}"

else -> "Class cast exception happened.\n" +
"Probably type information was erased.\n" +
"In this case use `hint` before call to specify " +
Expand Down