90
votes
public class KV<K, V> {
    public K key;
    public V value;
    public KV(K key, V value) {
        this.key = key;
        this.value = value;
    } 
}

I am trying to refactor the class variable value, which happens in place. That means no dialog pops up; I press enter and it tries to refactor across the entire project, including comments and what not, including:

<%--<link href="<c:url value="../core/core.css" />" />--%>

in a .jsp file. That is way too "clever" to try to refactor comments that match across the entire project. This often causes lots of bug risk, and refactoring in a Java environment is no longer safe.

The same thing was occurring in Intellij 12. Seriously, I don't need Intellij to recommend anything that is considered unsafe, or when it is not sure it is the same thing!

I can exclude the refactorings but I don't have time to evaluate five "suggestions" every time. It just raises the chance of human error: most of the time I just press enter, and woops things are refactored.

Refactoring is also a major issue in a Java environment when it sometimes tries to replace things in .js files. Seriously, this has to stop.

Without the popup dialog, I can't untick "search strings". Even if that was ticked, Intellij should never include the suggestions by default, especially when it is outside the current file. It can recommend to refactor them as well, but they should be excluded by default. That is, it should be an opt-in feature, rather than by default destroying everything.

This is a serious user experience problem with more recent so called "smart" Intellij refactoring. When refactoring JS files, I don't want to search Java files for comments or strings! Period! And vice versa!

Safety comes first! Developers that know what they are doing will search for strings themselves if needed. In a dynamic language environment it makes Intellij impossible to use, because frequently, and without any clear pattern, sometimes refactorings go through, sometimes it changes things across the project and what not.

There should be an option that says, "refactor only relative to this file or when 100% inferred!", especially for dynamic languages! For static languages it shouldn't even attempt to look for comments and strings outside the file.

I didn't mean to put it out in public, but I have raised this issue over 2 years ago in the bugtracker, but nobody paid any attention.

EDIT

For those of you that think that I might be going to far, I just tried this out:

With this class:

public class KV<K, V> {
    public K key;
    public V val;
    public KV(K key, V val) {
        this.key = key;
        this.val = val;
    }
}

And adding this to any Java class, for instance:

public class CoreConfig {
    String abc = "kv.val";
    String def = "somethingElse.val";
}

When refactoring KV.val as before, I get the following recommendations, an ENTER from disaster and something I have to evaluate and exclude one at a time. It takes effort and is just annoying and risky. It's like someone yelling out, STOP! And then ooh, nothing after a minute, frustration and a 1000 long word essay ( this ).

enter image description here

Seriously, is there a way to disable this kind of risky behaviour!? And is there any reason why this is on by default??

EDIT 20200706

Shit continues in 2020: https://youtrack.jetbrains.com/issue/IDEA-245370

2
Intellij is full of things forced upon me. If android supported other editors, I'd switch in a heartbeat. I find myself fighting the editor, instead of spending time coding. I spend time here trying to find a way to turn things off. Most of the times, they don't recommend solutions. Most the time they are saying... "WHY DO YOU HATE THIS FEATURE?"TatiOverflow
At the very least this feature should have a minimum length limit - like if I'm refactoring a variable with a common 3-letter name, it makes zero sense to search and replace that in strings and comments by default. That 3-letter sequence is overwhelmingly likely to exist in a random string if it's a large project. Ugh.Vicky Chijwani
It's now plain and simply broken. It used to be the one IDE that made sense. Not being able to turn off this terrible default behavior makes IntelliJ such a terrible tool to use, I've unknowingly created terrible seemingly unrelated bugs by simply renaming variables like IntelliJ has tought me to over years... I keep forgetting that I can't trust its refactoring at all anymore -.-yeoman
Today, it changed a Spring MVC POST mapping's path because I moved the class to a different package (!!!!!!!)yeoman
Yes, this is one of the worst feature of intellij. If I want to rename a class I can end up breaking the whole project where that class name happens to appear in strings. So if you rename the class User to MyUser it will rename everything including config files, labels, urls, paths in rest calls mapping...ACV

2 Answers

102
votes

When you press Shift + F6 (Refactor Rename) twice, it opens the dialog and you can disable "Search in comments and strings"

8
votes

And is there any reason why this is on by default??

Yes, there is. People tend to use way too many DSLs, templates and language injections these days. In plain old Java all these things mainly exist as Strings. Reflection API also represents method/class name as a String. It is not possible for any IDE to support and recognize them all, so it does it's best to provide you with a safety net against possible refactoring mistakes. If you have an excellent unit test coverage, though, then you're probably safe here.

As for comments, they often contain code samples. These code chunks become obsolete quickly during renamings, so it's helpful when IDE reminds you about their existence.

This check, of course, results in false positives sometimes. However, if you're giving your variables descriptive self-explanatory names (I mean not "var" or "val"), this is unlikely to happen. So, IDE is pushing you towards a better code style in some way.

If you're still not convinced, then follow an advice by @Meo and disable the search in strings and comments.