[testFramework] plugin spec: use class' classloader in include(Package)ClassFile

GitOrigin-RevId: 8eb5d54dbd266bb4f6d5fb4d2de12dc5f49df60f
This commit is contained in:
Vadim Salavatov
2025-07-21 11:43:07 +00:00
committed by intellij-monorepo-bot
parent 1cffa7bc3b
commit 7a6eb99117
3 changed files with 19 additions and 14 deletions
@@ -38,10 +38,12 @@ class PluginSpec internal constructor(
val body: String?,
val classFiles: List<String>,
val packageClassFiles: List<String>,
val classFiles: List<PluginSpecClassReference>,
val packageClassFiles: List<PluginSpecClassReference>,
)
data class PluginSpecClassReference(val className: String, val classLoader: ClassLoader? = null)
class PluginSpecBuilder(
var id: String? = null,
var name: String? = null,
@@ -73,8 +75,8 @@ class PluginSpecBuilder(
@Language("XML") var body: String? = null,
internal var classFiles: List<String> = emptyList(),
internal var packageClassFiles: List<String> = emptyList(),
internal var classFiles: List<PluginSpecClassReference> = emptyList(),
internal var packageClassFiles: List<PluginSpecClassReference> = emptyList(),
) {
fun build(): PluginSpec = PluginSpec(
id = id, name = name, packagePrefix = packagePrefix, implementationDetail = implementationDetail, isSeparateJar = isSeparateJar,
@@ -3,6 +3,7 @@ package com.intellij.platform.testFramework.plugins
import com.intellij.ide.plugins.ModuleLoadingRule
import org.intellij.lang.annotations.Language
import org.jetbrains.annotations.ApiStatus
import java.util.concurrent.atomic.AtomicInteger
private val idCounter = AtomicInteger()
@@ -90,16 +91,18 @@ fun PluginSpecBuilder.pluginAlias(id: String) {
pluginAliases += id
}
inline fun <reified T> PluginSpecBuilder.includeClassFile(): Unit = includeClassFile(T::class.java.name)
inline fun <reified T> PluginSpecBuilder.includeClassFile(): Unit =
includeClassFile(T::class.java.name, T::class.java.classLoader)
fun PluginSpecBuilder.includeClassFile(classFqn: String) {
classFiles += classFqn
fun PluginSpecBuilder.includeClassFile(classFqn: String, classLoader: ClassLoader? = null) {
classFiles += PluginSpecClassReference(classFqn, classLoader)
}
inline fun <reified T> PluginSpecBuilder.includePackageClassFiles(): Unit = includePackageClassFiles(T::class.java.packageName)
inline fun <reified T> PluginSpecBuilder.includePackageClassFiles(): Unit =
includePackageClassFiles(T::class.java.packageName, T::class.java.classLoader)
fun PluginSpecBuilder.includePackageClassFiles(packageFqn: String) {
packageClassFiles += packageFqn
fun PluginSpecBuilder.includePackageClassFiles(packageFqn: String, classLoader: ClassLoader? = null) {
packageClassFiles += PluginSpecClassReference(packageFqn, classLoader)
}
fun PluginSpecBuilder.dependsIntellijModulesLang(): Unit = depends("com.intellij.modules.lang")
@@ -182,13 +182,13 @@ private fun ContentModuleSpec.buildContentDir(dir: DirectoryContentBuilder, conf
}
private fun PluginSpec.buildClasses(dir: DirectoryContentBuilder) {
for (classFqn in classFiles) {
val url = this::class.java.classLoader.getResource(classFqn.replace('.', '/') + ".class")
for ((classFqn, classLoader) in classFiles) {
val url = (classLoader ?: this::class.java.classLoader).getResource(classFqn.replace('.', '/') + ".class")
?: error("$classFqn not found")
dir.dirsFile(classFqn.replace('.', '/') + ".class", url.readBytes())
}
for (pkg in packageClassFiles) {
for (url in this::class.java.classLoader.getResources(pkg.replace('.', '/'))) {
for ((pkg, classLoader) in packageClassFiles) {
for (url in (classLoader ?: this::class.java.classLoader).getResources(pkg.replace('.', '/'))) {
require(url.toString().endsWith('/')) { url }
val entries = url.readText().splitToSequence("\n").filter { !it.isBlank() }
for (entry in entries) {