inplace introduce variable: ensure validity of created var

EA-63354 - PIEAE: CompositePsiElement.getContainingFile
This commit is contained in:
Anna.Kozlova
2016-10-17 13:10:49 +02:00
parent 45f6ba5775
commit 0cb5558e85
5 changed files with 52 additions and 18 deletions
@@ -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<PsiVariable> 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<PsiVariable>() {
SmartPsiElementPointer<PsiVariable> pointer = ApplicationManager.getApplication().runWriteAction(new Computable<SmartPsiElementPointer<PsiVariable>> () {
@Override
public PsiVariable compute() {
public SmartPsiElementPointer<PsiVariable> 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) {
@@ -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<RangeMarker> 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());
@@ -0,0 +1,10 @@
class C {
void sort(int[] array) {
int j;
for (int i = 0; i < array.length; i++) {
j = 0;
while (j<i)&&(array[j]<caret>>array[i])
}
}
}
@@ -0,0 +1,10 @@
class C {
void sort(int[] array) {
int j;
for (int i = 0; i < array.length; i++) {
j = 0;
while (j<i) boolean bool = array[j] > array[i];&&(array[j] > array[i])
}
}
}
@@ -205,6 +205,15 @@ public class InplaceIntroduceVariableTest extends AbstractJavaInplaceIntroduceTe
doTestReplaceChoice(OccurrencesChooser.ReplaceChoice.ALL);
}
public void testBrokenFormattingWithInValidation() throws Exception {
doTest(new Pass<AbstractInplaceIntroducer>() {
@Override
public void pass(AbstractInplaceIntroducer introducer) {
type("bool");
}
});
}
public void testStopEditing() {
doTestStopEditing(new Pass<AbstractInplaceIntroducer>() {
@Override