I was wondering if it was possible to start a cons...
# intellij
j
I was wondering if it was possible to start a constructive discussion on refactoring support for kotlin in intellij. Around the place a lot of people have been expressing concerns to me about the perceived poor support for refactoring. Refactoring was a massive feature in favour of intellij when editing java, but basic features seem to be fat less powerful or correct when editing kotlin. This is so important when working on larger production codebases. Using java, refactorings were SO reliable... I'm not sure this is the case anymore. Things like - extract method or variable not working reliably, moving things around messes up imports... I sort of feel that it's not up to people who pay good money to raise youtrack tickets, which may never be actioned, to get this kind of expected functionality. I'm also surprised that jetbrains developers don't see these same problems in their own kotlin codebases. I dont work on Android, nor use Spring - I'm just talking about kotlin, and kotlin+java. Am I alone, in which case - thanks for reading... or maybe we can discuss some issues and JB can talk about their thoughts on the matter too. Please read this in the spirit in which it is intended, about constructively raising what I see to be a bit of an issue in IDEA, a product I've been using since 2003 or 2004, I think!
🙏 2
14
💯 7
a
cc @Anton Yalyshev [JB]
c
I totally agree. I have been an idea user since version 1.0 (and 2.0 beta), and i was always suprised how bug free idea was. kotlin support on the other hand is very buggy and the refactorings don’t have most of the cleverness that idea java refactorings have. and the really complex edge cases that are all handler superbly in java are not handled at all in kotlin
f
It's not limited to IntelliJ Kotlin, Kotlin itself is similar. It seems that the concentration overall is on new features, not on correctness, performance, and stability. I find myself resorting back to Java more and more (and then encounter so many corner cases that I go back to Kotlin 😄).
👍 3
👍🏾 1
c
iirc one of the design goals of kotlin was that compilation should be as fast as java. it would be great if idea autocompletion (or just editing) was also as fast as java
🙏 1
j
Would it be OK to start a different thread for the kotlin language stability conversation - its a different thing and it'd hard to stay focused if there are multiple conversations in one thread.
👍 1
c
ok. i guess it depends if you consider the kotlin plugin a part of kotlin or idea. it sure uses a lot of code from the kotlin repo but technically its now part of idea.
I used to file a ton of youtrack issues about refactoring bugs, but nowadays i just git commit before every refactoring and work around the bugs
j
Please discuss away! .....
a
Hi James, I’m from IntelliJ Kotlin plugin team. I will be happy to discuss any point regarding refactoring support, but I should ask in advance what exactly you wanted to discuss? JetBrains developers know about that problems, we have understanding of reasons and we have a plan of how we will solve it. I can give more details about this, or about other questions you wanted to discuss here
c
I would really like to know about the reasons and the plan.
j
It would be great to understand the reasons (I'm guessing here, but the fact that jetbrains is covering so many things - android, space, etc etc - feels like it must be a factor) - and the thought process - kotlin is literally*your* language - how can it be acceptable to have such poor refactoring support, especially if you know about the issues. - IDEA grew its market share in large part due to such capability. Knowing about problems and being up front about them is very valuable, and gives users reassurance that they are not being ignored. "Hey IDEA2022.1 is out - we know you still can't move a method in kotlin, we are working on Dagger stuff - that's coming next release". It would be also great if you can enumerate the issues that you feel are highest priority in kotlin refactorings, and howyou plan to address them (and in what timeframe). As an open source contributor, I'm perfectly used to people asking for lots and not really getting that its just down to free time and my own priortisation. As a long-time all-Products subscriber, i feel this should work a bit differently. Thanks!
c
for example what is the reason that this 4 year old ticket is idle for > 7 months? (actually its idle for a year) https://youtrack.jetbrains.com/issue/KTIJ-10606/Support-moving-a-function-to-an-instance-class
a
Let me describe the general reason first. IDE support was being developed along with rapidly developing language. New technologies, features, approaches occurred every half a year. For example, LightClasses - the way how Kotlin interact with Java and how Java sees Kotlin code. Rename refactoring relies on this technology a lot. As you know, one can not invent a good effective solution right from the first time. We were evolving LightClasses during years on the language level, we adapted IntelliJ Platform making it more multi-lingual. There were other new things, like Multiplatform, language feature, etc., which weren’t considered at the beginning of IDE support implementation. So, it wasn’t possible to provide the same quality of refactoring as for Java. Java was much more established foundation, and we had much better understanding of how it should be properly supported. Couple of years ago we could definitely say that Kotlin passed the “rapidly developing start-up” phase, and knowledge about correct and effective IDE support became more defined. Since that time we focused the major part of our efforts on tooling stabilisation. It was not only fixing of particular cases but was also rewriting/refactoring of some subsystems and even migration of entire plugin codebase from Kotlin to IntelliJ repository. The latest thing was a really huge work, but it gave us much more capabilities for stabilisation and amplified/speeded-up our work. Today the stabilisation is ongoing, and also we transferred part of our resources to development of a new IntelliJ plugin, that will be based on K2 compiler. Actually, it also can be seen as stabilisation. Subsystems with bad quality and big amounts of hacks are being re-written from scratch, with respect to all previous experience. Good quality code will be just migrated. Technologies like LightClasses, MPP, all language features are taken into account from the very beginning of the plugin development. Now the plugin with a very limited set of feature is being tested inside JetBrains. In 2023 we plan to announce its pre-view version.
👌 2
j
Thanks for the update. As a software developer I do understand that it is practically impossible to get things right first time, and second time is often worse. However, as a power user of a system, that im often using for 8+ hours a day, it is really really bad to get performance or functional regressions. I'm sure you have a bunch of approval tests for kotlin refactorings - I don't know how many are failing/ignored now, but it must be quite a few. Please consider the balance between features and reliability. I'm sure you do already... but an unreliable feature is just the worst. Please be transparent about known failings. Moving codebases together when they are actually one thing is great for improving feedback loops, and it makes sense that you've taken steps to improve your internal feedback loops. Have you considered introducing feedback loops externally? I haven't really thought this through, but having a "last refactoring didn't work" keybinding (opt in maybe) may be a way to get faster feedback about real world use cases, idk. I also don't want to cross threads... but reliable and stable refactoring to me is FAR more important than adding firstNotNullOfOrNull to the stdlib, because it saves me orders of magnitude more time and mental effort. Kotlin is a good language, please be kind to it with the tooling. IDEA made Java programming easy - even for large systems, it should do the same for kotlin. I'm looking forward to the new stability, but I can't say I'm not a bit nervous, based on recent history, that it will be just differently a bit unreliable. Thanks for taking the time to respond.
m
@Anton Yalyshev [JB] what's the best way for the community to help? I used to open a lot of YouTrack issues but is that still helping? Sometimes I feel like you should have so many that it might create more noise than helping especially if the ultimate solution is to rewrite part of the subsystem (and therefore invalidate a bunch of YouTrack all at once). Do issues still help? Or would you prefer something else? (what?)
👍 1
a
Good bug reports with self-contained code samples are always welcome. At the very least we should know what doesn’t work right now. When the subsystem is rewritten, all bug reports will be rechecked and either actualized or closed and converted to regression tests.
👍 1
a
Yep. As well as voting, commenting, updating existing issues help us better orient in and analyse our issue-tracker. Rising more general questions here is also welcome. And thank you for bringing and discussing this topic. On the preview stage of K2-based plugin we will be grateful for any kind of feedback.
👍 6
c
will you make any efforts to make the current kotlin plugin bug free, or will we have to wait for the plugin rewrite with a preview some time next year? i mean the k2 compiler is also pretty unstable still.
for the last 4 years there was always something on the horizon that will happen next year and make the kotlin idea plugin finally less buggy and on par with java refactorings. you should really communicate clearly in your idea announcements that its currently does not work so well for kotlin and that it will take until next year to be better. I mean for everyone using idea with kotlin in the last 4 years the course that the plugin took was really very suprising.
3
o
While I'm also having issues with the current IDE plugin from time to time, and I am aware that it is not on par with Java support, in my view it is generally pretty stable and enormously useful. The refactoring I'm using most of the time is renaming and signature changes (adding parameters and such). Which works quite well for me. Indexing, symbol lookup, syntax checking and method discovery are the most important features for me. Not always perfect, could be faster, but overall absolutely useful. So my picture is not dark at all and I'm still seeing issues getting fixed from release to release. Given the circumstances, the balance between legacy support and new (K2) development seems quite reasonable for me. And while the one thing that haunts me frequently (KTIJ-22253 – IDE wrongly flagging to opt in) is still not fixed yet, the reason seems to be that it is hard to tackle, not that it has been deprioritized. So thanks to everyone involved for steadily advancing Kotlin support in the IDE!
🙏 1
☝️ 1
r
@Anton Yalyshev [JB] Do you guys review and action the crash reports from the plugin submitted via the IDE? I find the general pattern is that some versions of the plugin crash all the time, then the next version is better (but never perfect), and then the next is back to crashing all the time again.
Current stable version
222-1.7.20-Beta-release-102-IJ3345.90
seems to be on the better end of the spectrum.
a
Do you guys review and action the crash reports from the plugin submitted via the IDE?
Yes, of course. This crash-reporting system is not as good as full-fledged bug-tracker, in terms of requests management, but at the same, that reports contain all diagnostics information that IDE can give. It’s quite useful in case of UI freezes and code analysis failures, when the bug is caused by a combination of many circumstances and barely can be reproduced.
there was always something on the horizon that will happen next year
Well, 3-5 years ago our team had another approach in the product development - we were trying to fix as much reports as possible. And almost always it was quite a local fixes, patches, hacks, which solved only that particular use-cases. At some point, we began to realize that in our conditions (product. that is built on rapidly developing technologies) this approach will not effective in a long term. And besides quick fixes we have to solve not urgent but big/long and important tasks. For example, moving the plugin codebase from the Kotlin to the IntelliJ repo took ~ 2 years (including complete integration to the new infrastructure and solving new issues, like building EAP-compiler-based plugins for EAP of IJ IDEA). Performance, Find Usages, Scripting support optimisations, usually take months, but it solves not a single but classes of problems. And also regarding refactoring, it was better to organise quality sprints for them (Inline_1, Inline_2, Change_signature). We couldn’t pay attention on all of them, but we choose these ones with help of our users feedback in the Youtrack. To sum up, we found that an effective approach, in our case, may be to allocate 1/2 team efforts on the K2-based plugin, 1/4 team on urgent fixes and 1/4 on long-term tasks, like I pointed above, for K1-based plugin
c
that is probably the best long term strategy. but I think you may be not aware how many refactorings currently are broken (produce code that does not compile), and I think you should treat all those bugs as release critical because it affects the every day work life of your users.
a
We are aware: https://youtrack.jetbrains.com/issues/KTIJ?q=Subsystems:%20%7BIDE.%20Refactorings*%7D%20%23bug%20-Resolved Sorry, I don’t think we can treat 500 bugs as release critical all at the same time.
c
makes sense but what are you going to do about those 500 bugs? will they be fixed in a later 2022.2.x release?
a
It would probably take like several years, realistically. But of course many of those bugs are not major so it’s unlikely that we will fix 100% of them, given that there are many other important tasks.
c
sure theres a difference between “something does not look perfect” and an refactoring that produces uncompilable code. the latter should probably be critical
m
My, contrary, feedback would be that, while many things do fall apart and I can't really rely on the stability of kotlin ecosystem, the refactorings themself are the richest and most useful than any other IDE/language combo I used, as well as I have not encountered any issue with them. I have not really used java in IJ (I was .net back then), but if it's that of a gap, it must be a kind of magic to write java. Or maybe I still do not rely on the refactorings as much as I should 🤔
f
It must be the latter. Extremely simple refactorings are going to break your code entirely. Here's an extremely simple thing:
Copy code
class C {
  companion object
}
Now use any generate method refactoring (e.g.
equals and hashCode
). 🤕 This is just an example from the top of my head. There are other trivial things, like this which I just encountered in Gradle:
Copy code
val source = source.get()
fs.copy {
  from(archives.zipTree(source))
  into(target)
}
Doing an
inline variable
on
source
results in:
Copy code
fs.copy {
  from(archives.zipTree(this.source.get()))
  into(target)
}
Obviously this won't compile, because
this
is not
this
in the
copy
context. It's sometimes almost like the Kotlin plugin does not understand Kotlin at all. Nothing like that ever happens in Java in IJ. IJ goes way beyond trivial refactorings in Java (and all of them actually work) like those available to us in IJ for Kotlin today, the inspections there are also much more useful. Honestly, if Java wouldn't be such a pita to write I'd switch back just because of the much, much, much better IJ support for pretty much everything.
o
Hmm, I can reproduce the first refactoring problem, but it seems a bit exotic as the empty
companion object
does not make any sense. With
companion object {}
, refactoring starts to work. Would the second one still happen if there had not been two identically named, but different instances of
source
, say
sourceProvider
and
source
?
f
Empty companion objects are sadly still important in libraries to allow other users to write static extension functions. Once the namespace feature lands this practice can die. I don't know, but finding workarounds is not the way to go here. The point is that these kind of things work reliably in Java, but they don't work in Kotlin.
1
o
It's not about finding workarounds. I'm trying to figure out why the way we experience the situation is that different.
c
I think what makes my idea kotlin experience different from some other people is how much I am used to refactoring and quickfixes. my whole programming style is influenced by years of perfect refactoring capabilities with idea and java
o
Yes, that must be a factor. I did Java in the old days, then different stuff, then Kotlin. So the way I put things together might not be as refactoring-centric as it would have been if I had switched directly from J to K. Another consequence seems to be that I'm quite allergic to any kind of ceremony, which always comes up once I have to touch Java stuff. 🙂
c
for context: java refactoring support has 355 unresolved bugs, but some of them are from 2008. https://youtrack.jetbrains.com/issues/IDEA?q=Subsystem:%20%7BJava.%20Refactorings%7D%20%23bug%20-Resolved
and some are about real edge case of very complex refactorings that don’t exist for kotlin
o
That's the thing with metrics: There is no weight associated with individual issues, so just counting them means summing up fleas and elephants. If we had something like, "OK, this issue/feature leads to x hours of total developer time wasted/saved", that would make a difference. And then there's duplicates and stale issues (identified or not).
c
sure I just wanted to put the 520 in context
👍 1
the context being: when I use idea with java for a week I will not notice on single refactoring bug, so 355 unresolved bugs can mean everything is fine.
plus one 1