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 614f204c6a95..fa92d548a366 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -699,8 +699,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { final PsiElement chosenAnchor = chooseAnchor(settings.isReplaceAllOccurrences(), hasWriteAccess, nonWrite, anchorStatementIfAll, anchorStatement); - variable = ApplicationManager.getApplication().runWriteAction( - introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings)); + variable = introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings); } finally { final RefactoringEventData afterData = new RefactoringEventData(); @@ -794,12 +793,12 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { return parent3 instanceof JspHolderMethod; } - public static Computable introduce(final Project project, - final PsiExpression expr, - final Editor editor, - final PsiElement anchorStatement, - final PsiExpression[] occurrences, - final IntroduceVariableSettings settings) { + public static PsiVariable introduce(final Project project, + final PsiExpression expr, + final Editor editor, + final PsiElement anchorStatement, + final PsiExpression[] occurrences, + final IntroduceVariableSettings settings) { final PsiElement container = anchorStatement.getParent(); PsiElement child = anchorStatement; final boolean isInsideLoop = RefactoringUtil.isLoopOrIf(container); @@ -841,9 +840,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { final PsiCodeBlock newDeclarationScope = PsiTreeUtil.getParentOfType(container, PsiCodeBlock.class, false); final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(settings.getEnteredName(), newDeclarationScope); - return new Computable() { + SmartPsiElementPointer pointer = ApplicationManager.getApplication().runWriteAction(new Computable> () { @Override - public PsiVariable compute() { + public SmartPsiElementPointer compute() { try { PsiStatement statement = null; if (!isInsideLoop && deleteSelf) { @@ -913,7 +912,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { PsiVariable var = (PsiVariable) declaration.getDeclaredElements()[0]; PsiUtil.setModifierProperty(var, PsiModifier.FINAL, settings.isDeclareFinal()); fieldConflictsResolver.fix(); - return var; + return SmartPointerManager.getInstance(project).createSmartPsiElementPointer(var); } catch (IncorrectOperationException e) { LOG.error(e); } @@ -945,7 +944,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { } return (PsiDeclarationStatement) container.addBefore(declaration, anchor); } - }; + }); + return pointer != null ? pointer.getElement() : null; } private static PsiType stripNullabilityAnnotationsFromTargetType(SmartTypePointer selectedType, final Project project) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java index c6ad929835b0..a53c51acc6c8 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/JavaVariableInplaceIntroducer.java @@ -395,10 +395,19 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer @Override protected PsiVariable createFieldToStartTemplateOn(String[] names, PsiType psiType) { - final PsiVariable variable = ApplicationManager.getApplication().runWriteAction( - IntroduceVariableBase.introduce(myProject, myExpr, myEditor, myChosenAnchor.getElement(), getOccurrences(), mySettings)); + PsiVariable variable = IntroduceVariableBase.introduce(myProject, myExpr, myEditor, myChosenAnchor.getElement(), getOccurrences(), mySettings); + final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class); + myPointer = declarationStatement != null ? SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(declarationStatement) : null; + myEditor.putUserData(ReassignVariableUtil.DECLARATION_KEY, myPointer); + setAdvertisementText(getAdvertisementText(declarationStatement, variable.getType(), myHasTypeSuggestion)); + PsiDocumentManager.getInstance(myProject).doPostponedOperationsAndUnblockDocument(myEditor.getDocument()); + final PsiVariable restoredVar = getVariable(); + if (restoredVar != null) { + variable = restoredVar; + } + if (isReplaceAllOccurrences()) { List occurrences = new ArrayList<>(); ReferencesSearch.search(variable).forEach(reference -> { @@ -407,10 +416,6 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer setOccurrenceMarkers(occurrences); } - final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class); - myPointer = declarationStatement != null ? SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(declarationStatement) : null; - myEditor.putUserData(ReassignVariableUtil.DECLARATION_KEY, myPointer); - setAdvertisementText(getAdvertisementText(declarationStatement, variable.getType(), myHasTypeSuggestion)); final PsiIdentifier identifier = variable.getNameIdentifier(); if (identifier != null) { myEditor.getCaretModel().moveToOffset(identifier.getTextOffset()); diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceVariable/brokenFormattingWithInValidation.java b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/brokenFormattingWithInValidation.java new file mode 100644 index 000000000000..06b06cbd5f32 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/brokenFormattingWithInValidation.java @@ -0,0 +1,10 @@ +class C { + void sort(int[] array) { + int j; + for (int i = 0; i < array.length; i++) { + j = 0; + while (j>array[i]) + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceVariable/brokenFormattingWithInValidation_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/brokenFormattingWithInValidation_after.java new file mode 100644 index 000000000000..b36d03646293 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceVariable/brokenFormattingWithInValidation_after.java @@ -0,0 +1,10 @@ +class C { + void sort(int[] array) { + int j; + for (int i = 0; i < array.length; i++) { + j = 0; + while (j array[i];&&(array[j] > array[i]) + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java index 5e9ca964059c..44a86d4a2388 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceVariableTest.java @@ -205,6 +205,15 @@ public class InplaceIntroduceVariableTest extends AbstractJavaInplaceIntroduceTe doTestReplaceChoice(OccurrencesChooser.ReplaceChoice.ALL); } + public void testBrokenFormattingWithInValidation() throws Exception { + doTest(new Pass() { + @Override + public void pass(AbstractInplaceIntroducer introducer) { + type("bool"); + } + }); + } + public void testStopEditing() { doTestStopEditing(new Pass() { @Override