diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java index 3915c8a696ae..4bc6b70363b1 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java @@ -166,7 +166,12 @@ public class InlineLocalHandler extends JavaInlineActionHandler { } } - if (checkRefsInAugmentedAssignmentOrUnaryModified(refsToInline, project, editor, localName)) { + final PsiElement writeAccess = checkRefsInAugmentedAssignmentOrUnaryModified(refsToInline); + if (writeAccess != null) { + HighlightManager.getInstance(project).addOccurrenceHighlights(editor, new PsiElement[]{writeAccess}, writeAttributes, true, null); + String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("variable.is.accessed.for.writing", localName)); + CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE); + WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting")); return; } @@ -238,8 +243,8 @@ public class InlineLocalHandler extends JavaInlineActionHandler { }, RefactoringBundle.message("inline.command", localName), null); } - private static boolean checkRefsInAugmentedAssignmentOrUnaryModified(final PsiElement[] refsToInline, final Project project, final Editor editor, - final String localName) { + @Nullable + public static PsiElement checkRefsInAugmentedAssignmentOrUnaryModified(final PsiElement[] refsToInline) { for (PsiElement element : refsToInline) { PsiElement parent = element.getParent(); @@ -251,16 +256,10 @@ public class InlineLocalHandler extends JavaInlineActionHandler { if (parent instanceof PsiAssignmentExpression && element == ((PsiAssignmentExpression)parent).getLExpression() || isUnaryWriteExpression(parent)) { - EditorColorsManager manager = EditorColorsManager.getInstance(); - final TextAttributes writeAttributes = manager.getGlobalScheme().getAttributes(EditorColors.WRITE_SEARCH_RESULT_ATTRIBUTES); - HighlightManager.getInstance(project).addOccurrenceHighlights(editor, new PsiElement[]{element}, writeAttributes, true, null); - String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("variable.is.accessed.for.writing", localName)); - CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE); - WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting")); - return true; + return element; } } - return false; + return null; } private static boolean isUnaryWriteExpression(PsiElement parent) { diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java index 104332c1c3e8..d93340f4108d 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterHandler.java @@ -26,12 +26,15 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; +import com.intellij.psi.controlFlow.DefUseUtil; import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; +import com.intellij.refactoring.util.InlineUtil; import com.intellij.refactoring.util.RefactoringMessageDialog; import com.intellij.util.Processor; import org.jetbrains.annotations.Nullable; @@ -107,7 +110,36 @@ public class InlineParameterHandler extends JavaInlineActionHandler { } }); if (occurrences.isEmpty()) { - CommonRefactoringUtil.showErrorHint(project, editor, "Method has no usages", RefactoringBundle.message("inline.parameter.refactoring"), null); + final int offset = editor.getCaretModel().getOffset(); + final PsiElement refExpr = psiElement.getContainingFile().findElementAt(offset); + final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(refExpr, PsiCodeBlock.class); + if (codeBlock != null) { + final PsiElement[] defs = DefUseUtil.getDefs(codeBlock, psiParameter, refExpr); + if (defs.length == 1) { + final PsiElement def = defs[0]; + if (def instanceof PsiReferenceExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression)def)) { + final PsiExpression rExpr = ((PsiAssignmentExpression)def.getParent()).getRExpression(); + if (rExpr != null) { + final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr); + + if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs) == null) { + new WriteCommandAction(project) { + @Override + protected void run(Result result) throws Throwable { + for (final PsiElement ref : refs) { + InlineUtil.inlineVariable(psiParameter, rExpr, (PsiJavaCodeReferenceElement)ref); + } + def.getParent().delete(); + } + }.execute(); + return; + } + } + } + } + } + CommonRefactoringUtil + .showErrorHint(project, editor, "Method has no usages", RefactoringBundle.message("inline.parameter.refactoring"), null); return; } if (!result) { diff --git a/java/java-tests/testData/refactoring/inlineParameter/InlineLocalParamDef.java b/java/java-tests/testData/refactoring/inlineParameter/InlineLocalParamDef.java new file mode 100644 index 000000000000..9e5953fec89e --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineParameter/InlineLocalParamDef.java @@ -0,0 +1,6 @@ +public class ExpData { + void foo(String s) { + s = ""; + System.out.println(s.substring(2)); + } +} diff --git a/java/java-tests/testData/refactoring/inlineParameter/InlineLocalParamDef.java.after b/java/java-tests/testData/refactoring/inlineParameter/InlineLocalParamDef.java.after new file mode 100644 index 000000000000..332d13232d9c --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineParameter/InlineLocalParamDef.java.after @@ -0,0 +1,5 @@ +public class ExpData { + void foo(String s) { + System.out.println("".substring(2)); + } +} diff --git a/java/java-tests/testData/refactoring/inlineParameter/ParameterDefWithWriteAccess.java b/java/java-tests/testData/refactoring/inlineParameter/ParameterDefWithWriteAccess.java new file mode 100644 index 000000000000..a9c50831ad68 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineParameter/ParameterDefWithWriteAccess.java @@ -0,0 +1,6 @@ +public class ExpData { + void foo(int i) { + i = 0; + System.out.println(i++); + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java index 673361a21540..4e58558adc28 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java @@ -246,6 +246,19 @@ public class InlineParameterTest extends LightCodeInsightTestCase { } } + public void testInlineLocalParamDef() throws Exception { + doTest(false); + } + + public void testParameterDefWithWriteAccess() throws Exception { + try { + doTest(false); + } + catch (CommonRefactoringUtil.RefactoringErrorHintException e) { + assertEquals("Method has no usages", e.getMessage()); + } + } + private void doTest(final boolean createLocal) throws Exception { getProject().putUserData(InlineParameterExpressionProcessor.CREATE_LOCAL_FOR_TESTS,createLocal);