diff --git a/.idea/modules.xml b/.idea/modules.xml index 5fbe4581a919..b724cbc1c285 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -264,6 +264,7 @@ + diff --git a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java index 775a5e6cf40e..3159a8ac56bb 100644 --- a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java +++ b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestLocator.java @@ -56,8 +56,7 @@ public class JavaTestLocator implements SMTestLocator { PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), path, null, true, scope); if (aClass != null) { results = ContainerUtil.newSmartList(); - results.add(paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName) - : new PsiLocation<>(project, aClass)); + results.add(createClassNavigatable(paramName, aClass)); } } else if (TEST_PROTOCOL.equals(protocol)) { @@ -67,11 +66,16 @@ public class JavaTestLocator implements SMTestLocator { PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), className, null, true, scope); if (aClass != null) { results = ContainerUtil.newSmartList(); - PsiMethod[] methods = aClass.findMethodsByName(methodName.trim(), true); - if (methods.length > 0) { - for (PsiMethod method : methods) { - results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName) - : MethodLocation.elementInClass(method, aClass)); + if (methodName.trim().equals(aClass.getName())) { + results.add(createClassNavigatable(paramName, aClass)); + } + else { + PsiMethod[] methods = aClass.findMethodsByName(methodName.trim(), true); + if (methods.length > 0) { + for (PsiMethod method : methods) { + results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName) + : MethodLocation.elementInClass(method, aClass)); + } } } } @@ -80,4 +84,9 @@ public class JavaTestLocator implements SMTestLocator { return results; } + + private Location createClassNavigatable(String paramName, @NotNull PsiClass aClass) { + return paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName) + : new PsiLocation<>(aClass.getProject(), aClass); + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java index 800506886c39..5d9304895ed7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java @@ -27,6 +27,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; @@ -155,6 +156,7 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction { if (file == null) return null; } OpenFileDescriptor descriptor = new OpenFileDescriptor(project, file, textOffset); + descriptor.setScrollType(ScrollType.MAKE_VISIBLE); // avoid centering caret in editor if it's already visible return FileEditorManager.getInstance(project).openTextEditor(descriptor, true); } diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 6eaed57e2aff..5629ba9a2ad9 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -47,7 +47,8 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; import com.intellij.psi.codeStyle.*; -import com.intellij.psi.controlFlow.ControlFlowUtil; +import com.intellij.psi.controlFlow.*; +import com.intellij.psi.controlFlow.ControlFlow; import com.intellij.psi.impl.source.codeStyle.JavaCodeStyleManagerImpl; import com.intellij.psi.scope.processor.VariablesProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; @@ -1092,13 +1093,21 @@ public class ExtractMethodProcessor implements MatchProvider { } private boolean hasNormalExit() { - boolean hasNormalExit = false; - PsiElement lastElement = myElements[myElements.length - 1]; - if (!(lastElement instanceof PsiReturnStatement || lastElement instanceof PsiBreakStatement || - lastElement instanceof PsiContinueStatement)) { - hasNormalExit = true; + try { + PsiCodeBlock block = JavaPsiFacade.getElementFactory(myProject).createCodeBlock(); + block.addRange(myElements[0], myElements[myElements.length - 1]); + ControlFlow flow = ControlFlowFactory.getInstance(myProject).getControlFlow(block, new LocalsControlFlowPolicy(block), false, false); + return ControlFlowUtil.canCompleteNormally(flow, 0, flow.getSize()); + } + catch (AnalysisCanceledException e) { + //check incomplete code as simple as possible + PsiElement lastElement = myElements[myElements.length - 1]; + if (!(lastElement instanceof PsiReturnStatement || lastElement instanceof PsiBreakStatement || + lastElement instanceof PsiContinueStatement)) { + return true; + } + return false; } - return hasNormalExit; } protected boolean isNeedToChangeCallContext() { diff --git a/java/java-tests/testData/refactoring/extractMethod/NormalExitIf.java b/java/java-tests/testData/refactoring/extractMethod/NormalExitIf.java new file mode 100644 index 000000000000..72ce352f6baf --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/NormalExitIf.java @@ -0,0 +1,17 @@ +class Test { + + private static void f(boolean a, boolean b) { + if (a) { + if (b) { + System.out.println(""); + return; + } else { + System.out.println(""); + return; + } + } else { + System.out.println(""); + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/NormalExitIf_after.java b/java/java-tests/testData/refactoring/extractMethod/NormalExitIf_after.java new file mode 100644 index 000000000000..e17024e677a6 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/NormalExitIf_after.java @@ -0,0 +1,22 @@ +class Test { + + private static void f(boolean a, boolean b) { + if (a) { + newMethod(b); + return; + } else { + System.out.println(""); + } + } + + private static void newMethod(boolean b) { + if (b) { + System.out.println(""); + return; + } else { + System.out.println(""); + return; + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/NormalExitTry.java b/java/java-tests/testData/refactoring/extractMethod/NormalExitTry.java new file mode 100644 index 000000000000..d170445f5624 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/NormalExitTry.java @@ -0,0 +1,17 @@ +class Test { + + private static void f(boolean a, boolean b) { + if (a) { + try { + System.out.println(); + return; + } + catch (Exception e) { + return; + } + } else { + System.out.println(""); + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethod/NormalExitTry_after.java b/java/java-tests/testData/refactoring/extractMethod/NormalExitTry_after.java new file mode 100644 index 000000000000..9f0a21499dbb --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/NormalExitTry_after.java @@ -0,0 +1,22 @@ +class Test { + + private static void f(boolean a, boolean b) { + if (a) { + newMethod(); + return; + } else { + System.out.println(""); + } + } + + private static void newMethod() { + try { + System.out.println(); + return; + } + catch (Exception e) { + return; + } + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java index d54f20e4719e..1600bfa069f4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/ex/InspectionProfileTest.java @@ -525,12 +525,12 @@ public class InspectionProfileTest extends LightIdeaTestCase { assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("bar"))); assertFalse(profile.isToolEnabled(HighlightDisplayKey.find("disabled"))); - assertTrue(profile.getToolDefaultState("bar", getProject()).isEnabled()); + assertFalse(profile.getToolDefaultState("bar", getProject()).isEnabled()); assertFalse(profile.getToolDefaultState("disabled", getProject()).isEnabled()); assertEquals("\n" + " ", serialize(profile)); @@ -623,7 +623,6 @@ public class InspectionProfileTest extends LightIdeaTestCase { InspectionProfileImpl foo = new InspectionProfileImpl("foo", InspectionToolRegistrar.getInstance(), InspectionProjectProfileManager.getInstance(getProject())); String test = "\n" + "