Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 405096 - [save actions][clean up] Use parentheses in expressions: Only if necessary, removes required parentheses
Summary: [save actions][clean up] Use parentheses in expressions: Only if necessary, r...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Text (show other bugs)
Version: 4.2.2   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 4.3 M7   Edit
Assignee: Noopur Gupta CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 404523
Blocks:
  Show dependency tree
 
Reported: 2013-04-07 02:27 EDT by Bopher Lu CLA
Modified: 2013-04-22 08:49 EDT (History)
2 users (show)

See Also:
markus.kell.r: review+


Attachments
Patch (7.37 KB, patch)
2013-04-10 06:09 EDT, Noopur Gupta CLA
daniel_megert: review+
Details | Diff
Patch-updated (5.58 KB, patch)
2013-04-17 02:29 EDT, Noopur Gupta CLA
no flags Details | Diff
Patch-Fixed Test failure (657 bytes, patch)
2013-04-22 07:51 EDT, Noopur Gupta CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bopher Lu CLA 2013-04-07 02:27:23 EDT
Editor save action "Remove unnecessary parentheses" makes code uncompilable.

Code line below before save:
static final Short cache[] = new Short[-(-128) + 127 + 1]; //compilable

code line after save:
static final Short cache[] = new Short[--128 + 127 + 1];  //uncompilable

This line of code is from java.lang.Short.
Comment 1 Dani Megert CLA 2013-04-08 06:26:23 EDT
(In reply to comment #0)
> Editor save action "Remove unnecessary parentheses" makes code uncompilable.

I guess you mean the following option:
Use parentheses in expressions: Only if necessary

Can reproduce with 4.3 M6.
Comment 2 Noopur Gupta CLA 2013-04-10 06:09:42 EDT
Created attachment 229549 [details]
Patch

NecessaryParenthesesChecker#needsParentheses(..) had not considered the case where both the parent and child expressions are PrefixExpression. 

In such a case, we can have a pair of prefix operators (+, -, ~, !, ++ and --) separated from each other with opening parentheses.

Out of the 36 possible pairs:

a) For some, the parentheses can be safely removed. 
Example: +(-Expression) => +-Expression

b) Some are already invalid and have a compilation error, so parentheses can be removed, which is the existing behavior and has not been changed. 
Example: ++(PrefixOperator Expression)

c) Following pairs lead to a compilation error or semantic change on removing parentheses:
+(+128) => ++128 (compile error) 
+(+i) => ++i (semantic change)
+(++i) => +++i (considered as ++(+i), compile error and semantic change)
-(-128) => --128 (compile error) 
-(-i) => --i (semantic change)
-(--i) => ---i (considered as --(-i), compile error and semantic change)
+(++128) and -(--128) are invalid and the child expression comes as a NumberLiteral, hence these do not fall under the case where both parent and child are PrefixExpression.

For the above cases in c), the patch contains a check to preserve the parentheses.
Also, added corresponding test cases in CleanUpTest.

Dani, please check if the behavior is fine.
Comment 3 Dani Megert CLA 2013-04-11 05:52:57 EDT
*** Bug 386028 has been marked as a duplicate of this bug. ***
Comment 4 Dani Megert CLA 2013-04-11 08:47:38 EDT
Thanks Noopur, the patch looks good.

Committed patch with http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/commit/?id=c47cfd066ed2625d7d5bcb86255bd873a5058b8b
Comment 5 Markus Keller CLA 2013-04-11 09:20:22 EDT
Note that this fix is not strictly correct.

NecessaryParenthesesChecker is meant to handle cases where only parentheses can preserve semantics. But in this case, a whitespace between the two "-" is enough: "- -128". The code formatter also preserves this whitespace (and bug 405038 recently fixed a similar problem for infix expressions).

The proper fix would be in the ASTRewrite, see bug 404523.
Comment 6 Dani Megert CLA 2013-04-11 10:53:39 EDT
(In reply to comment #5)
> Note that this fix is not strictly correct.
> 
> NecessaryParenthesesChecker is meant to handle cases where only parentheses
> can preserve semantics. But in this case, a whitespace between the two "-"
> is enough: "- -128". The code formatter also preserves this whitespace (and
> bug 405038 recently fixed a similar problem for infix expressions).
> 
> The proper fix would be in the ASTRewrite, see bug 404523.

I suggest we keep the workaround until bug 404523 has been fixed.
Comment 7 Markus Keller CLA 2013-04-11 12:01:21 EDT
> I suggest we keep the workaround until bug 404523 has been fixed.

I agree. However, to finish this off, we should also handle the same problems with InfixExpressions, e.g.:

	int i = 1-(-128);

AFAICS, PostfixExpressions don't pose a problem, since they bind stronger than Prefix and Infix and they don't exist in unary form.

Noopur, could you please have another look?
Comment 8 Noopur Gupta CLA 2013-04-17 02:29:32 EDT
Created attachment 229785 [details]
Patch-updated

The same cases apply for infix parent expressions also.
The attached patch has the updated code.
Dani, please review.
Comment 9 Dani Megert CLA 2013-04-19 08:54:16 EDT
Looks good. Go ahead and commit it.
Comment 10 Noopur Gupta CLA 2013-04-19 10:48:52 EDT
Thanks Dani.
Committed patch with http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/commit/?id=e671df9ce3e004b5f28924e663b4002e4cd9266d
Comment 11 Markus Keller CLA 2013-04-19 11:12:16 EDT
.
Comment 12 Markus Keller CLA 2013-04-22 06:53:15 EDT
N20130421-2000 has a test failure in InlineMethodTests.testPrefixPlus.
Noopur, please fix the test if the change makes sense.
Comment 13 Noopur Gupta CLA 2013-04-22 07:51:30 EDT
Created attachment 229954 [details]
Patch-Fixed Test failure

(In reply to comment #12)
> N20130421-2000 has a test failure in InlineMethodTests.testPrefixPlus.
> Noopur, please fix the test if the change makes sense.

The test failure is in the following case:

        public void foo() {
		int i= 10;
		result= inline(++i); 
                // After inline operation:
                // Earlier:   result= 1 + ++i;
                // Now:       result= 1 + (++i);
	}
	
	public int inline(int x) {
		return 1 + x;
	}

As mentioned in comment #5, this fix does not consider if a whitespace is enough to prevent the bug and keeps more parentheses than needed to avoid the bug without a whitespace. It is a workaround for bug 404523.
So the test update should also be a workaround until bug 404523 is fixed and this fix is reverted.

I have updated the test currently. Markus, please check and let me know if it is fine.
Comment 14 Markus Keller CLA 2013-04-22 08:44:18 EDT
Looks good, please commit and resolve this bug again.