Emacs definitely doesn't have any of the advanced refactoring and code analysis features of a Jetbrains IDE. Now, these are all mostly niche features that you'd use maybe once a month, but when you do need them, they save huge amounts of time for large code bases.
Here are some examples:
- Extract class / method / function (takes a piece of code and converts it to a class/method/free-floating function, while detecting all context dependencies and turning them to parameters or fields; also generates the proper constructors to populate those fields; and calls the right constructors/methods passing those parameters from context)
- Extract parameter / field (takes a local variable and makes it a parameter/field, and identifies all callers to propagate a value)
- Versions of the previous extractions that can go through a deeper call stack, automatically propagating along all functions along the way; essentially identical to using the same thing repeatedly, but in a single step
- Data flow to/from here (takes a variable and tells you something like 'the value here is coming from this parameter, which was populated from that field, which is assigned to in these two places; in the first place, it is assigned from this IO function; in the second place it is set to the value of this parameter which is populated from this constant; for "from", it is doing the same, but for all downstream uses of this value)
Emacs definitely has those, in the same way that VSCode has them, ie via extensions. Emacs has LSP builtin now I believe, so these things are easier to setup
If you know of an Emacs extension that does these, I would be very happy to know about it. These days I'm programming 100% in Emacs for various reasons, so I looked quite a bit (though it's true that was a few years ago now, so maybe some have turned up).
LSP itself certainly doesn't support this, though they can probably be built on top of it with some effort. For that matter, I also don't think VSCode supports them, though I have used Emacs far far more than that.
Here are some examples:
- Extract class / method / function (takes a piece of code and converts it to a class/method/free-floating function, while detecting all context dependencies and turning them to parameters or fields; also generates the proper constructors to populate those fields; and calls the right constructors/methods passing those parameters from context)
- Extract parameter / field (takes a local variable and makes it a parameter/field, and identifies all callers to propagate a value)
- Versions of the previous extractions that can go through a deeper call stack, automatically propagating along all functions along the way; essentially identical to using the same thing repeatedly, but in a single step
- Data flow to/from here (takes a variable and tells you something like 'the value here is coming from this parameter, which was populated from that field, which is assigned to in these two places; in the first place, it is assigned from this IO function; in the second place it is set to the value of this parameter which is populated from this constant; for "from", it is doing the same, but for all downstream uses of this value)