Kotlin コンパニオンオブジェクトはそれに含まれるクラスをロードしようとすると常に作成されるため、拡張ポイントの実装は低コストで作成できるはずです。 プラグインでの過度なクラスのロードは IDE の起動にとって大きな問題です。
不正なパターン:
class KotlinDocumentationProvider : AbstractDocumentationProvider(), ExternalDocumentationProvider {
companion object {
private val LOG = Logger.getInstance(KotlinDocumentationProvider::class.java)
private val javaDocumentProvider = JavaDocumentationProvider()
}
}
以下の KotlinDocumentationProvider は plugin.xml に登録されている拡張機能です。
<lang.documentationProvider language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.KotlinDocumentationProvider"
order="first"/>
この例では new KotlinDocumentationProvider() を呼び出されるだけで JavaDocumentationProvider がディスクからロードされます。
拡張ポイント実装内の Kotlin コンパニオンオブジェクトはロガーと単純な定数のみを含むことができます。
その他の宣言は過剰なクラスのロードや大量のリソース (例: TokenSet、Regex など) の早期初期化を
発生させる可能性があります。
@JvmStatic が付いた宣言もコンパニオンオブジェクトに余計なクラスを生成するため、計算コストが高くなる可能性があることに注意してください。
このような宣言はコンパニオンオブジェクトに格納するのではなく、トップレベルにするか、オブジェクト内に格納する必要があります。
宣言をトップレベルに移動します。
// 適切。トップレベルの fun を使用
internal fun mnRunConfigurationType(): MnRunConfigurationType = runConfigurationType<MnRunConfigurationType>()
internal class MnRunConfigurationType : ConfigurationType {
companion object { // 不適切
fun getInstance(): MnRunConfigurationType = runConfigurationType<MnRunConfigurationType>()
}
...
前:
internal class SpringBootImportsFileType : LanguageFileType(SPILanguage.INSTANCE, true) {
companion object {
val FILE_TYPE = SpringBootImportsFileType()
...
後:
internal object SpringBootImportsFileType : LanguageFileType(SPILanguage.INSTANCE, true) {
...
plugin.xml で INSTANCE fieldName を使用します。
<fileType name="Spring Boot Imports"
fieldName="INSTANCE"
implementationClass="com.intellij.spring.boot.spi.SpringBootImportsFileType"/>
前:
class AntActionsUsagesCollector : CounterUsagesCollector() {
override fun getGroup(): EventLogGroup = GROUP
companion object {
private val GROUP = EventLogGroup("build.ant.actions", 1)
@JvmField
val runSelectedBuildAction = GROUP.registerEvent("RunSelectedBuild")
}
}
後:
object AntActionsUsagesCollector : CounterUsagesCollector() {
override fun getGroup(): EventLogGroup = GROUP
private val GROUP = EventLogGroup("build.ant.actions", 1)
@JvmField
val runSelectedBuildAction = GROUP.registerEvent("RunSelectedBuild")
}
2023.3 の新機能です