Can the companion object of an extension point implementation contain functions?

I get this warning from DevKit when attempting to declare a companion object on an extension point implementation:

Companion objects in IDE extension implementations may only contain a logger and constants

I’m aware this is to avoid performance hits, but is it truly inadvisable to place static functions within said object, as opposed to, say, properties with backing fields? Even with only constants, the object is generated in the bytecode anyway; how much could a few functions cost?

We implemented this inspection to discourage fat extension classes. Extension instances are created in batches when EP_NAME queried and it is better to not put APIs to extensions.

When you do this in Kotlin:

class SomeExtension {
  companion object { }
}

in JVM there will be 2 classes defined on loading of SomeExtension.

Also in Kotlin it is more idiomatic to use top level declarations and not companion objects.

This only applies to IntelliJ Platform plugins and not important anywhere else, but rather important for IDE startup times when it loads thousands of related classes.

in JVM there will be 2 classes defined on loading of SomeExtension.

This is also true even if the companion object only contains constants and loggers, wouldn’t it?

class SomeExtension {
    companion object {  // Still loaded, private or not.
        const val C = 299_792_458
    }
}

(At this point the question is just about understanding things.)

If constants and loggers are considered cheap, then how much does a function cost compared to them?

JVM will locate and load classes required for declarations of funs, so this leads to a lot more classes read (but not initialised yet) from disk.

Constants and logger is a trade-off that does not bring the overhead usually.

1 Like