diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java index ac5df759aeb2..d5707a284b48 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java @@ -23,13 +23,17 @@ import com.intellij.openapi.project.Project; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.ProjectScope; +import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import java.util.Collection; + public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { @Override public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) { @@ -66,17 +70,39 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { final PsiElement codeBlock = declaration.getParent(); if (!(codeBlock instanceof PsiCodeBlock)) return; + PsiElement firstStatement = declaration.getNextSibling(), lastUsage = null; + final Collection references = ReferencesSearch.search(variable, new LocalSearchScope(codeBlock)).findAll(); + for (PsiReference reference : references) { + final PsiElement statement = PsiTreeUtil.findPrevParent(codeBlock, reference.getElement()); + if ((lastUsage == null || statement.getTextOffset() > lastUsage.getTextOffset())) { + lastUsage = statement; + } + } + final String text = "try (" + variable.getTypeElement().getText() + " " + variable.getName() + " = " + initializer.getText() + ") {}"; final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); final PsiStatement armStatement = factory.createStatementFromText(text, codeBlock); final PsiElement newElement = declaration.replace(armStatement); + if (firstStatement != null && lastUsage != null) { + final PsiCodeBlock tryBlock = ((PsiTryStatement)newElement).getTryBlock(); + assert tryBlock != null : newElement.getText(); + final PsiJavaToken rBrace = tryBlock.getRBrace(); + assert rBrace != null : newElement.getText(); + + tryBlock.addRangeBefore(firstStatement, lastUsage, rBrace); + codeBlock.deleteChildRange(firstStatement, lastUsage); + } + final PsiElement formattedElement = CodeStyleManager.getInstance(project).reformat(newElement); - final PsiCodeBlock tryBlock = ((PsiTryStatement)formattedElement).getTryBlock(); - if (tryBlock != null) { - final PsiJavaToken brace = tryBlock.getLBrace(); - if (brace != null) { - editor.getCaretModel().moveToOffset(brace.getTextOffset() + 1); + + if (lastUsage == null) { + final PsiCodeBlock tryBlock = ((PsiTryStatement)formattedElement).getTryBlock(); + if (tryBlock != null) { + final PsiJavaToken brace = tryBlock.getLBrace(); + if (brace != null) { + editor.getCaretModel().moveToOffset(brace.getTextOffset() + 1); + } } } } diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage.java index 03083fc533ea..b34beda14116 100644 --- a/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage.java +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage.java @@ -5,6 +5,11 @@ import java.io.IOException; class C { void m(File file) throws IOException { FileInputStream fileInputStream = new FileInputStream(file); - int read = fileInputStream.read(); + int read; + do { + read = fileInputStream.read(); + System.out.println(read); + } + while (read != -1); } } diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage_after.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage_after.java index 5916d01bace8..458e331b7f8f 100644 --- a/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage_after.java +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/Usage_after.java @@ -5,7 +5,12 @@ import java.io.IOException; class C { void m(File file) throws IOException { try (FileInputStream fileInputStream = new FileInputStream(file)) { - int read = fileInputStream.read(); + int read; + do { + read = fileInputStream.read(); + System.out.println(read); + } + while (read != -1); } } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java index 37787bad599e..92c34f8371c7 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java @@ -37,7 +37,7 @@ public class SurroundAutoCloseableActionTest extends JavaCodeInsightFixtureTestC } public void testSimple() { doTest(); } - //public void testUsage() { doTest(); } + public void testUsage() { doTest(); } private void doTest() { String name = getTestName(false);