From f8581b839bbef84c8619d0917d23994166f9262d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 19 Jun 2015 13:44:33 +0300 Subject: [PATCH] EA-45951, EA-58568 (PSI traversal fixed; test added) --- .../impl/SurroundAutoCloseableAction.java | 28 ++++++++++-------- .../surroundAutoCloseable/SplitVar.java | 13 +++++++++ .../surroundAutoCloseable/SplitVar_after.java | 15 ++++++++++ .../SurroundAutoCloseableActionTest.java | 29 +++++-------------- 4 files changed, 52 insertions(+), 33 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar.java create mode 100644 java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar_after.java 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 e60743c0ae71..4c6b91dd6de9 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -92,10 +92,7 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { List toFormat = null; if (last != null) { - final PsiElement first = armStatement.getNextSibling(); - if (first != null) { - toFormat = moveStatements(first, last, armStatement); - } + toFormat = moveStatements(last, armStatement); } final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); @@ -117,14 +114,19 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { } } - private static List moveStatements(@NotNull PsiElement first, PsiElement last, PsiTryStatement statement) { + private static List moveStatements(PsiElement last, PsiTryStatement statement) { PsiCodeBlock tryBlock = statement.getTryBlock(); assert tryBlock != null : statement.getText(); PsiElement parent = statement.getParent(); List toFormat = new SmartList(); PsiElement stopAt = last.getNextSibling(); - for (PsiElement child = first; child != null && child != stopAt; child = child.getNextSibling()) { + + PsiElement i = statement.getNextSibling(); + while (i != null && i != stopAt) { + PsiElement child = i; + i = PsiTreeUtil.skipSiblingsForward(i, PsiWhiteSpace.class, PsiComment.class); + if (!(child instanceof PsiDeclarationStatement)) continue; PsiElement anchor = child; @@ -134,8 +136,8 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { final int endOffset = last.getTextRange().getEndOffset(); boolean contained = ReferencesSearch.search(declared, new LocalSearchScope(parent)).forEach(new Processor() { @Override - public boolean process(PsiReference reference) { - return reference.getElement().getTextOffset() <= endOffset; + public boolean process(PsiReference ref) { + return ref.getElement().getTextOffset() <= endOffset; } }); @@ -148,9 +150,10 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { toFormat.add(parent.addBefore(factory.createVariableDeclarationStatement(name, var.getType(), null), statement)); PsiExpression varInit = var.getInitializer(); - assert varInit != null : child.getText(); - String varAssignText = name + " = " + varInit.getText() + ";"; - anchor = parent.addAfter(factory.createStatementFromText(varAssignText, parent), anchor); + if (varInit != null) { + String varAssignText = name + " = " + varInit.getText() + ";"; + anchor = parent.addAfter(factory.createStatementFromText(varAssignText, parent), anchor); + } var.delete(); } @@ -161,6 +164,7 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { } } + PsiElement first = statement.getNextSibling(); tryBlock.addRangeBefore(first, last, tryBlock.getRBrace()); parent.deleteChildRange(first, last); diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar.java new file mode 100644 index 000000000000..c92318efafd1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar.java @@ -0,0 +1,13 @@ +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; + +class C { + void m(File file) throws IOException { + FileInputStream stream = new FileInputStream(file); + int x; + FileChannel ch = stream.getChannel(); + ch.close(); + x = 0; + } +} diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar_after.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar_after.java new file mode 100644 index 000000000000..54f387044cf1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/SplitVar_after.java @@ -0,0 +1,15 @@ +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; + +class C { + void m(File file) throws IOException { + int x; + FileChannel ch; + try (FileInputStream stream = new FileInputStream(file)) { + ch = stream.getChannel(); + } + ch.close(); + x = 0; + } +} 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 1a44bb0c0898..5ac793868072 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/SurroundAutoCloseableActionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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. @@ -17,37 +17,24 @@ package com.intellij.codeInsight.intention; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightBundle; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; import com.intellij.testFramework.fixtures.CodeInsightTestUtil; -import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; - -public class SurroundAutoCloseableActionTest extends JavaCodeInsightFixtureTestCase { - private String myIntention; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +public class SurroundAutoCloseableActionTest extends LightCodeInsightFixtureTestCase { @Override - public void setUp() throws Exception { - super.setUp(); - myIntention = CodeInsightBundle.message("intention.surround.resource.with.ARM.block"); - } - - @Override - protected void tuneFixture(final JavaModuleFixtureBuilder moduleBuilder) throws Exception { - moduleBuilder.setLanguageLevel(LanguageLevel.JDK_1_7); + protected String getTestDataPath() { + return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/surroundAutoCloseable/"; } public void testSimple() { doTest(); } public void testUsage() { doTest(); } public void testMixedUsages() { doTest(); } public void testLastDeclaration() { doTest(); } + public void testSplitVar() { doTest(); } private void doTest() { String name = getTestName(false); - CodeInsightTestUtil.doIntentionTest(myFixture, myIntention, name + ".java", name + "_after.java"); - } - - @Override - protected String getTestDataPath() { - return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/surroundAutoCloseable/"; + String intention = CodeInsightBundle.message("intention.surround.resource.with.ARM.block"); + CodeInsightTestUtil.doIntentionTest(myFixture, intention, name + ".java", name + "_after.java"); } }