Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Java Development Tools (JDT) » Refactoring idea for org.eclipse.jdt.internal.compiler.ast.BinaryExpression
Refactoring idea for org.eclipse.jdt.internal.compiler.ast.BinaryExpression [message #1413476] Thu, 28 August 2014 16:16 Go to next message
Na Mising name is currently offline Na Mising nameFriend
Messages: 11
Registered: August 2011
Junior Member
I'm doing some research in automatic refactoring suggestion. By observing the co-change pattern of some similar code, we would like to develop a tool to suggest possible refactorings to apply in order to extract out common code while parameterizing any difference between them.

I have examined the code snippets in class org.eclipse.jdt.internal.compiler.ast.BinaryExpression.java. In the class, there are two methods generateOptimizedGreaterThan(BlockScope, CodeStream, Label, Label, boolean) and generateOptimizedGreaterThanOrEqual(BlockScope, CodeStream, Label, Label, boolean). I see these two methods have pretty similar method bodies and also experience similar changes at least one time in the version history. Do you think it will be a good idea or bad idea to extract a method out of the two methods while parameterizing any differences between them?

As far as I can see, these two methods are only different in terms of six method calls, for instance, one calls "codeStream.if_icmplt(falseLabel)" while the other calls "codeStream.if_icmple(falseLabel)". If you would like to apply the refactoring, what will be the refactored version like? Will it be something like the following?

abstract class TemplateClass{
public void extractMethod(...){
... ...
m1(codeStream, falseLabel); //newly created method to abstract different method calls;
... ...
}
public abstract void m1(CodeStream codeStream, Label falseLabel);
... ...
}

class TemplateClass1 extends TemplateClass{
public void m1(CodeStream codeStream, Label falseLabel){
codeStream.if_icmplt(falseLabel);
}
... ...
}

class TemplateClass2 extends TemplateClass{
public void m1(CodeStream codeStream, Label falseLabel){
codeStream.if_icmple(falseLabel);
}
... ...
}

public void generateOptimizedGreaterThanOrEqual(...){
new TemplateClass1().extractMethod(...);
}

public void generateOptimizedGreaterThan(...){
new TemplateClass2().extractMethod(...);
}

If you don't like the refactoring idea, would you like to share the factors in your mind which affects your decision, such as complexity of refactoring, poor readability, poor maintainability, code size, etc. For each factor, how do you think it can affects your decision about using refactoring? If possible, any quantative analysis will be great. For example, if the code size after refactoring is greater than that before refactoring, I won't do refactoring. Or
if there are only two lines shared between two code snippets, I won't do refactoring, etc.

Thanks a lot for your help! Your suggestion will be very valuable for our research.
Re: Refactoring idea for org.eclipse.jdt.internal.compiler.ast.BinaryExpression [message #1413526 is a reply to message #1413476] Thu, 28 August 2014 19:32 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1828
Registered: July 2009
Senior Member
I can't speak for the entire team, but my personal impression is: this pair of methods is not a pain point during maintenance / evolution of JDT. That particular class is very stable, and the readability of the code as it is now outweighs potential benefits of refactoring.

We have other duplications, that are more likely to cause pain, e.g., by being forgotten during maintenance: have a look at AllocationExpression vs. QualifiedAllocationExpression for an example. Even AllocationExpression and MessageSend should show on your radar of co-evolution, right?
In these classes, potential gain might be greater, but then a refactoring to avoid redundancy would certainly introduce a significant amount of additional complexity.

We don't typically refactor unless we have to change the code for some bug fix or new feature.

best,
Stephan
Re: Refactoring idea for org.eclipse.jdt.internal.compiler.ast.BinaryExpression [message #1413541 is a reply to message #1413526] Thu, 28 August 2014 20:14 Go to previous messageGo to next message
Na Mising name is currently offline Na Mising nameFriend
Messages: 11
Registered: August 2011
Junior Member
Hi Stephan,

Thank you so much for your quick response! The insight is quite helpful. If I summarize correctly, it seems that you don't always do refactoring for two reasons:
(1) the class is very stable, requiring no additional code changes to fix bugs or add features.
(2) the class is not stable, but refactoring makes the code too complex to read or understand.

I'm curious that:
(1) If some classes are co-changed again and again, without refactoring, what kind of tool/strategy do you usually use to guarantee that you don't commit error of omission? For instance, writing some scripts, memorize the correlated classes and leverage your expertise when debugging, etc.?
(2) For the method pairs which are pain points, how do you decide whether the gain is greater than pain by applying refactoring? How much difference or what kind of difference will your extracted method allow? Different variable names, method calls, used types? Will you try to use some really complicated refactorings in order to avoid the error of omission mentioned above, such as Delegate design pattern, Parameterize Type (declare a template with type parameters to define an extracted method which works on differently typed variables)? Will you also reconstruct the code if two code snippets are syntactically different but semantically equivalent?

Thanks a lot for your generous sharing!
Na Meng
Re: Refactoring idea for org.eclipse.jdt.internal.compiler.ast.BinaryExpression [message #1414544 is a reply to message #1413541] Sun, 31 August 2014 17:19 Go to previous message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1828
Registered: July 2009
Senior Member
... still only speaking for myself, no explicit rules ...

Na Mising name wrote on Thu, 28 August 2014 22:14

(1) If some classes are co-changed again and again, without refactoring, what kind of tool/strategy do you usually use to guarantee that you don't commit error of omission? For instance, writing some scripts, memorize the correlated classes and leverage your expertise when debugging, etc.?


Some classes carry a comment, reminding us of duplication. Most explicit example would be org.eclipse.jdt.internal.compiler.parser.Scanner.

Other similarities are indeed subject basically to: experience.

Quote:

(2) For the method pairs which are pain points, how do you decide whether the gain is greater than pain by applying refactoring? How much difference or what kind of difference will your extracted method allow? Different variable names, method calls, used types?


Frankly, reducing existing code duplication doesn't seem to be a frequent consideration in JDT/Core. I'd say we spend more time on finding the right spot for making a change in the first place, rather than merging methods after the fact.

While I'm not shy at introducing new parameters to existing methods to avoid new redundancy, I tend to think that every existing method has its reason for being (and normally I can't just ask the author, many of them are no longer part of the team).



Quote:

Will you try to use some really complicated refactorings in order to avoid the error of omission mentioned above, such as Delegate design pattern, Parameterize Type (declare a template with type parameters to define an extracted method which works on differently typed variables)? Will you also reconstruct the code if two code snippets are syntactically different but semantically equivalent?


Parameterized types: until recently JDT/Core was built at source level 1.3!

Where not shy on introducing new abstractions (by the book, or invented for the task), for an example introduced for Java 8 see TypeAnnotationWalker. But this was introduced during initial design for a new feature.

Even if we would eliminate a few more instances of (near) code duplication, we still wouldn't be safe against errors of omission: in the compiler business every feature worked on tends to (intentionally or unintentionally) interact with about every other feature. So when we change s.t. about overload resolution, we must *always* be aware that this could interfere with var-args methods, auto-boxing, type inference, to name just a few. At this point we're dependent on testing: 60000+ JUnits plus free-style manual testing per milestone are our main tools, here.

So, maybe we are quite conservative, but I think we *do* have something very valuable to conserve, actually Smile

Since I'd normally claim that existing JDT code is already of high quality, I'd be curious to hear from you, how the degree of detectable duplication and co-changes in JDT compares to other software?

best,
Stephan
Previous Topic:Configure Eclipse to compile with javac instead of ECJ?
Next Topic:Issue with Eclipse hadoop plugin
Goto Forum:
  


Current Time: Thu Dec 03 21:13:20 GMT 2020

Powered by FUDForum. Page generated in 0.02379 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top