Do not retain proxy-based components for compiler plugin settings in project model (again) (KT-24444)

The previous approach didn't work because Gradle wraps the copy() result, and the leakage didn't go away.
This commit is contained in:
Yan Zhulanow
2018-08-30 22:58:22 +05:00
parent f55a52b86e
commit a434cb00c6
4 changed files with 37 additions and 17 deletions
@@ -17,13 +17,11 @@
package org.jetbrains.kotlin.allopen.ide package org.jetbrains.kotlin.allopen.ide
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginModel import org.jetbrains.kotlin.annotation.plugin.ide.*
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginModelBuilderService
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginProjectResolverExtension
interface AllOpenModel : AnnotationBasedPluginModel { interface AllOpenModel : AnnotationBasedPluginModel {
override fun copy(): AllOpenModel { override fun dump(): DumpedPluginModel {
return AllOpenModelImpl(annotations.toList(), presets.toList()) return DumpedPluginModelImpl(AllOpenModelImpl::class.java, annotations.toList(), presets.toList())
} }
} }
@@ -29,11 +29,32 @@ import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
import java.io.Serializable import java.io.Serializable
import java.lang.Exception import java.lang.Exception
interface DumpedPluginModel {
val className: String
// May contain primitives, Strings and collections of primitives/Strings
val args: Array<*>
operator fun component1() = className
operator fun component2() = args
}
class DumpedPluginModelImpl(
override val className: String,
override val args: Array<*>
) : DumpedPluginModel, Serializable {
constructor(clazz: Class<*>, vararg args: Any?) : this(clazz.canonicalName, args)
}
interface AnnotationBasedPluginModel : Serializable { interface AnnotationBasedPluginModel : Serializable {
val annotations: List<String> val annotations: List<String>
val presets: List<String> val presets: List<String>
fun copy(): AnnotationBasedPluginModel /*
Objects returned from Gradle importer are implicitly wrapped in a proxy that can potentially leak internal Gradle structures.
So we need a way to safely serialize the arbitrary annotation plugin model.
*/
fun dump(): DumpedPluginModel
val isEnabled get() = annotations.isNotEmpty() || presets.isNotEmpty() val isEnabled get() = annotations.isNotEmpty() || presets.isNotEmpty()
} }
@@ -58,7 +79,12 @@ abstract class AnnotationBasedPluginProjectResolverExtension<T : AnnotationBased
val model = resolverCtx.getExtraProject(gradleModule, modelClass) val model = resolverCtx.getExtraProject(gradleModule, modelClass)
if (model != null) { if (model != null) {
ideModule.putCopyableUserData(userDataKey, model.copy() as T) val (className, args) = model.dump()
@Suppress("UNCHECKED_CAST")
val refurbishedModel = Class.forName(className).constructors.single().newInstance(*args) as T
ideModule.putCopyableUserData(userDataKey, refurbishedModel)
} }
super.populateModuleExtraModels(gradleModule, ideModule) super.populateModuleExtraModels(gradleModule, ideModule)
@@ -17,15 +17,13 @@
package org.jetbrains.kotlin.noarg.ide package org.jetbrains.kotlin.noarg.ide
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginModel import org.jetbrains.kotlin.annotation.plugin.ide.*
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginModelBuilderService
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginProjectResolverExtension
interface NoArgModel : AnnotationBasedPluginModel { interface NoArgModel : AnnotationBasedPluginModel {
val invokeInitializers: Boolean val invokeInitializers: Boolean
override fun copy(): NoArgModel { override fun dump(): DumpedPluginModel {
return NoArgModelImpl(annotations.toList(), presets.toList(), invokeInitializers) return DumpedPluginModelImpl(NoArgModelImpl::class.java, annotations.toList(), presets.toList(), invokeInitializers)
} }
} }
@@ -17,13 +17,11 @@
package org.jetbrains.kotlin.samWithReceiver.ide package org.jetbrains.kotlin.samWithReceiver.ide
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginModel import org.jetbrains.kotlin.annotation.plugin.ide.*
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginModelBuilderService
import org.jetbrains.kotlin.annotation.plugin.ide.AnnotationBasedPluginProjectResolverExtension
interface SamWithReceiverModel : AnnotationBasedPluginModel { interface SamWithReceiverModel : AnnotationBasedPluginModel {
override fun copy(): SamWithReceiverModel { override fun dump(): DumpedPluginModel {
return SamWithReceiverModelImpl(annotations.toList(), presets.toList()) return DumpedPluginModelImpl(SamWithReceiverModelImpl::class.java, annotations.toList(), presets.toList())
} }
} }