mirror of
https://github.com/mamoe/mirai.git
synced 2026-08-22 14:13:32 +08:00
[core] Relocate ktor-io in mirai-core-api. Fix #2381
This commit is contained in:
@@ -44,7 +44,7 @@ kotlin {
|
|||||||
implementation(project(":mirai-console-compiler-annotations"))
|
implementation(project(":mirai-console-compiler-annotations"))
|
||||||
implementation(`kotlinx-serialization-protobuf`)
|
implementation(`kotlinx-serialization-protobuf`)
|
||||||
implementation(`kotlinx-atomicfu`)
|
implementation(`kotlinx-atomicfu`)
|
||||||
compileOnly(`ktor-io`) // runtime from mirai-core-utils
|
relocateCompileOnly(`ktor-io_relocated`) // runtime from mirai-core-utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(gradleApi())
|
implementation(gradleApi())
|
||||||
implementation(gradleKotlinDsl())
|
implementation(gradleKotlinDsl())
|
||||||
|
implementation(`kotlin-reflect`)
|
||||||
implementation(kotlin("gradle-plugin-api"))
|
implementation(kotlin("gradle-plugin-api"))
|
||||||
implementation(kotlin("gradle-plugin"))
|
implementation(kotlin("gradle-plugin"))
|
||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
|
|||||||
@@ -113,7 +113,8 @@ abstract class AbstractTest {
|
|||||||
add("org.gradle.jvmargs=-Xmx512m")
|
add("org.gradle.jvmargs=-Xmx512m")
|
||||||
add("-D")
|
add("-D")
|
||||||
add("file.encoding=UTF-8")
|
add("file.encoding=UTF-8")
|
||||||
add("--stacktrace")
|
// add("--stacktrace")
|
||||||
|
add("--info")
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
@@ -165,6 +166,10 @@ abstract class AbstractTest {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
|
implementation(kotlin("reflect"))
|
||||||
|
testImplementation(kotlin("test-junit5"))
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.2")
|
||||||
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.2")
|
||||||
}
|
}
|
||||||
tasks.test {
|
tasks.test {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
private const val OkHttp = "okhttp3.OkHttp"
|
private const val OkHttp = "okhttp3.OkHttp"
|
||||||
private const val OkIO = "okio.ByteString"
|
private const val OkIO = "okio.ByteString"
|
||||||
|
|
||||||
private fun relocated(string: String): String {
|
fun relocated(string: String): String {
|
||||||
return "net.mamoe.mirai.internal.deps.$string"
|
return "net.mamoe.mirai.internal.deps.$string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,6 +59,7 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
-both(`ktor-client-okhttp`)
|
-both(`ktor-client-okhttp`)
|
||||||
-both(`okhttp3-okhttp`)
|
-both(`okhttp3-okhttp`)
|
||||||
-both(okio)
|
-both(okio)
|
||||||
|
+relocated(`ExternalResource-input`)
|
||||||
}
|
}
|
||||||
applyCodeFragment(fragment)
|
applyCodeFragment(fragment)
|
||||||
buildFile.appendText(
|
buildFile.appendText(
|
||||||
@@ -80,6 +81,7 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
+relocated(`ktor-client-okhttp`)
|
+relocated(`ktor-client-okhttp`)
|
||||||
+relocated(`okhttp3-okhttp`)
|
+relocated(`okhttp3-okhttp`)
|
||||||
+relocated(okio)
|
+relocated(okio)
|
||||||
|
+relocated(`ExternalResource-input`)
|
||||||
}
|
}
|
||||||
applyCodeFragment(fragment)
|
applyCodeFragment(fragment)
|
||||||
buildFile.appendText(
|
buildFile.appendText(
|
||||||
@@ -128,6 +130,7 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
-both(`ktor-client-okhttp`)
|
-both(`ktor-client-okhttp`)
|
||||||
-both(`okhttp3-okhttp`)
|
-both(`okhttp3-okhttp`)
|
||||||
-both(okio)
|
-both(okio)
|
||||||
|
// +relocated(`ExternalResource-input`) // Will fail with no class def found error because there is no runtime ktor-io
|
||||||
}
|
}
|
||||||
applyCodeFragment(fragment)
|
applyCodeFragment(fragment)
|
||||||
buildFile.appendText(
|
buildFile.appendText(
|
||||||
@@ -151,6 +154,7 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
+relocated(`ktor-client-okhttp`)
|
+relocated(`ktor-client-okhttp`)
|
||||||
+relocated(`okhttp3-okhttp`)
|
+relocated(`okhttp3-okhttp`)
|
||||||
+relocated(okio)
|
+relocated(okio)
|
||||||
|
+relocated(`ExternalResource-input`)
|
||||||
}
|
}
|
||||||
applyCodeFragment(fragment)
|
applyCodeFragment(fragment)
|
||||||
|
|
||||||
@@ -177,31 +181,81 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
"""
|
"""
|
||||||
package test
|
package test
|
||||||
import org.junit.jupiter.api.*
|
import org.junit.jupiter.api.*
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import kotlin.reflect.jvm.kotlinFunction
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
|
||||||
|
private val Method.signature: String
|
||||||
|
get() = buildString {
|
||||||
|
append(kotlinFunction?.toString())
|
||||||
|
return@buildString
|
||||||
|
append(kotlinFunction?.visibility?.name?.lowercase())
|
||||||
|
append(kotlinFunction?.visibility?.name?.lowercase())
|
||||||
|
append(' ')
|
||||||
|
append(returnType.canonicalName)
|
||||||
|
append(' ')
|
||||||
|
append(name)
|
||||||
|
append('(')
|
||||||
|
for (parameter in parameters) {
|
||||||
|
append(parameter.type.canonicalName)
|
||||||
|
append(' ')
|
||||||
|
append(parameter.name)
|
||||||
|
append(", ")
|
||||||
|
}
|
||||||
|
if (parameterCount != 0) {
|
||||||
|
deleteAt(lastIndex)
|
||||||
|
deleteAt(lastIndex)
|
||||||
|
}
|
||||||
|
append(')')
|
||||||
|
}
|
||||||
|
|
||||||
class MyTest {
|
class MyTest {
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
).append("\n").append("\n")
|
).append("\n").append("\n")
|
||||||
|
|
||||||
class TestCase(
|
class ClassTestCase(
|
||||||
val name: String,
|
val name: String,
|
||||||
val qualifiedClassName: String,
|
val qualifiedClassName: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
val `ktor-io` = TestCase("ktor-io ByteBufferChannel", ByteBufferChannel)
|
class FunctionTestCase(
|
||||||
val `ktor-client-core` = TestCase("ktor-client-core HttpClient", HttpClient)
|
val name: String,
|
||||||
val `ktor-client-okhttp` = TestCase("ktor-client-core OkHttp", KtorOkHttp)
|
val qualifiedClassName: String,
|
||||||
val `okhttp3-okhttp` = TestCase("okhttp3 OkHttp", OkHttp)
|
val signature: String,
|
||||||
val okio = TestCase("okio ByteString", OkIO)
|
val relocated: (FunctionTestCase.() -> FunctionTestCase)? = null,
|
||||||
|
|
||||||
class Relocated(
|
|
||||||
val testCase: TestCase
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class Both(
|
val `ktor-io` = ClassTestCase("ktor-io ByteBufferChannel", ByteBufferChannel)
|
||||||
val testCase: TestCase
|
val `ktor-client-core` = ClassTestCase("ktor-client-core HttpClient", HttpClient)
|
||||||
|
val `ktor-client-okhttp` = ClassTestCase("ktor-client-core OkHttp", KtorOkHttp)
|
||||||
|
val `okhttp3-okhttp` = ClassTestCase("okhttp3 OkHttp", OkHttp)
|
||||||
|
val okio = ClassTestCase("okio ByteString", OkIO)
|
||||||
|
val `ExternalResource-input` =
|
||||||
|
FunctionTestCase(
|
||||||
|
"ExternalResource_input",
|
||||||
|
"net.mamoe.mirai.utils.ExternalResource",
|
||||||
|
"fun net.mamoe.mirai.utils.ExternalResource.input(): io.ktor.utils.io.core.Input"
|
||||||
|
) original@{
|
||||||
|
FunctionTestCase(
|
||||||
|
"relocated ExternalResource_input",
|
||||||
|
"net.mamoe.mirai.utils.ExternalResource",
|
||||||
|
"fun net.mamoe.mirai.utils.ExternalResource.input(): ${relocated("io.ktor.utils.io.core.Input")}"
|
||||||
|
) {
|
||||||
|
this@original
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RelocatedClassTestCase(
|
||||||
|
val testCase: ClassTestCase
|
||||||
|
)
|
||||||
|
|
||||||
|
class BothClassTestCase(
|
||||||
|
val testCase: ClassTestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
private fun appendHas(name: String, qualifiedClassName: String) {
|
private fun appendHasClass(name: String, qualifiedClassName: String) {
|
||||||
result.append(
|
result.append(
|
||||||
"""
|
"""
|
||||||
@Test
|
@Test
|
||||||
@@ -212,6 +266,30 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
).append("\n")
|
).append("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun appendClassHasMethod(name: String, qualifiedClassName: String, methodSignature: String) {
|
||||||
|
result.append(
|
||||||
|
"""
|
||||||
|
@Test
|
||||||
|
fun `has ${name}`() {
|
||||||
|
val signatures = Class.forName("$qualifiedClassName").declaredMethods.map { it.signature }
|
||||||
|
assertTrue("All signatures: " + signatures.joinToString("\n")) { signatures.any { it == "$methodSignature" } }
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
).append("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun appendClassMethodNotFound(name: String, qualifiedClassName: String, methodSignature: String) {
|
||||||
|
result.append(
|
||||||
|
"""
|
||||||
|
@Test
|
||||||
|
fun `has ${name}`() {
|
||||||
|
val signatures = Class.forName("$qualifiedClassName").declaredMethods.map { it.signature }
|
||||||
|
assertFalse("All signatures: " + signatures.joinToString("\n")) { signatures.any { it == "$methodSignature" } }
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
).append("\n")
|
||||||
|
}
|
||||||
|
|
||||||
private fun appendNotFound(name: String, qualifiedClassName: String) {
|
private fun appendNotFound(name: String, qualifiedClassName: String) {
|
||||||
result.append(
|
result.append(
|
||||||
"""
|
"""
|
||||||
@@ -227,15 +305,25 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
/**
|
/**
|
||||||
* Asserts a class exists. Also asserts its relocated class does not exist.
|
* Asserts a class exists. Also asserts its relocated class does not exist.
|
||||||
*/
|
*/
|
||||||
operator fun TestCase.unaryPlus() {
|
operator fun FunctionTestCase.unaryPlus() {
|
||||||
appendHas(name, qualifiedClassName)
|
appendClassHasMethod(name, qualifiedClassName, signature)
|
||||||
|
relocated?.invoke(this)?.let { inverted ->
|
||||||
|
appendClassMethodNotFound(inverted.name, inverted.qualifiedClassName, inverted.signature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts a class exists. Also asserts its relocated class does not exist.
|
||||||
|
*/
|
||||||
|
operator fun ClassTestCase.unaryPlus() {
|
||||||
|
appendHasClass(name, qualifiedClassName)
|
||||||
appendNotFound("relocated $name", Companion.relocated(qualifiedClassName))
|
appendNotFound("relocated $name", Companion.relocated(qualifiedClassName))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts a class does not exist.
|
* Asserts a class does not exist.
|
||||||
*/
|
*/
|
||||||
operator fun TestCase.unaryMinus() {
|
operator fun ClassTestCase.unaryMinus() {
|
||||||
appendNotFound(name, qualifiedClassName)
|
appendNotFound(name, qualifiedClassName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,9 +331,9 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
/**
|
/**
|
||||||
* Asserts a relocated class exists. Also asserts the original class does not exist.
|
* Asserts a relocated class exists. Also asserts the original class does not exist.
|
||||||
*/
|
*/
|
||||||
operator fun Relocated.unaryPlus() {
|
operator fun RelocatedClassTestCase.unaryPlus() {
|
||||||
this.testCase.run {
|
this.testCase.run {
|
||||||
appendHas("relocated $name", Companion.relocated(qualifiedClassName))
|
appendHasClass("relocated $name", Companion.relocated(qualifiedClassName))
|
||||||
appendNotFound(name, qualifiedClassName)
|
appendNotFound(name, qualifiedClassName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,7 +341,7 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
/**
|
/**
|
||||||
* Asserts a relocated class does not exist.
|
* Asserts a relocated class does not exist.
|
||||||
*/
|
*/
|
||||||
operator fun Relocated.unaryMinus() {
|
operator fun RelocatedClassTestCase.unaryMinus() {
|
||||||
this.testCase.run {
|
this.testCase.run {
|
||||||
appendNotFound("relocated $name", Companion.relocated(qualifiedClassName))
|
appendNotFound("relocated $name", Companion.relocated(qualifiedClassName))
|
||||||
}
|
}
|
||||||
@@ -262,13 +350,14 @@ class CoreShadowRelocationTest : AbstractTest() {
|
|||||||
/**
|
/**
|
||||||
* Asserts both the class and its relocated one do not exist.
|
* Asserts both the class and its relocated one do not exist.
|
||||||
*/
|
*/
|
||||||
operator fun Both.unaryMinus() {
|
operator fun BothClassTestCase.unaryMinus() {
|
||||||
-this.testCase
|
-this.testCase
|
||||||
-relocated(this.testCase)
|
-relocated(this.testCase)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun relocated(testCase: TestCase): Relocated = Relocated(testCase)
|
fun relocated(testCase: ClassTestCase): RelocatedClassTestCase = RelocatedClassTestCase(testCase)
|
||||||
fun both(testCase: TestCase) = Both(testCase)
|
fun relocated(testCase: FunctionTestCase): FunctionTestCase = testCase.relocated!!(testCase)
|
||||||
|
fun both(testCase: ClassTestCase) = BothClassTestCase(testCase)
|
||||||
|
|
||||||
fun build(): String = result.append("\n}\n").toString()
|
fun build(): String = result.append("\n}\n").toString()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user