diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaAnonymousUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaAnonymousUnwrapper.java index b9d2f836910b..4e0094267fa8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaAnonymousUnwrapper.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaAnonymousUnwrapper.java @@ -51,13 +51,7 @@ public class JavaAnonymousUnwrapper extends JavaUnwrapper { final PsiStatement[] statements = body.getStatements(); if (statements.length == 1 && statements[0] instanceof PsiReturnStatement) { final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue(); - if (from instanceof PsiDeclarationStatement) { - final PsiElement[] declaredElements = ((PsiDeclarationStatement)from).getDeclaredElements(); - if (declaredElements.length == 1 && declaredElements[0] instanceof PsiVariable) { - context.setInitializer((PsiVariable)declaredElements[0], returnValue); - return; - } - } + if (toAssignment(context, from, returnValue)) return; } } } @@ -73,7 +67,18 @@ public class JavaAnonymousUnwrapper extends JavaUnwrapper { context.deleteExactly(from); } - private static PsiElement findElementToExtractFrom(PsiElement el) { + public static boolean toAssignment(Context context, PsiElement from, PsiExpression returnValue) { + if (from instanceof PsiDeclarationStatement) { + final PsiElement[] declaredElements = ((PsiDeclarationStatement)from).getDeclaredElements(); + if (declaredElements.length == 1 && declaredElements[0] instanceof PsiVariable) { + context.setInitializer((PsiVariable)declaredElements[0], returnValue); + return true; + } + } + return false; + } + + public static PsiElement findElementToExtractFrom(PsiElement el) { if (el.getParent() instanceof PsiNewExpression) el = el.getParent(); el = findTopmostParentOfType(el, PsiMethodCallExpression.class); el = findTopmostParentOfType(el, PsiAssignmentExpression.class); diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaLambdaUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaLambdaUnwrapper.java new file mode 100644 index 000000000000..65007a462b43 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaLambdaUnwrapper.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; + +import java.util.List; + +public class JavaLambdaUnwrapper extends JavaUnwrapper { + public JavaLambdaUnwrapper() { + super(CodeInsightBundle.message("unwrap.lambda")); + } + + @Override + public boolean isApplicableTo(PsiElement e) { + return e instanceof PsiLambdaExpression; + } + + @Override + public PsiElement collectAffectedElements(PsiElement e, List toExtract) { + super.collectAffectedElements(e, toExtract); + return JavaAnonymousUnwrapper.findElementToExtractFrom(e); + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + PsiElement from = JavaAnonymousUnwrapper.findElementToExtractFrom(element); + PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)element; + PsiElement body = lambdaExpression.getBody(); + if (body instanceof PsiExpression || body instanceof PsiCodeBlock && ((PsiCodeBlock)body).getStatements().length == 1) { + List returnExpressions = LambdaUtil.getReturnExpressions(lambdaExpression); + if (returnExpressions.size() == 1 + && !PsiType.VOID.equals(returnExpressions.get(0).getType()) + && JavaAnonymousUnwrapper.toAssignment(context, from, returnExpressions.get(0))) { + return; + } + } + + if (body instanceof PsiCodeBlock) { + context.extractFromCodeBlock((PsiCodeBlock)body, from); + } + else { + context.extractElement(body, from); + if (context.myIsEffective) { + PsiStatement emptyStatement = JavaPsiFacade.getElementFactory(from.getProject()).createStatementFromText(";", from); + from.getParent().addBefore(emptyStatement, from); + } + } + context.deleteExactly(from); + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java index deda06052d68..d1be8f3fd8a6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java @@ -34,6 +34,7 @@ public class JavaUnwrapDescriptor extends UnwrapDescriptorBase { new JavaCatchRemover(), new JavaSynchronizedUnwrapper(), new JavaAnonymousUnwrapper(), + new JavaLambdaUnwrapper(), new JavaConditionalUnwrapper(), new JavaPolyadicExpressionUnwrapper() }; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/unwrap/UnwrapLambdaTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/unwrap/UnwrapLambdaTest.java new file mode 100644 index 000000000000..c23b3ae9e17a --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/unwrap/UnwrapLambdaTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.unwrap; + +public class UnwrapLambdaTest extends UnwrapTestCase { + public void testUnwrap() throws Exception { + assertUnwrapped("{\n" + + " Runnable r = () -> {\n" + + " System.gc();\n" + + " }\n" + + "}\n", + + "{\n" + + " System.gc();\n" + + "}\n"); + } + + public void testUnwrapExpressionDeclaration() throws Exception { + assertUnwrapped("{\n" + + " interface I {int get();}" + + " I i = () -> 1;\n" + + "}\n", + + "{\n" + + " interface I {int get();}" + + " I i = 1;\n" + + "}\n"); + } + + public void testUnwrapBlockDeclaration() throws Exception { + assertUnwrapped("{\n" + + " interface I {int get();}" + + " I i = () -> { return 1;};\n" + + "}\n", + + "{\n" + + " interface I {int get();}" + + " I i = 1;\n" + + "}\n"); + } + + public void testUnwrapUnresolved() throws Exception { + assertUnwrapped("{\n" + + " () -> null;\n" + + "}\n", + + "{\n" + + " null;\n" + + "}\n"); + } +} \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index e4e70c99fc4b..1a7aae77370c 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -102,6 +102,7 @@ unwrap.array.initializer=Unwrap array initializer unwrap.synchronized=Unwrap 'synchronized...' unwrap.with.placeholder=Unwrap ''{0}'' unwrap.anonymous=Unwrap 'anonymous...' +unwrap.lambda=Unwrap 'lambda...' generate.equals.hashcode.wizard.title=Generate equals() and hashCode() generate.equals.hashcode.equals.fields.chooser.title=Choose &fields to be included in equals() generate.equals.hashcode.hashcode.fields.chooser.title=Choose &fields to be included in hashCode()