Disable componentN() generation in data classes


#1

When writing libraries which will primarily be used from Java, I found that the the generated componentN() functions were irritating when accessing data classes from Java.


  • Is it possible to implement destructuring declarations without these methods?
  • (or) Is it possible to have an @NoDestructuring annotation which would disable this feature?

#2

Could you specify a case where componentN would be a hindrance?


#3

Well, the functions only make sense when using them from Kotlin. A Java/Groovy/(any other JVM language) user will just be confused when they see something like this when trying out a library:


#4

It seems to be IDE problem, not language problem. The solution could be to introduce a special method annotation like @Generated which is added automatically to generated methods and force IDE not to list such methods in some cases.


#5

That would also work, even though I would prefer a @NoDestructuring annotation.
If the compiler could figure out if a class is a data class (the data modifier could be stored in the metadata of the class) destructuring could be supported without the componentN() functions.


#6

bump


#7

Please don’t bump. Especially not after such a short period of time with no response. The only reason to revive a topic is to ask how things are going with (possible) future features, and even then you have to be patient and wait at least a couple of weeks or months.

About your proposal: It won’t work because how would the Kotlin compiler know the order of the properties if they are not numbered?

I think @darksnake’s suggestion will solve the issue. Unfortunately the standard @Generated annotation is not retained in class files. There is already an issue for the standard annotation, but I guess it cannot be implemented.

The best thing you can do is create an issue for IntelliJ IDEA where you request that the code completion for Java stops showing certain Kotlin functions. I suppose they must only not be shown immediately, and that they will be shown when pressed harder as you might want to invoke them from Java too for some reason.


#8

Well, for generated (synthetic) methods Java offer magical $ symbol, which hides generated (in the byte-code) methods from the normal Java-code.

I’d say Kotlin could generate methods component$1, component$2, which it still could use for destruction (those names are not supposed to be used directly). No problems here.

If user decides to provide such method (e.g. like it is done for Map.Entry), she still could write component1 manually - and it will be visible from Java (unless it’s an extension method, of course)


#9

True, this could have been better names for the generated methods. I don’t know if this naming scheme has been considered. It is probably too late to switch to these names because of backward compatibility.


#10

The $ symbol doesn’t actually hide anything from Java code. Its special meaning is only a convention; it doesn’t have any impact on the behavior of the compiler and IDE.


#11

I agree with you.

Annotate generated method should be helpful for test coverage and mutation test.


#12

Yes, an @Generated annotation seems to be the cleanest solution! I’ll create an issue in the issue tracker this evening.

Edit: KT-20284