From 849712b4932ef57d2af91f98e8bc961c110ad942 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 4 Sep 2022 13:18:30 +0200 Subject: [PATCH 01/12] create new module for platform implementations, and move ValueClassSupport into it (deleting the duplicated versions in Android and DSL modules) --- modules/mockk-agent-android/build.gradle.kts | 2 + .../io/mockk/ValueClassSupportAndroid.kt | 68 ------------------- .../io/mockk/proxy/android/advice/Advice.kt | 2 +- modules/mockk-agent/build.gradle.kts | 1 + .../kotlin/io/mockk/ValueClassSupport.kt | 68 ------------------- .../io/mockk/proxy/jvm/advice/Interceptor.kt | 2 +- modules/mockk-dsl/build.gradle.kts | 1 + .../kotlin/io/mockk/InternalPlatformDsl.kt | 3 +- modules/mockk-platform-tools/build.gradle.kts | 39 +++++++++++ .../io/mockk/platform/ValueClassSupport.kt | 22 ++++++ .../io/mockk/platform/ValueClassSupport.kt} | 16 ++--- modules/mockk/build.gradle.kts | 1 + .../kotlin/io/mockk/impl/annotations/MockK.kt | 2 +- .../kotlin/io/mockk/impl/InternalPlatform.kt | 4 +- .../instantiation/JvmMockFactoryHelper.kt | 2 + settings.gradle.kts | 1 + 16 files changed, 80 insertions(+), 154 deletions(-) delete mode 100644 modules/mockk-agent-android/src/main/kotlin/io/mockk/ValueClassSupportAndroid.kt delete mode 100644 modules/mockk-agent/src/jvmMain/kotlin/io/mockk/ValueClassSupport.kt create mode 100644 modules/mockk-platform-tools/build.gradle.kts create mode 100644 modules/mockk-platform-tools/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt rename modules/{mockk-dsl/src/jvmMain/kotlin/io/mockk/ValueClassSupportDsl.kt => mockk-platform-tools/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt} (82%) diff --git a/modules/mockk-agent-android/build.gradle.kts b/modules/mockk-agent-android/build.gradle.kts index 9275bca15..515fd7485 100644 --- a/modules/mockk-agent-android/build.gradle.kts +++ b/modules/mockk-agent-android/build.gradle.kts @@ -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}") diff --git a/modules/mockk-agent-android/src/main/kotlin/io/mockk/ValueClassSupportAndroid.kt b/modules/mockk-agent-android/src/main/kotlin/io/mockk/ValueClassSupportAndroid.kt deleted file mode 100644 index b139cd1b6..000000000 --- a/modules/mockk-agent-android/src/main/kotlin/io/mockk/ValueClassSupportAndroid.kt +++ /dev/null @@ -1,68 +0,0 @@ -package io.mockk - -import kotlin.reflect.KClass -import kotlin.reflect.KProperty1 -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.jvm.internal.KotlinReflectionInternalError -import kotlin.reflect.jvm.isAccessible -import kotlin.reflect.jvm.javaField - -// TODO this class is copy-pasted and should be de-duplicated -// see https://github.com/mockk/mockk/issues/857 - -/** - * Underlying property value of a **`value class`** or self. - * - * The type of the return might also be a `value class`! - */ -val T.boxedValue: Any? - @Suppress("UNCHECKED_CAST") - get() = if (!this::class.isValue_safe) { - this - } else { - (this::class as KClass).boxedProperty.get(this) - } - -/** - * Underlying property class of a **`value class`** or self. - * - * The returned class might also be a `value class`! - */ -val KClass<*>.boxedClass: KClass<*> - get() = if (!this.isValue_safe) { - this - } else { - this.boxedProperty.returnType.classifier as KClass<*> - } - -private val valueClassFieldCache = mutableMapOf, KProperty1>() - -/** - * Underlying property of a **`value class`**. - * - * The underlying property might also be a `value class`! - */ -private val KClass.boxedProperty: KProperty1 - get() = if (!this.isValue_safe) { - throw UnsupportedOperationException("$this is not a value class") - } else { - @Suppress("UNCHECKED_CAST") - valueClassFieldCache.getOrPut(this) { - // value classes always have exactly one property with a backing field - this.declaredMemberProperties.first { it.javaField != null }.apply { isAccessible = true } - } as KProperty1 - } - -/** - * Returns `true` if calling [KClass.isValue] is safe. - * - * (In some instances [KClass.isValue] can throw an exception.) - */ -private val KClass.isValue_safe: Boolean - get() = try { - this.isValue - } catch (_: UnsupportedOperationException) { - false - } catch (_: KotlinReflectionInternalError) { - false - } diff --git a/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt b/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt index 4c4dd594f..4b07ba8c9 100644 --- a/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt +++ b/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt @@ -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 diff --git a/modules/mockk-agent/build.gradle.kts b/modules/mockk-agent/build.gradle.kts index a660bc601..a528425c5 100644 --- a/modules/mockk-agent/build.gradle.kts +++ b/modules/mockk-agent/build.gradle.kts @@ -24,6 +24,7 @@ kotlin { dependencies { api(projects.modules.mockkAgentApi) implementation(kotlin("reflect")) + implementation(projects.modules.mockkPlatformTools) } } val commonTest by getting { diff --git a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/ValueClassSupport.kt b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/ValueClassSupport.kt deleted file mode 100644 index b139cd1b6..000000000 --- a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/ValueClassSupport.kt +++ /dev/null @@ -1,68 +0,0 @@ -package io.mockk - -import kotlin.reflect.KClass -import kotlin.reflect.KProperty1 -import kotlin.reflect.full.declaredMemberProperties -import kotlin.reflect.jvm.internal.KotlinReflectionInternalError -import kotlin.reflect.jvm.isAccessible -import kotlin.reflect.jvm.javaField - -// TODO this class is copy-pasted and should be de-duplicated -// see https://github.com/mockk/mockk/issues/857 - -/** - * Underlying property value of a **`value class`** or self. - * - * The type of the return might also be a `value class`! - */ -val T.boxedValue: Any? - @Suppress("UNCHECKED_CAST") - get() = if (!this::class.isValue_safe) { - this - } else { - (this::class as KClass).boxedProperty.get(this) - } - -/** - * Underlying property class of a **`value class`** or self. - * - * The returned class might also be a `value class`! - */ -val KClass<*>.boxedClass: KClass<*> - get() = if (!this.isValue_safe) { - this - } else { - this.boxedProperty.returnType.classifier as KClass<*> - } - -private val valueClassFieldCache = mutableMapOf, KProperty1>() - -/** - * Underlying property of a **`value class`**. - * - * The underlying property might also be a `value class`! - */ -private val KClass.boxedProperty: KProperty1 - get() = if (!this.isValue_safe) { - throw UnsupportedOperationException("$this is not a value class") - } else { - @Suppress("UNCHECKED_CAST") - valueClassFieldCache.getOrPut(this) { - // value classes always have exactly one property with a backing field - this.declaredMemberProperties.first { it.javaField != null }.apply { isAccessible = true } - } as KProperty1 - } - -/** - * Returns `true` if calling [KClass.isValue] is safe. - * - * (In some instances [KClass.isValue] can throw an exception.) - */ -private val KClass.isValue_safe: Boolean - get() = try { - this.isValue - } catch (_: UnsupportedOperationException) { - false - } catch (_: KotlinReflectionInternalError) { - false - } diff --git a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt index 1ce1673cf..bf792c463 100644 --- a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt +++ b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt @@ -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 diff --git a/modules/mockk-dsl/build.gradle.kts b/modules/mockk-dsl/build.gradle.kts index 4324bd3cf..f7dca9a4e 100644 --- a/modules/mockk-dsl/build.gradle.kts +++ b/modules/mockk-dsl/build.gradle.kts @@ -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 { diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt index 7ad64fc0f..4976a488d 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -1,6 +1,6 @@ package io.mockk -import io.mockk.ValueClassSupportDsl.boxedClass +import io.mockk.platform.ValueClassSupport.boxedClass import java.lang.reflect.AccessibleObject import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method @@ -13,7 +13,6 @@ import kotlin.reflect.KProperty1 import kotlin.reflect.KType import kotlin.reflect.KTypeParameter 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 diff --git a/modules/mockk-platform-tools/build.gradle.kts b/modules/mockk-platform-tools/build.gradle.kts new file mode 100644 index 000000000..64b253dbb --- /dev/null +++ b/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 Platform Tools" + +val mavenName: String by extra("MockK Core") +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) + } + } + } +} diff --git a/modules/mockk-platform-tools/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-platform-tools/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt new file mode 100644 index 000000000..03a418128 --- /dev/null +++ b/modules/mockk-platform-tools/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt @@ -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.boxedValue: Any? + + /** + * Underlying property class of a **`value class`** or self. + * + * The returned class might also be a `value class`! + */ + val KClass<*>.boxedClass: KClass<*> + +} diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/ValueClassSupportDsl.kt b/modules/mockk-platform-tools/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt similarity index 82% rename from modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/ValueClassSupportDsl.kt rename to modules/mockk-platform-tools/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt index 9ad287209..701f245ba 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/ValueClassSupportDsl.kt +++ b/modules/mockk-platform-tools/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt @@ -1,4 +1,4 @@ -package io.mockk +package io.mockk.platform import kotlin.reflect.KClass import kotlin.reflect.KProperty1 @@ -6,21 +6,15 @@ 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.boxedValue: Any? + actual val T.boxedValue: Any? @Suppress("UNCHECKED_CAST") get() = if (!this::class.isValue_safe) { this @@ -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 { diff --git a/modules/mockk/build.gradle.kts b/modules/mockk/build.gradle.kts index d672d1387..09c52ec71 100644 --- a/modules/mockk/build.gradle.kts +++ b/modules/mockk/build.gradle.kts @@ -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) diff --git a/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt b/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt index 737730e86..c7a3d5cf1 100644 --- a/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt +++ b/modules/mockk/src/commonMain/kotlin/io/mockk/impl/annotations/MockK.kt @@ -25,4 +25,4 @@ annotation class MockK( val name: String = "", val relaxed: Boolean = false, val relaxUnitFun: Boolean = false -) \ No newline at end of file +) diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt index 4b2dc598a..774ba3fd5 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt @@ -3,8 +3,8 @@ 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.platform.ValueClassSupport.boxedValue +import io.mockk.platform.ValueClassSupport.boxedClass import io.mockk.impl.platform.CommonIdentityHashMapOf import io.mockk.impl.platform.CommonRef import io.mockk.impl.platform.JvmWeakConcurrentMap diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt index b08b9250d..6095e65e3 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt @@ -1,6 +1,8 @@ package io.mockk.impl.instantiation import io.mockk.* +import io.mockk.platform.ValueClassSupport.boxedValue +import io.mockk.platform.ValueClassSupport.boxedClass import io.mockk.impl.InternalPlatform import io.mockk.impl.stub.Stub import io.mockk.proxy.MockKInvocationHandler diff --git a/settings.gradle.kts b/settings.gradle.kts index d53d10207..c653860db 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,6 +14,7 @@ include( ":modules:mockk", ":modules:mockk-agent-api", ":modules:mockk-agent", + ":modules:mockk-platform-tools", ":modules:mockk-dsl", ":test-modules:client-tests", From acda8d35bd5e8e630296433e41b122b6323e784c Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 4 Sep 2022 13:21:47 +0200 Subject: [PATCH 02/12] update API dumps --- .../mockk-agent-android/api/mockk-agent-android.api | 5 ----- modules/mockk-agent/api/mockk-agent.api | 5 ----- .../api/mockk-platform-tools.api | 6 ++++++ .../performance-tests/api/performance-tests.api | 12 ++++++++++++ 4 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 modules/mockk-platform-tools/api/mockk-platform-tools.api create mode 100644 test-modules/performance-tests/api/performance-tests.api diff --git a/modules/mockk-agent-android/api/mockk-agent-android.api b/modules/mockk-agent-android/api/mockk-agent-android.api index 7ba2bd2ea..f1432b778 100644 --- a/modules/mockk-agent-android/api/mockk-agent-android.api +++ b/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; diff --git a/modules/mockk-agent/api/mockk-agent.api b/modules/mockk-agent/api/mockk-agent.api index f6faa7f05..a29884c89 100644 --- a/modules/mockk-agent/api/mockk-agent.api +++ b/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 ()V public static fun chooseClassLoadingStrategy (Ljava/lang/Class;)Lnet/bytebuddy/dynamic/loading/ClassLoadingStrategy; diff --git a/modules/mockk-platform-tools/api/mockk-platform-tools.api b/modules/mockk-platform-tools/api/mockk-platform-tools.api new file mode 100644 index 000000000..afb31b52d --- /dev/null +++ b/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; +} + diff --git a/test-modules/performance-tests/api/performance-tests.api b/test-modules/performance-tests/api/performance-tests.api new file mode 100644 index 000000000..af9b41c9a --- /dev/null +++ b/test-modules/performance-tests/api/performance-tests.api @@ -0,0 +1,12 @@ +public class io/mockk/performance/JmhTest { + public fun ()V + public final fun noMockOrStub (Lorg/openjdk/jmh/infra/Blackhole;)V + public final fun simpleMock (Lorg/openjdk/jmh/infra/Blackhole;)V + public final fun simpleMockAndStub (Lorg/openjdk/jmh/infra/Blackhole;)V +} + +public final class io/mockk/performance/JmhTest$MockedClass { + public fun ()V + public final fun mockedFun ()Ljava/lang/String; +} + From 7d4b31c64dd88ce90032200df953facbe795e26e Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 4 Sep 2022 14:04:03 +0200 Subject: [PATCH 03/12] delete performance-tests.api (will be resolved by https://github.com/mockk/mockk/pull/914) --- .../performance-tests/api/performance-tests.api | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 test-modules/performance-tests/api/performance-tests.api diff --git a/test-modules/performance-tests/api/performance-tests.api b/test-modules/performance-tests/api/performance-tests.api deleted file mode 100644 index af9b41c9a..000000000 --- a/test-modules/performance-tests/api/performance-tests.api +++ /dev/null @@ -1,12 +0,0 @@ -public class io/mockk/performance/JmhTest { - public fun ()V - public final fun noMockOrStub (Lorg/openjdk/jmh/infra/Blackhole;)V - public final fun simpleMock (Lorg/openjdk/jmh/infra/Blackhole;)V - public final fun simpleMockAndStub (Lorg/openjdk/jmh/infra/Blackhole;)V -} - -public final class io/mockk/performance/JmhTest$MockedClass { - public fun ()V - public final fun mockedFun ()Ljava/lang/String; -} - From d1ce726ad025403d68d194719dd01ef2a731c01a Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 4 Sep 2022 14:58:31 +0200 Subject: [PATCH 04/12] update name & description --- modules/mockk-platform-tools/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mockk-platform-tools/build.gradle.kts b/modules/mockk-platform-tools/build.gradle.kts index 64b253dbb..8cdd813a2 100644 --- a/modules/mockk-platform-tools/build.gradle.kts +++ b/modules/mockk-platform-tools/build.gradle.kts @@ -6,9 +6,9 @@ plugins { buildsrc.convention.`mockk-publishing` } -description = "MockK Platform Tools" +description = "MockK tools that are used by other MockK modules" -val mavenName: String by extra("MockK Core") +val mavenName: String by extra("MockK Platform Tools") val mavenDescription: String by extra("${project.description}") kotlin { From df2ccd4f3f8575554c3083b957bc3b0e36827c98 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Sun, 4 Sep 2022 15:00:33 +0200 Subject: [PATCH 05/12] formatting --- .../kotlin/io/mockk/InternalPlatformDsl.kt | 16 +++++++--------- .../kotlin/io/mockk/impl/InternalPlatform.kt | 8 ++++---- .../impl/instantiation/JvmMockFactoryHelper.kt | 4 ++-- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt index 4976a488d..2a770e534 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -1,26 +1,22 @@ package io.mockk 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.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 runCoroutine(block: suspend () -> T): T { @@ -127,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) { diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt index 774ba3fd5..acec6e63f 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt @@ -3,16 +3,15 @@ package io.mockk.impl import io.mockk.InternalPlatformDsl import io.mockk.MockKException import io.mockk.StackElement -import io.mockk.platform.ValueClassSupport.boxedValue -import io.mockk.platform.ValueClassSupport.boxedClass 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 @@ -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 " + diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt index 6095e65e3..32a565e94 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt @@ -1,10 +1,9 @@ package io.mockk.impl.instantiation import io.mockk.* -import io.mockk.platform.ValueClassSupport.boxedValue -import io.mockk.platform.ValueClassSupport.boxedClass import io.mockk.impl.InternalPlatform import io.mockk.impl.stub.Stub +import io.mockk.platform.ValueClassSupport.boxedClass import io.mockk.proxy.MockKInvocationHandler import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method @@ -129,6 +128,7 @@ object JvmMockFactoryHelper { val returnTypeIsUnit = when { kotlinFunc != null -> kotlinFunc.returnType.toString() == "kotlin.Unit" + else -> returnType == Void.TYPE } From 1badf459e9cfcd34f717167f66a4621a799d9d36 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Sep 2022 17:39:51 +0200 Subject: [PATCH 06/12] rename mockk-platform-tools -> mockk-core --- modules/mockk-agent-android/build.gradle.kts | 2 +- modules/mockk-agent/build.gradle.kts | 2 +- .../api/mockk-core.api} | 0 modules/{mockk-platform-tools => mockk-core}/build.gradle.kts | 4 ++-- .../commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt | 0 .../src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt | 0 modules/mockk-dsl/build.gradle.kts | 2 +- modules/mockk/build.gradle.kts | 2 +- settings.gradle.kts | 2 +- 9 files changed, 7 insertions(+), 7 deletions(-) rename modules/{mockk-platform-tools/api/mockk-platform-tools.api => mockk-core/api/mockk-core.api} (100%) rename modules/{mockk-platform-tools => mockk-core}/build.gradle.kts (86%) rename modules/{mockk-platform-tools => mockk-core}/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt (100%) rename modules/{mockk-platform-tools => mockk-core}/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt (100%) diff --git a/modules/mockk-agent-android/build.gradle.kts b/modules/mockk-agent-android/build.gradle.kts index 515fd7485..b566cd44d 100644 --- a/modules/mockk-agent-android/build.gradle.kts +++ b/modules/mockk-agent-android/build.gradle.kts @@ -45,7 +45,7 @@ dependencies { api(projects.modules.mockkAgentApi) api(projects.modules.mockkAgent) - implementation(projects.modules.mockkPlatformTools) + implementation(projects.modules.mockkCore) implementation(kotlin("reflect")) implementation("com.linkedin.dexmaker:dexmaker:${buildsrc.config.Deps.Versions.dexmaker}") diff --git a/modules/mockk-agent/build.gradle.kts b/modules/mockk-agent/build.gradle.kts index a528425c5..f97c3058a 100644 --- a/modules/mockk-agent/build.gradle.kts +++ b/modules/mockk-agent/build.gradle.kts @@ -24,7 +24,7 @@ kotlin { dependencies { api(projects.modules.mockkAgentApi) implementation(kotlin("reflect")) - implementation(projects.modules.mockkPlatformTools) + implementation(projects.modules.mockkCore) } } val commonTest by getting { diff --git a/modules/mockk-platform-tools/api/mockk-platform-tools.api b/modules/mockk-core/api/mockk-core.api similarity index 100% rename from modules/mockk-platform-tools/api/mockk-platform-tools.api rename to modules/mockk-core/api/mockk-core.api diff --git a/modules/mockk-platform-tools/build.gradle.kts b/modules/mockk-core/build.gradle.kts similarity index 86% rename from modules/mockk-platform-tools/build.gradle.kts rename to modules/mockk-core/build.gradle.kts index 8cdd813a2..305f13417 100644 --- a/modules/mockk-platform-tools/build.gradle.kts +++ b/modules/mockk-core/build.gradle.kts @@ -6,9 +6,9 @@ plugins { buildsrc.convention.`mockk-publishing` } -description = "MockK tools that are used by other MockK modules" +description = "MockK functionality that is used by other MockK modules" -val mavenName: String by extra("MockK Platform Tools") +val mavenName: String by extra("MockK Core") val mavenDescription: String by extra("${project.description}") kotlin { diff --git a/modules/mockk-platform-tools/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt similarity index 100% rename from modules/mockk-platform-tools/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt rename to modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt diff --git a/modules/mockk-platform-tools/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt similarity index 100% rename from modules/mockk-platform-tools/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt rename to modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt diff --git a/modules/mockk-dsl/build.gradle.kts b/modules/mockk-dsl/build.gradle.kts index f7dca9a4e..b1007d768 100644 --- a/modules/mockk-dsl/build.gradle.kts +++ b/modules/mockk-dsl/build.gradle.kts @@ -20,7 +20,7 @@ kotlin { implementation(dependencies.platform(Deps.Libs.kotlinCoroutinesBom)) implementation(Deps.Libs.kotlinCoroutinesCore) implementation(kotlin("reflect")) - implementation(projects.modules.mockkPlatformTools) + implementation(projects.modules.mockkCore) } } val commonTest by getting { diff --git a/modules/mockk/build.gradle.kts b/modules/mockk/build.gradle.kts index 09c52ec71..7c53e65ad 100644 --- a/modules/mockk/build.gradle.kts +++ b/modules/mockk/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { api(projects.modules.mockkDsl) api(projects.modules.mockkAgent) api(projects.modules.mockkAgentApi) - api(projects.modules.mockkPlatformTools) + api(projects.modules.mockkCore) implementation(dependencies.platform(Deps.Libs.kotlinCoroutinesBom)) implementation(Deps.Libs.kotlinCoroutinesCore) diff --git a/settings.gradle.kts b/settings.gradle.kts index c653860db..e291ec322 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,7 +14,7 @@ include( ":modules:mockk", ":modules:mockk-agent-api", ":modules:mockk-agent", - ":modules:mockk-platform-tools", + ":modules:mockk-core", ":modules:mockk-dsl", ":test-modules:client-tests", From f45e129974ad15ee4eadc9e4e66d7e458e7ac63b Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Sep 2022 18:12:53 +0200 Subject: [PATCH 07/12] refactor value class helper code to be in ValueClassSupport - remove InternalPlatformDsl.unboxClass util (it's the same as ValueClassSupport.boxedClass) - move InternalPlatformDsl.boxCast to ValueClassSupport --- .../io/mockk/platform/ValueClassSupport.kt | 14 +++++++++++-- .../io/mockk/platform/ValueClassSupport.kt | 14 +++++++++++++ .../src/commonMain/kotlin/io/mockk/API.kt | 20 +++++++++--------- .../kotlin/io/mockk/InternalPlatformDsl.kt | 21 ------------------- .../commonMain/kotlin/io/mockk/Matchers.kt | 9 ++++---- .../kotlin/io/mockk/InternalPlatformDsl.kt | 14 ------------- .../recording/JvmSignatureValueGenerator.kt | 6 +++--- 7 files changed, 44 insertions(+), 54 deletions(-) diff --git a/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt index 03a418128..121d0602e 100644 --- a/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt +++ b/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt @@ -13,10 +13,20 @@ expect object ValueClassSupport { val T.boxedValue: Any? /** - * Underlying property class of a **`value class`** or self. + * Underlying property class of a **`value class`**, or self. * - * The returned class might also be a `value class`! + * The result might also be a value class! So check recursively, if necessary. */ val KClass<*>.boxedClass: KClass<*> + /** + * Normally this simply casts [arg] to `T` + * + * However, if `T` is a `value class` (of type [cls]) this will construct a new instance of the + * value class, and set [arg] as the value. + */ + fun boxCast( + cls: KClass<*>, + arg: Any, + ): T } diff --git a/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt index 701f245ba..f398b07d2 100644 --- a/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt +++ b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt @@ -3,6 +3,7 @@ package io.mockk.platform import kotlin.reflect.KClass import kotlin.reflect.KProperty1 import kotlin.reflect.full.declaredMemberProperties +import kotlin.reflect.full.primaryConstructor import kotlin.reflect.jvm.isAccessible import kotlin.reflect.jvm.javaField @@ -63,4 +64,17 @@ actual object ValueClassSupport { } catch (_: UnsupportedOperationException) { false } + + @Suppress("UNCHECKED_CAST") + actual fun boxCast( + cls: KClass<*>, + arg: Any, + ): T { + return if (cls.isValue) { + val constructor = cls.primaryConstructor!!.apply { isAccessible = true } + constructor.call(arg) as T + } else { + arg as T + } + } } diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt index defebb02a..ea8d26597 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt @@ -4,9 +4,9 @@ package io.mockk import io.mockk.InternalPlatformDsl.toStr import io.mockk.MockKGateway.* +import io.mockk.platform.ValueClassSupport.boxedClass import kotlin.coroutines.Continuation import kotlin.reflect.KClass -import io.mockk.* /** * Exception thrown by library @@ -536,14 +536,14 @@ object MockKDsl { inline fun internalUnmockkConstructor(vararg classes: KClass<*>) { classes.forEach { MockKGateway.implementation().constructorMockFactory.clear( - it, - MockKGateway.ClearOptions( - answers = true, - recordedCalls = true, - childMocks = true, - verificationMarks = true, - exclusionRules = true - ) + it, + MockKGateway.ClearOptions( + answers = true, + recordedCalls = true, + childMocks = true, + verificationMarks = true, + exclusionRules = true + ) ) MockKCancellationRegistry .subRegistry(MockKCancellationRegistry.Type.CONSTRUCTOR) @@ -3553,7 +3553,7 @@ interface TypedMatcher { return when { argumentType.simpleName === null -> true else -> { - val unboxedClass = InternalPlatformDsl.unboxClass(argumentType) + val unboxedClass = argumentType.boxedClass return unboxedClass.isInstance(arg) } } diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt index 461c3247d..c01d0bd17 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -1,7 +1,6 @@ package io.mockk import kotlin.coroutines.Continuation -import kotlin.reflect.KClass expect object InternalPlatformDsl { fun identityHashCode(obj: Any): Int @@ -36,26 +35,6 @@ expect object InternalPlatformDsl { fun counter(): InternalCounter fun coroutineCall(lambda: suspend () -> T): CoroutineCall - - /** - * Get the [KClass] of the single value that a `value class` contains. - * - * The result might also be a value class! So check recursively, if necessary. - * - * @return [KClass] of boxed value, if this is `value class`, else [cls]. - */ - internal fun unboxClass(cls: KClass<*>): KClass<*> - - /** - * Normally this simply casts [arg] to `T` - * - * However, if `T` is a `value class` (of type [cls]) this will construct a new instance of the - * value class, and set [arg] as the value. - */ - internal fun boxCast( - cls: KClass<*>, - arg: Any, - ): T } interface CoroutineCall { diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt index 100cad605..a5c0a7250 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt @@ -2,6 +2,7 @@ package io.mockk import io.mockk.InternalPlatformDsl.toArray import io.mockk.InternalPlatformDsl.toStr +import io.mockk.platform.ValueClassSupport import kotlin.math.min import kotlin.reflect.KClass @@ -56,7 +57,7 @@ data class FunctionMatcher( override fun equivalent(): Matcher = ConstantMatcher(true) override fun match(arg: T?): Boolean { - return if(arg == null) { + return if (arg == null) { false } else { try { @@ -79,7 +80,7 @@ data class FunctionWithNullableArgMatcher( override fun match(arg: T?): Boolean = matchingFunc(arg) override fun checkType(arg: Any?): Boolean { - if(arg == null) { + if (arg == null) { return true } @@ -125,7 +126,7 @@ data class CaptureNullableMatcher( override fun match(arg: T?): Boolean = true override fun checkType(arg: Any?): Boolean { - if(arg == null) { + if (arg == null) { return true } @@ -149,7 +150,7 @@ data class CapturingSlotMatcher( captureSlot.isNull = true } else { captureSlot.isNull = false - captureSlot.captured = InternalPlatformDsl.boxCast(argumentType, arg) + captureSlot.captured = ValueClassSupport.boxCast(argumentType, arg) } captureSlot.isCaptured = true } diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt index 2a770e534..575cd15b2 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -215,20 +215,6 @@ actual object InternalPlatformDsl { actual fun coroutineCall(lambda: suspend () -> T): CoroutineCall = JvmCoroutineCall(lambda) - actual fun unboxClass(cls: KClass<*>): KClass<*> = cls.boxedClass - - @Suppress("UNCHECKED_CAST") - internal actual fun boxCast( - cls: KClass<*>, - arg: Any, - ): T { - return if (cls.isValue) { - val constructor = cls.primaryConstructor!!.apply { isAccessible = true } - constructor.call(arg) as T - } else { - arg as T - } - } } class JvmCoroutineCall(private val lambda: suspend () -> T) : CoroutineCall { diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt index 6428d98e7..d69e9dfba 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt @@ -1,9 +1,9 @@ package io.mockk.impl.recording -import io.mockk.InternalPlatformDsl import io.mockk.impl.instantiation.AbstractInstantiator import io.mockk.impl.instantiation.AnyValueGenerator -import java.util.Random +import io.mockk.platform.ValueClassSupport.boxedClass +import java.util.* import kotlin.reflect.KClass import kotlin.reflect.full.cast import kotlin.reflect.full.primaryConstructor @@ -17,7 +17,7 @@ class JvmSignatureValueGenerator(val rnd: Random) : SignatureValueGenerator { ): T { if (cls.isValue) { - val valueCls = InternalPlatformDsl.unboxClass(cls) + val valueCls = cls.boxedClass val valueSig = signatureValue(valueCls, anyValueGeneratorProvider, instantiator) val constructor = cls.primaryConstructor!!.apply { isAccessible = true } From 5b1f61cd8fbc345fd0f70d6085301a37223ecb7d Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Sep 2022 18:20:10 +0200 Subject: [PATCH 08/12] revert boxCast refactor (while it respects value classes, it is not specifically for value classes, so it makes more sense to be in a general util class) --- .../kotlin/io/mockk/platform/ValueClassSupport.kt | 10 ---------- .../kotlin/io/mockk/platform/ValueClassSupport.kt | 12 ------------ .../kotlin/io/mockk/InternalPlatformDsl.kt | 12 ++++++++++++ .../src/commonMain/kotlin/io/mockk/Matchers.kt | 3 +-- .../jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt | 13 ++++++++++++- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt index 121d0602e..f57d52e96 100644 --- a/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt +++ b/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt @@ -19,14 +19,4 @@ expect object ValueClassSupport { */ val KClass<*>.boxedClass: KClass<*> - /** - * Normally this simply casts [arg] to `T` - * - * However, if `T` is a `value class` (of type [cls]) this will construct a new instance of the - * value class, and set [arg] as the value. - */ - fun boxCast( - cls: KClass<*>, - arg: Any, - ): T } diff --git a/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt index f398b07d2..92d564641 100644 --- a/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt +++ b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt @@ -65,16 +65,4 @@ actual object ValueClassSupport { false } - @Suppress("UNCHECKED_CAST") - actual fun boxCast( - cls: KClass<*>, - arg: Any, - ): T { - return if (cls.isValue) { - val constructor = cls.primaryConstructor!!.apply { isAccessible = true } - constructor.call(arg) as T - } else { - arg as T - } - } } diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt index c01d0bd17..2e5457344 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -1,6 +1,7 @@ package io.mockk import kotlin.coroutines.Continuation +import kotlin.reflect.KClass expect object InternalPlatformDsl { fun identityHashCode(obj: Any): Int @@ -35,6 +36,17 @@ expect object InternalPlatformDsl { fun counter(): InternalCounter fun coroutineCall(lambda: suspend () -> T): CoroutineCall + + /** + * Normally this simply casts [arg] to `T` + * + * However, if `T` is a `value class` (of type [cls]) this will construct a new instance of the + * value class, and set [arg] as the value. + */ + fun boxCast( + cls: KClass<*>, + arg: Any, + ): T } interface CoroutineCall { diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt index a5c0a7250..9a8e49981 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/Matchers.kt @@ -2,7 +2,6 @@ package io.mockk import io.mockk.InternalPlatformDsl.toArray import io.mockk.InternalPlatformDsl.toStr -import io.mockk.platform.ValueClassSupport import kotlin.math.min import kotlin.reflect.KClass @@ -150,7 +149,7 @@ data class CapturingSlotMatcher( captureSlot.isNull = true } else { captureSlot.isNull = false - captureSlot.captured = ValueClassSupport.boxCast(argumentType, arg) + captureSlot.captured = InternalPlatformDsl.boxCast(argumentType, arg) } captureSlot.isCaptured = true } diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt index 575cd15b2..1297cb212 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -1,6 +1,5 @@ package io.mockk -import io.mockk.platform.ValueClassSupport.boxedClass import kotlinx.coroutines.runBlocking import java.lang.reflect.AccessibleObject import java.lang.reflect.InvocationTargetException @@ -215,6 +214,18 @@ actual object InternalPlatformDsl { actual fun coroutineCall(lambda: suspend () -> T): CoroutineCall = JvmCoroutineCall(lambda) + @Suppress("UNCHECKED_CAST") + actual fun boxCast( + cls: KClass<*>, + arg: Any, + ): T { + return if (cls.isValue) { + val constructor = cls.primaryConstructor!!.apply { isAccessible = true } + constructor.call(arg) as T + } else { + arg as T + } + } } class JvmCoroutineCall(private val lambda: suspend () -> T) : CoroutineCall { From 2213135d2a9d22ca7626e85bd7e55403f2a42225 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Sep 2022 18:26:09 +0200 Subject: [PATCH 09/12] make boxCast internal again --- .../src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt | 2 +- .../src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt index 2e5457344..d461ba618 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -43,7 +43,7 @@ expect object InternalPlatformDsl { * However, if `T` is a `value class` (of type [cls]) this will construct a new instance of the * value class, and set [arg] as the value. */ - fun boxCast( + internal fun boxCast( cls: KClass<*>, arg: Any, ): T diff --git a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt index 1297cb212..0bcb6d982 100644 --- a/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt +++ b/modules/mockk-dsl/src/jvmMain/kotlin/io/mockk/InternalPlatformDsl.kt @@ -215,7 +215,7 @@ actual object InternalPlatformDsl { actual fun coroutineCall(lambda: suspend () -> T): CoroutineCall = JvmCoroutineCall(lambda) @Suppress("UNCHECKED_CAST") - actual fun boxCast( + internal actual fun boxCast( cls: KClass<*>, arg: Any, ): T { From 0e9ff0ceecbb7173f14c3f41c0e07af97aa255a9 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Sep 2022 18:27:00 +0200 Subject: [PATCH 10/12] update package after subproject rename --- .../jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt | 2 +- .../kotlin/io/mockk/{platform => core}/ValueClassSupport.kt | 2 +- .../kotlin/io/mockk/{platform => core}/ValueClassSupport.kt | 2 +- modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt | 2 +- .../src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt | 4 ++-- .../io/mockk/impl/instantiation/JvmMockFactoryHelper.kt | 2 +- .../io/mockk/impl/recording/JvmSignatureValueGenerator.kt | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) rename modules/mockk-core/src/commonMain/kotlin/io/mockk/{platform => core}/ValueClassSupport.kt (94%) rename modules/mockk-core/src/jvmMain/kotlin/io/mockk/{platform => core}/ValueClassSupport.kt (98%) diff --git a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt index bf792c463..71ee71812 100644 --- a/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt +++ b/modules/mockk-agent/src/jvmMain/kotlin/io/mockk/proxy/jvm/advice/Interceptor.kt @@ -1,6 +1,6 @@ package io.mockk.proxy.jvm.advice -import io.mockk.platform.ValueClassSupport.boxedValue +import io.mockk.core.ValueClassSupport.boxedValue import io.mockk.proxy.MockKInvocationHandler import java.lang.reflect.Method import java.util.concurrent.Callable diff --git a/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/commonMain/kotlin/io/mockk/core/ValueClassSupport.kt similarity index 94% rename from modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt rename to modules/mockk-core/src/commonMain/kotlin/io/mockk/core/ValueClassSupport.kt index f57d52e96..c5b50db58 100644 --- a/modules/mockk-core/src/commonMain/kotlin/io/mockk/platform/ValueClassSupport.kt +++ b/modules/mockk-core/src/commonMain/kotlin/io/mockk/core/ValueClassSupport.kt @@ -1,4 +1,4 @@ -package io.mockk.platform +package io.mockk.core import kotlin.reflect.KClass diff --git a/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/core/ValueClassSupport.kt similarity index 98% rename from modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt rename to modules/mockk-core/src/jvmMain/kotlin/io/mockk/core/ValueClassSupport.kt index 92d564641..797926d90 100644 --- a/modules/mockk-core/src/jvmMain/kotlin/io/mockk/platform/ValueClassSupport.kt +++ b/modules/mockk-core/src/jvmMain/kotlin/io/mockk/core/ValueClassSupport.kt @@ -1,4 +1,4 @@ -package io.mockk.platform +package io.mockk.core import kotlin.reflect.KClass import kotlin.reflect.KProperty1 diff --git a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt index ea8d26597..0378e1a0e 100644 --- a/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt +++ b/modules/mockk-dsl/src/commonMain/kotlin/io/mockk/API.kt @@ -4,7 +4,7 @@ package io.mockk import io.mockk.InternalPlatformDsl.toStr import io.mockk.MockKGateway.* -import io.mockk.platform.ValueClassSupport.boxedClass +import io.mockk.core.ValueClassSupport.boxedClass import kotlin.coroutines.Continuation import kotlin.reflect.KClass diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt index acec6e63f..b5cf10450 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/InternalPlatform.kt @@ -6,8 +6,8 @@ import io.mockk.StackElement 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 io.mockk.core.ValueClassSupport.boxedClass +import io.mockk.core.ValueClassSupport.boxedValue import java.lang.ref.WeakReference import java.lang.reflect.Modifier import java.util.* diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt index 32a565e94..06a82a767 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/instantiation/JvmMockFactoryHelper.kt @@ -3,7 +3,7 @@ package io.mockk.impl.instantiation import io.mockk.* import io.mockk.impl.InternalPlatform import io.mockk.impl.stub.Stub -import io.mockk.platform.ValueClassSupport.boxedClass +import io.mockk.core.ValueClassSupport.boxedClass import io.mockk.proxy.MockKInvocationHandler import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method diff --git a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt index d69e9dfba..20a0278e2 100644 --- a/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt +++ b/modules/mockk/src/jvmMain/kotlin/io/mockk/impl/recording/JvmSignatureValueGenerator.kt @@ -2,7 +2,7 @@ package io.mockk.impl.recording import io.mockk.impl.instantiation.AbstractInstantiator import io.mockk.impl.instantiation.AnyValueGenerator -import io.mockk.platform.ValueClassSupport.boxedClass +import io.mockk.core.ValueClassSupport.boxedClass import java.util.* import kotlin.reflect.KClass import kotlin.reflect.full.cast From 6a8ff9f0e60bb1baf6537a807b913bc0aa288665 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Sep 2022 19:01:18 +0200 Subject: [PATCH 11/12] fix import after mockk-core package rename --- .../src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt b/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt index 4b07ba8c9..0225d7a6b 100644 --- a/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt +++ b/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/advice/Advice.kt @@ -5,7 +5,7 @@ package io.mockk.proxy.android.advice -import io.mockk.platform.ValueClassSupport.boxedValue +import io.mockk.core.ValueClassSupport.boxedValue import io.mockk.proxy.MockKAgentException import io.mockk.proxy.android.AndroidMockKMap import io.mockk.proxy.android.MethodDescriptor From c986928dd30be8890e8b4caaacfe045cf1484b81 Mon Sep 17 00:00:00 2001 From: Adam <897017+aSemy@users.noreply.github.com> Date: Tue, 6 Sep 2022 19:20:05 +0200 Subject: [PATCH 12/12] update API dump --- modules/mockk-core/api/mockk-core.api | 4 ++-- modules/mockk-dsl/api/mockk-dsl.api | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/mockk-core/api/mockk-core.api b/modules/mockk-core/api/mockk-core.api index afb31b52d..e7cebf530 100644 --- a/modules/mockk-core/api/mockk-core.api +++ b/modules/mockk-core/api/mockk-core.api @@ -1,5 +1,5 @@ -public final class io/mockk/platform/ValueClassSupport { - public static final field INSTANCE Lio/mockk/platform/ValueClassSupport; +public final class io/mockk/core/ValueClassSupport { + public static final field INSTANCE Lio/mockk/core/ValueClassSupport; public final fun getBoxedClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass; public final fun getBoxedValue (Ljava/lang/Object;)Ljava/lang/Object; } diff --git a/modules/mockk-dsl/api/mockk-dsl.api b/modules/mockk-dsl/api/mockk-dsl.api index 10ced70e5..cecd93fc8 100644 --- a/modules/mockk-dsl/api/mockk-dsl.api +++ b/modules/mockk-dsl/api/mockk-dsl.api @@ -326,7 +326,6 @@ public final class io/mockk/InternalPlatformDsl { public final fun toArray (Ljava/lang/Object;)[Ljava/lang/Object; public final fun toStr (Ljava/lang/Object;)Ljava/lang/String; public final fun unboxChar (Ljava/lang/Object;)Ljava/lang/Object; - public final fun unboxClass (Lkotlin/reflect/KClass;)Lkotlin/reflect/KClass; } public abstract interface class io/mockk/InternalRef {