Community
Participate
Working Groups
I was playing with a lambda with a simple expression, and then I wanted to add slightly more logic which required me to use a block instead of the expression. Wouldn't it be cool if JDT/UI offered a quick assist "Convert body expression to block"? :) To convert this: void assistDemo(boolean flag) { perform(() -> 13); } into this: void assistDemo(boolean flag) { perform(() -> { return 13; }); } (And perhaps the inverse, too, if possible).
We can also provide these as clean up options along with the quick assists. The clean up could be similar to: Code Style -> Control statements -> Use blocks... Should these be added in a separate group for lambda expressions on the Code Style page?
(In reply to Noopur Gupta from comment #1) > We can also provide these as clean up options along with the quick assists. > > The clean up could be similar to: > Code Style -> Control statements -> Use blocks... I see the analogy, but actually I doubt that people would use that clean-up. After all, lambdas are all about code brevity, so single expressions will usually stay block-less, I guess. I see it more as an issue during editing, when code gets more complex..
Yes, let's just add quick assists for now (in both directions). Later, we could even integrate this into the existing "Use blocks in ..." cleanup option (i.e. no separate option just for lambdas). And let's reuse the terminology of similar existing quick assists for if/while/... statements: - Change body expression to block - Change body block to expression
Created attachment 239665 [details] WIP Patch The patch can be applied to mmathew/BETA_JAVA8 branch. It provides 2 quick assists: - Change body expression to block: If the return type of lambda is 'void', ExpressionStatement is created. Otherwise, ReturnStatement is created. - Change body block to expression: Available only when the single statement in the lambda body is a ReturnStatement or an ExpressionStatement (with expression being a valid body of lambda). (Checked all the sub-classes of Statement and ExpressionStatement to find the valid cases). TODO: - Add tests. - The "Change body block to expression" quick assist, when applied to a lambda body containing a single statement along with some comments, does not preserve the comments currently. Example: FI1 fi1 = x -> { // comment1 return x; // comment2 // comment3 }; will result in: FI1 fi1 = x -> x; Markus, how can we preserve the comments or disable the quick assist when there are comments in the lambda body?
(In reply to Noopur Gupta from comment #4) In both new QuickAssistProcessor methods, this statement should appear earlier in the code, before the 'ASTRewrite.create(..)' call: if (resultingCollections == null) return true; The quick assist infrastructure always calls _all_ these get*Proposals(..) methods in hasAssists(..) to check whether assists are available at all. This should be quick, and we should not create an ASTRewrite unless we know we're actually going to use it to create a proposal. > Markus, how can we preserve the comments or disable the quick assist when > there are comments in the lambda body? I don't see a simple solution. I looked at the other 'Change xxx to block/statement' quick assists, but the difference here is that there's no good place to put the comments at all. I would just ignore the problem for now and let the comments disappear. Bug 424266 is about the same problem in a sightly different context, but the solution to both problems will work the same way. And this bug is about a quick assist, so the removal of the comments happens in the user's sight. That's less severe than if it happens in a Clean Up.
Released into BETA_JAVA8 after moving the "if (resultingCollections == null)" condition as mentioned in comment #5 and adding the tests. http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/commit/?h=BETA_JAVA8&id=b119a29fa393e16e5c068d6ec8a155c4a7f9df11 Keeping the bug open, in case some changes are required after review.
getChangeLambdaBodyToExpressionProposal(..) should also do the whole analysis before creating an ASTRewrite. I've also increased the relevance of the proposals, because I think they will be used more often than "Convert to anonymous". Finished up with http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/commit/?id=23dfea26642d6307c698c3c91e53a0dfaa50baae
Have the following piece of code: package snippet; public class Snippet { interface I { int add(); } void perform(I i) {} void assistDemo(boolean flag) { perform(() -> 13); } } Place cursor on -> and Ctrl 1. The transformation from expression to block takes place correctly. Verified for Eclipse Kepler 4.3.2 RC4 Build id: M20140212-0800.
Verified as working for Eclipse + Java 8 RC1 Eclipse Kepler 4.3.2(RC4) Build id: M20140212-0800 + Eclipse Java Development Tools Patch for Java 8 Support (BETA) 1.0.0.v20140220-2054.