JnRouvignac
Joined 11 years ago
Joined 11 years ago
Actually the comment is wrong in that case using BigDecimal.valueOf() is better since it could reuse the immutable object, so that is better for memory. I'll rework the samples to make it more explicit.
However I was wondering where a refactoring tool would need an IR. I found one: a CFG. For this, I need a three-address code representation. As a hypothesis, let's suppose I can build one that is independent from the input language. Once I have found how to refactor it, I then need to describe which code must be rewritten to what, in the input langage. This is the part where I find it very hard to do. I have the impression it will fall short here.
That would be an interesting experiment :)
One reason I can think of is that for GCC all input languages are converted to the same intermediate representation (IR). From there, it's easy to apply the same optimisations, generated code, etc.
For refactoring tools, I have never heard of such IR. The benefits of going for an IR are not obvious either. The drawbacks are huge: a lot more code, difficulty to build an IR rich enough to represent the semantics of all input languages, and there's an extra mapping to go back to the original code by keeping indentation and formatting.
While it is more obvious for GCC: you need another representation than the AST to compile to assembly, optimisations are run on the IR, there is no need to take care of the original source formatting.
Languages also have very subtle differences in meaning/behaviour making it harder to reuse refactorings across languages.
Maybe it's possible to go with your idea, but I think it would require a big team working on it. Who's willing to spend the money or the time when the current approach seems satisfactory?
"Good style", "best practice", all of this comes from an observation made by somebody who can justify it is good practice by some real evidence. If you were using if-elseif like a switch statement, then maybe there should be an else. If the if conditions are not related, then I don't see why there should necessarily be one.
Please enlighten me by pointing to the relevant online resources.
I did not try, but I don't expect so. Why? Because AFAIK, Lombok enabled code is not valid java code. So I don't expect that Eclipse JDT (basis for AutoRefactor) will be able to parse it. The only way to make this work would be to work on the code generated by Lombok, then do the round trip back to the original Lombok source. Patch welcome!
If someone tries it out, I would be happy to read the feedback.
BTW I think AutoValue could work better thanks to the use of standard annotation pre processor.
I can explain for me: why do I fix the code like this? I spend a lot of time reading code to understand it, fix bugs, add features. Sometimes I read code and realize it is unnecessarily complicated, written in a not very concise way. Which increases the burden of reading code. This time that I spent, I do not want to have to spend it again, so I put back in the code the knowledge I gained from it. Martin Fowler argues for this too: http://martinfowler.com/articles/preparatory-refactoring-exa...
That my selfish reason for doing it. It's also the boy scout rule: http://programmer.97things.oreilly.com/wiki/index.php/The_Bo...
Finally another quote from Donald Knuth that I am summing up as "code for human beings, not for machines": https://en.m.wikiquote.org/wiki/Donald_Knuth (see the quote from "literate programming")
Somebody commented such refactoring rules are part of their coding rules. I argue such rules are rarely expressed anywhere. Furthermore, if we were to write them down, I think there would be too many of them for anyone to remember. Putting them all in a tool relieves the team as a whole: I get tired to repeat the same things over all code reviews. Sometimes, I am even so tired that I forget to comment on some of them. Sometimes I even violate the rules I put in the tool because I was thinking so much of the problem I was trying to solve!
Another problem are inherited code base where the amount of technical debt is so overwhelming that it's impractical to fix it by hand.
Finally, a last reason could be to upgrade automatically to new language features that make code more concise or more readable. Think about the introduction of generics in Java 5, project Coin features in Java 7 or lambdas in Java 8.
You can also think about it as good code hygiene, pretty much like a good code indentation and formatting is a requirement for green field projects today.
I have a few other reasons outlined here: http://autorefactor.org/
I nearly forgot one use case! I know a company transcompiling code from COBOL to Java. The resulting code is so huge (hundreds of thousands of LOC) and dirty (you would not believe it) that they are considering using AutoRefactor to clean up the mess.
Why should there always be a else to an if-elseif?
Secondly, in the original if-else, the if in the else clause does not have a else. Why is it not a problem for you? It seems contradictory...
Concerning the not null case, I agree this one is very subjective. I hesitated a lot before adding it. It is not as broad as what you think it is. It is only touching if statements when the then and else clauses are similar.
Say if (o == null) return null; else return o.toString(); I am arguing that the cognitive load is less important when the if statement is inverted. i.e. if (o != null) return o.toString(); else return null; Or with ternary operator: return o != null ? o.toString() : null;
You can disagree and then not run this particular rule.