diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index 8ea513e0f462..b46589f451d6 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -816,7 +816,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { final IntroduceVariableSettings settings) { final PsiElement container = anchorStatement.getParent(); PsiElement child = anchorStatement; - if (!RefactoringUtil.isLoopOrIf(container)) { + final boolean isInsideLoop = RefactoringUtil.isLoopOrIf(container); + if (!isInsideLoop) { child = locateAnchor(child); if (isFinalVariableOnLHS(expr)) { child = child.getNextSibling(); @@ -826,10 +827,10 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { boolean tempDeleteSelf = false; final boolean replaceSelf = settings.isReplaceLValues() || !RefactoringUtil.isAssignmentLHS(expr); - if (!RefactoringUtil.isLoopOrIf(container)) { - if (expr.getParent() instanceof PsiExpressionStatement && anchor.equals(anchorStatement)) { - PsiStatement statement = (PsiStatement) expr.getParent(); - PsiElement parent = statement.getParent(); + final PsiElement exprParent = expr.getParent(); + if (!isInsideLoop) { + if (exprParent instanceof PsiExpressionStatement && anchor.equals(anchorStatement)) { + PsiElement parent = exprParent.getParent(); if (parent instanceof PsiCodeBlock || //fabrique parent instanceof PsiCodeFragment) { @@ -839,6 +840,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { tempDeleteSelf &= replaceSelf; } final boolean deleteSelf = tempDeleteSelf; + final boolean replaceLoop = isInsideLoop ? exprParent instanceof PsiExpressionStatement + : container instanceof PsiLambdaExpression && exprParent == container; final int col = editor != null ? editor.getCaretModel().getLogicalPosition().column : 0; @@ -857,9 +860,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { public PsiVariable compute() { try { PsiStatement statement = null; - final boolean isInsideLoop = RefactoringUtil.isLoopOrIf(container); if (!isInsideLoop && deleteSelf) { - statement = (PsiStatement) expr.getParent(); + statement = (PsiStatement)exprParent; } final PsiExpression expr1 = fieldConflictsResolver.fixInitializer(expr); @@ -879,7 +881,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { if (!isInsideLoop) { declaration = addDeclaration(declaration, initializer); LOG.assertTrue(expr1.isValid()); - if (deleteSelf) { // never true + if (deleteSelf) { final PsiElement lastChild = statement.getLastChild(); if (lastChild instanceof PsiComment) { // keep trailing comment declaration.addBefore(lastChild, null); @@ -925,7 +927,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { } } - declaration = (PsiDeclarationStatement) RefactoringUtil.putStatementInLoopBody(declaration, container, anchorStatement); + declaration = (PsiDeclarationStatement) RefactoringUtil.putStatementInLoopBody(declaration, container, anchorStatement, replaceSelf && replaceLoop); declaration = (PsiDeclarationStatement)JavaCodeStyleManager.getInstance(project).shortenClassReferences(declaration); PsiVariable var = (PsiVariable) declaration.getDeclaredElements()[0]; PsiUtil.setModifierProperty(var, PsiModifier.FINAL, settings.isDeclareFinal()); diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index ea277471b81a..453516c5ef04 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -859,7 +859,16 @@ public class RefactoringUtil { return false; } - public static PsiStatement putStatementInLoopBody(PsiStatement declaration, PsiElement container, PsiElement finalAnchorStatement) + public static PsiStatement putStatementInLoopBody(PsiStatement declaration, + PsiElement container, + PsiElement finalAnchorStatement) throws IncorrectOperationException { + return putStatementInLoopBody(declaration, container, finalAnchorStatement, false); + } + + public static PsiStatement putStatementInLoopBody(PsiStatement declaration, + PsiElement container, + PsiElement finalAnchorStatement, + boolean replaceBody) throws IncorrectOperationException { final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(container.getProject()).getElementFactory(); if(isLoopOrIf(container)) { @@ -879,7 +888,7 @@ public class RefactoringUtil { final PsiCodeBlock codeBlock = blockStatement.getCodeBlock(); declaration = (PsiStatement) codeBlock.add(declaration); JavaCodeStyleManager.getInstance(declaration.getProject()).shortenClassReferences(declaration); - if (loopBodyCopy != null) codeBlock.add(loopBodyCopy); + if (loopBodyCopy != null && !replaceBody) codeBlock.add(loopBodyCopy); } else if (container instanceof PsiLambdaExpression) { PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)container; final PsiElement invalidBody = lambdaExpression.getBody(); @@ -899,8 +908,12 @@ public class RefactoringUtil { LOG.assertTrue(lambdaExpressionBody != null); final PsiStatement lastBodyStatement; if (PsiType.VOID.equals(LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression))) { - lastBodyStatement = elementFactory.createStatementFromText("a;", lambdaExpression); - ((PsiExpressionStatement)lastBodyStatement).getExpression().replace(lambdaExpressionBody); + if (replaceBody) { + lastBodyStatement = null; + } else { + lastBodyStatement = elementFactory.createStatementFromText("a;", lambdaExpression); + ((PsiExpressionStatement)lastBodyStatement).getExpression().replace(lambdaExpressionBody); + } } else { lastBodyStatement = elementFactory.createStatementFromText("return a;", lambdaExpression); @@ -908,7 +921,9 @@ public class RefactoringUtil { LOG.assertTrue(returnValue != null); returnValue.replace(lambdaExpressionBody); } - newBody.add(lastBodyStatement); + if (lastBodyStatement != null) { + newBody.add(lastBodyStatement); + } final PsiLambdaExpression copy = (PsiLambdaExpression)lambdaExpression.replace(expressionFromText); newBody = (PsiCodeBlock)copy.getBody(); diff --git a/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoid.after.java b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoid.after.java new file mode 100644 index 000000000000..b4925b1ea2d2 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoid.after.java @@ -0,0 +1,8 @@ +class Foo { + + public static void main(String[] args) { + Runnable r = () -> { + String s = args.toString(); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoid.java b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoid.java new file mode 100644 index 000000000000..a91edac593eb --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoid.java @@ -0,0 +1,6 @@ +class Foo { + + public static void main(String[] args) { + Runnable r = () -> args.toString() + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index eceac23f1c6c..61a6442f400d 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -483,6 +483,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { public void testPutInLambdaBodyVoidValueConflict() { doTest(new MockIntroduceVariableHandler("c", false, false, false, "int")); } + + public void testPutInLambdaBodyVoid() { + doTest(new MockIntroduceVariableHandler("s", false, false, false, "java.lang.String")); + } public void testNormalizeDeclarations() { doTest(new MockIntroduceVariableHandler("i3", false, false, false, "int"));