diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java index 95549f8162da..5235c0adaf90 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java @@ -32,10 +32,10 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Pass; -import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.*; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -58,11 +58,13 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; +import org.jetbrains.plugins.groovy.lang.psi.api.util.GrDeclarationHolder; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -120,6 +122,35 @@ public abstract class GrIntroduceHandlerBase ref) { + CommandProcessor.getInstance().executeCommand(ref.get().getProject(), new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + GrIntroduceContext context = ref.get(); + + GrExpression expression = cutLiteral(context.getStringPart(), context.getProject()); + + ref.set(new GrIntroduceContextImpl(context.getProject(), context.getEditor(), expression, null, null, new PsiElement[]{expression}, context.getScope())); + } + }); + } + }, getRefactoringName(), getRefactoringName()); + } + + protected void addBraces(@NotNull final GrStatement anchor, @NotNull final Ref contextRef) { + CommandProcessor.getInstance().executeCommand(contextRef.get().getProject(), new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + GrIntroduceContext context = contextRef.get(); + SmartPointerManager pointManager = SmartPointerManager.getInstance(context.getProject()); + SmartPsiElementPointer expressionRef = context.getExpression() != null ? pointManager.createSmartPsiElementPointer(context.getExpression()) : null; + SmartPsiElementPointer varRef = context.getVar() != null ? pointManager.createSmartPsiElementPointer(context.getVar()) : null; + + SmartPsiElementPointer[] occurrencesRefs = new SmartPsiElementPointer[context.getOccurrences().length]; + PsiElement[] occurrences = context.getOccurrences(); + for (int i = 0; i < occurrences.length; i++) { + occurrencesRefs[i] = pointManager.createSmartPsiElementPointer(occurrences[i]); + } + + + PsiFile file = anchor.getContainingFile(); + SmartPsiFileRange anchorPointer = pointManager.createSmartPsiFileRangePointer(file, anchor.getTextRange()); + + Document document = context.getEditor().getDocument(); + CharSequence sequence = document.getCharsSequence(); + + TextRange range = anchor.getTextRange(); + + int end = range.getEndOffset(); + document.insertString(end, "\n}"); + + int start = range.getStartOffset(); + while (start > 0 && Character.isWhitespace(sequence.charAt(start - 1))) { + start--; + } + document.insertString(start, "{"); + + PsiDocumentManager.getInstance(context.getProject()).commitDocument(document); + + Segment anchorSegment = anchorPointer.getRange(); + PsiElement restoredAnchor = GroovyRefactoringUtil.findElementInRange(file, anchorSegment.getStartOffset(), anchorSegment.getEndOffset(), PsiElement.class); + GrCodeBlock block = (GrCodeBlock)restoredAnchor.getParent(); + CodeStyleManager.getInstance(context.getProject()).reformat(block.getRBrace()); + CodeStyleManager.getInstance(context.getProject()).reformat(block.getLBrace()); + + for (int i = 0; i < occurrencesRefs.length; i++) { + occurrences[i] = occurrencesRefs[i].getElement(); + } + + contextRef.set(new GrIntroduceContextImpl(context.getProject(), context.getEditor(), + expressionRef != null ? expressionRef.getElement() : null, + varRef != null ? varRef.getElement() : null, + null, occurrences, context.getScope())); + } + }); + } + }, getRefactoringName(), getRefactoringName()); + } + + @NotNull + protected static GrStatement findAnchor(@NotNull final GrIntroduceContext context, final boolean replaceAll) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public GrStatement compute() { + PsiElement[] occurrences = replaceAll ? context.getOccurrences() : new GrExpression[]{context.getExpression()}; + return getAnchor(occurrences, context.getScope()); + } + }); + } + protected abstract void showScopeChooser(Scope[] scopes, Pass callback, Editor editor); public GrIntroduceContext getContext(@NotNull Project project, @@ -613,17 +731,15 @@ public abstract class GrIntroduceHandlerBase getIntroducer(@NotNull GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) { - return new GrInplaceFieldIntroducer(context, choice); + + final Ref contextRef = Ref.create(context); + + if (context.getStringPart() != null) { + extractStringPart(contextRef); + } + + return new GrInplaceFieldIntroducer(contextRef.get(), choice); } static EnumSet getApplicableInitPlaces(GrIntroduceContext context, boolean replaceAll) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java index bf7d719e21b8..50f07d5eb6af 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java @@ -54,6 +54,7 @@ import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -62,29 +63,39 @@ import java.util.List; public class GrIntroduceFieldProcessor { private static final Logger LOG = Logger.getInstance(GrIntroduceFieldProcessor.class); - private final GrIntroduceContext context; - private final GrIntroduceFieldSettings settings; + private final GrIntroduceContext myContext; + private final GrIntroduceFieldSettings mySettings; + private GrExpression myInitializer; + private GrVariable myLocalVariable; public GrIntroduceFieldProcessor(@NotNull GrIntroduceContext context, @NotNull GrIntroduceFieldSettings settings) { - this.context = context; - this.settings = settings; + this.myContext = context; + this.mySettings = settings; } + @Nullable public GrVariable run() { - PsiElement scope = context.getScope(); + PsiElement scope = myContext.getScope(); final PsiClass targetClass = scope instanceof GroovyFileBase ? ((GroovyFileBase)scope).getScriptClass() : (PsiClass)scope; if (targetClass == null) return null; final GrVariableDeclaration declaration = insertField(targetClass); final GrVariable field = declaration.getVariables()[0]; - switch (settings.initializeIn()) { + if (mySettings.removeLocalVar()) { + myLocalVariable = GrIntroduceHandlerBase.resolveLocalVar(myContext); + } + myInitializer = (GrExpression)getInitializer().copy(); + + List replaced = processOccurrences(targetClass, field); + + switch (mySettings.initializeIn()) { case CUR_METHOD: - initializeInMethod(field); + initializeInMethod(field, replaced); break; case FIELD_DECLARATION: - field.setInitializerGroovy(getInitializer()); + field.setInitializerGroovy(myInitializer); break; case CONSTRUCTOR: initializeInConstructor(field); @@ -96,44 +107,46 @@ public class GrIntroduceFieldProcessor { JavaCodeStyleManager.getInstance(declaration.getProject()).shortenClassReferences(declaration); - if (settings.removeLocalVar()) { - GrIntroduceHandlerBase.deleteLocalVar(context); + if (mySettings.removeLocalVar()) { + GrIntroduceHandlerBase.deleteLocalVar(myLocalVariable); } - processOccurrences(targetClass, field); - return field; } - private void processOccurrences(@NotNull PsiClass targetClass, @NotNull GrVariable field) { - if (context.getStringPart() != null) { - final GrExpression expr = GrIntroduceHandlerBase.processLiteral(field.getName(), context.getStringPart(), context.getProject()); + @NotNull + private List processOccurrences(@NotNull PsiClass targetClass, @NotNull GrVariable field) { + if (myContext.getStringPart() != null) { + final GrExpression expr = GrIntroduceHandlerBase.processLiteral(field.getName(), myContext.getStringPart(), myContext.getProject()); final PsiElement occurrence = replaceOccurrence(field, expr, targetClass); updateCaretPosition(occurrence); + return Collections.singletonList(occurrence); } else { - if (settings.replaceAllOccurrences()) { - GroovyRefactoringUtil.sortOccurrences(context.getOccurrences()); - for (PsiElement occurrence : context.getOccurrences()) { - replaceOccurrence(field, occurrence, targetClass); + if (mySettings.replaceAllOccurrences()) { + GroovyRefactoringUtil.sortOccurrences(myContext.getOccurrences()); + ArrayList result = ContainerUtil.newArrayList(); + for (PsiElement occurrence : myContext.getOccurrences()) { + result.add(replaceOccurrence(field, occurrence, targetClass)); } + return result; } else { - final GrExpression expression = context.getExpression(); + final GrExpression expression = myContext.getExpression(); assert expression != null; if (PsiUtil.isExpressionStatement(expression)) { - expression.delete(); + return Collections.singletonList(expression); } else { - replaceOccurrence(field, expression, targetClass); + return Collections.singletonList(replaceOccurrence(field, expression, targetClass)); } } } } - private void updateCaretPosition(PsiElement occurrence) { - context.getEditor().getCaretModel().moveToOffset(occurrence.getTextRange().getEndOffset()); - context.getEditor().getSelectionModel().removeSelection(); + private void updateCaretPosition(@NotNull PsiElement occurrence) { + myContext.getEditor().getCaretModel().moveToOffset(occurrence.getTextRange().getEndOffset()); + myContext.getEditor().getSelectionModel().removeSelection(); } @NotNull @@ -172,20 +185,20 @@ public class GrIntroduceFieldProcessor { return anchor; } - void initializeInSetup(GrVariable field) { - final PsiMethod setUpMethod = TestFrameworks.getInstance().findOrCreateSetUpMethod(((PsiClass)context.getScope())); + void initializeInSetup(@NotNull GrVariable field) { + final PsiMethod setUpMethod = TestFrameworks.getInstance().findOrCreateSetUpMethod(((PsiClass)myContext.getScope())); assert setUpMethod instanceof GrMethod; final GrOpenBlock body = ((GrMethod)setUpMethod).getBlock(); final PsiElement anchor = findAnchorForAssignment(body); - generateAssignment(field, (GrStatement)anchor, body); + generateAssignment(field, (GrStatement)anchor, body, null); } - void initializeInMethod(GrVariable field) { - final PsiElement _scope = context.getScope(); + void initializeInMethod(@NotNull GrVariable field, @NotNull List replaced) { + final PsiElement _scope = myContext.getScope(); final PsiElement scope = _scope instanceof GroovyScriptClass ? ((GroovyScriptClass)_scope).getContainingFile() : _scope; - final PsiElement place = context.getPlace(); + final PsiElement place = replaced.get(0); final GrMember member = GrIntroduceFieldHandler.getContainer(place, scope); GrStatementOwner container = member instanceof GrMethod ? ((GrMethod)member).getBlock() : @@ -195,21 +208,31 @@ public class GrIntroduceFieldProcessor { assert container != null; final PsiElement anchor; - if (settings.removeLocalVar()) { - GrVariable variable = GrIntroduceHandlerBase.resolveLocalVar(context); + if (mySettings.removeLocalVar()) { + GrVariable variable = myLocalVariable; anchor = PsiTreeUtil.getParentOfType(variable, GrStatement.class); } else { - anchor = GrIntroduceHandlerBase.findAnchor(context.getOccurrences(), container); - GrIntroduceHandlerBase.assertStatement(anchor, context.getScope()); + anchor = GrIntroduceHandlerBase.findAnchor(replaced.toArray(new PsiElement[replaced.size()]), container); + GrIntroduceHandlerBase.assertStatement(anchor, myContext.getScope()); } - generateAssignment(field, (GrStatement)anchor, container); + PsiElement occurrence = replaced.get(0); + if (!mySettings.replaceAllOccurrences() && !isRefToField(occurrence, field) && PsiUtil.isExpressionStatement(occurrence)) { + generateAssignment(field, (GrStatement)anchor, container, occurrence); + } + else { + generateAssignment(field, (GrStatement)anchor, container, null); + } + } + + private static boolean isRefToField(@NotNull PsiElement occurrence, @NotNull PsiElement field) { + return occurrence instanceof GrReferenceExpression && ((GrReferenceExpression)occurrence).resolve() == field; } void initializeInConstructor(@NotNull GrVariable field) { - final PsiClass scope = (PsiClass)context.getScope(); + final PsiClass scope = (PsiClass)myContext.getScope(); if (scope instanceof GrAnonymousClassDefinition) { initializeInAnonymousClassInitializer(field, (GrAnonymousClassDefinition)scope); @@ -230,7 +253,7 @@ public class GrIntroduceFieldProcessor { if (invocation != null && invocation.isThisCall()) continue; final PsiElement anchor = findAnchorForAssignment(((GrMethod)constructor).getBlock()); - generateAssignment(field, (GrStatement)anchor, ((GrMethod)constructor).getBlock()); + generateAssignment(field, (GrStatement)anchor, ((GrMethod)constructor).getBlock(), null); } } @@ -238,7 +261,7 @@ public class GrIntroduceFieldProcessor { private PsiMethod generateConstructor(@NotNull PsiClass scope) { final String name = scope.getName(); LOG.assertTrue(name != null, scope.getText()); - GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject()); + GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myContext.getProject()); final GrMethod constructor = factory.createConstructorFromText(name, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}", scope); if (scope instanceof GroovyScriptClass) constructor.getModifierList().setModifierProperty(GrModifier.DEF, true); @@ -247,20 +270,21 @@ public class GrIntroduceFieldProcessor { private void initializeInAnonymousClassInitializer(@NotNull GrVariable field, @NotNull GrAnonymousClassDefinition scope) { final GrClassInitializer[] initializers = scope.getInitializers(); - GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject()); + GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myContext.getProject()); final GrClassInitializer initializer = initializers.length == 0 ? (GrClassInitializer)scope.add(factory.createClassInitializer()) : initializers[0]; final PsiElement anchor = findAnchorForAssignment(initializer.getBlock()); - generateAssignment(field, (GrStatement)anchor, initializer.getBlock()); + generateAssignment(field, (GrStatement)anchor, initializer.getBlock(), null); } - private void generateAssignment(GrVariable field, + private void generateAssignment(@NotNull GrVariable field, @Nullable GrStatement anchor, - GrStatementOwner defaultContainer) { - final GrExpression initializer = getInitializer(); - GrAssignmentExpression init = (GrAssignmentExpression)GroovyPsiElementFactory.getInstance(context.getProject()) - .createExpressionFromText(settings.getName() + " = " + initializer.getText()); + @NotNull GrStatementOwner defaultContainer, + @Nullable PsiElement occurrenceToDelete) { + final GrExpression initializer = myInitializer; + GrAssignmentExpression init = (GrAssignmentExpression)GroovyPsiElementFactory.getInstance(myContext.getProject()) + .createExpressionFromText(mySettings.getName() + " = " + initializer.getText()); GrStatementOwner block; if (anchor != null) { @@ -273,19 +297,24 @@ public class GrIntroduceFieldProcessor { } init = (GrAssignmentExpression)block.addStatementBefore(init, anchor); - replaceOccurrence(field, init.getLValue(), (PsiClass)context.getScope()); + replaceOccurrence(field, init.getLValue(), (PsiClass)myContext.getScope()); + + if (occurrenceToDelete != null) { + occurrenceToDelete.delete(); + } } + @NotNull private GrExpression extractVarInitializer() { - final PsiElement resolved = GrIntroduceHandlerBase.resolveLocalVar(context); - GrExpression initializer = ((GrVariable)resolved).getInitializerGroovy(); + assert myLocalVariable != null; + GrExpression initializer = myLocalVariable.getInitializerGroovy(); LOG.assertTrue(initializer != null); return initializer; } @Nullable private PsiElement findAnchorForAssignment(final GrCodeBlock block) { - final List elements = ContainerUtil.findAll(context.getOccurrences(), new Condition() { + final List elements = ContainerUtil.findAll(myContext.getOccurrences(), new Condition() { @Override public boolean value(PsiElement element) { return PsiTreeUtil.isAncestor(block, element, true); @@ -295,8 +324,9 @@ public class GrIntroduceFieldProcessor { return GrIntroduceHandlerBase.findAnchor(ContainerUtil.toArray(elements, new PsiElement[elements.size()]), block); } - private PsiElement replaceOccurrence(GrVariable field, PsiElement occurrence, PsiClass containingClass) { - boolean isOriginal = occurrence == context.getExpression(); + @NotNull + private PsiElement replaceOccurrence(@NotNull GrVariable field, @NotNull PsiElement occurrence, @NotNull PsiClass containingClass) { + boolean isOriginal = occurrence == myContext.getExpression(); final GrReferenceExpression newExpr = createRefExpression(field, occurrence, containingClass); final PsiElement replaced; if (occurrence instanceof GrExpression) { @@ -315,7 +345,10 @@ public class GrIntroduceFieldProcessor { return replaced; } - private static GrReferenceExpression createRefExpression(GrVariable field, PsiElement place, PsiClass containingClass) { + @NotNull + private static GrReferenceExpression createRefExpression(@NotNull GrVariable field, + @NotNull PsiElement place, + @NotNull PsiClass containingClass) { final String qname = containingClass.getQualifiedName(); final String prefix = qname != null ? qname + "." : ""; final String refText; @@ -329,21 +362,22 @@ public class GrIntroduceFieldProcessor { return GroovyPsiElementFactory.getInstance(place.getProject()).createReferenceExpressionFromText(refText, place); } - private GrVariableDeclaration createField(PsiClass targetClass) { - final String name = settings.getName(); - final PsiType type = settings.getSelectedType(); - final String modifier = settings.getVisibilityModifier(); + @NotNull + private GrVariableDeclaration createField(@NotNull PsiClass targetClass) { + final String name = mySettings.getName(); + final PsiType type = mySettings.getSelectedType(); + final String modifier = mySettings.getVisibilityModifier(); List modifiers = new ArrayList(); if (targetClass instanceof GroovyScriptClass) { modifiers.add("@" + GroovyCommonClassNames.GROOVY_TRANSFORM_FIELD); } - if (settings.isStatic()) modifiers.add(PsiModifier.STATIC); + if (mySettings.isStatic()) modifiers.add(PsiModifier.STATIC); if (!PsiModifier.PACKAGE_LOCAL.equals(modifier)) modifiers.add(modifier); - if (settings.declareFinal()) modifiers.add(PsiModifier.FINAL); + if (mySettings.declareFinal()) modifiers.add(PsiModifier.FINAL); final String[] arr_modifiers = ArrayUtil.toStringArray(modifiers); - final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject()); + final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myContext.getProject()); if (targetClass instanceof GroovyScriptClass) { return factory.createVariableDeclaration(arr_modifiers, ((GrExpression)null), type, name); } @@ -354,17 +388,17 @@ public class GrIntroduceFieldProcessor { @NotNull protected GrExpression getInitializer() { - if (settings.removeLocalVar()) { + if (mySettings.removeLocalVar()) { return extractVarInitializer(); } - final GrExpression expression = context.getExpression(); + final GrExpression expression = myContext.getExpression(); if (expression != null) { return expression; } - return GrIntroduceHandlerBase.generateExpressionFromStringPart(context.getStringPart(), context.getProject()); + return GrIntroduceHandlerBase.generateExpressionFromStringPart(myContext.getStringPart(), myContext.getProject()); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java index 8755ad322df6..0aa7ca0b8718 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java @@ -19,7 +19,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.ArrayUtilRt; @@ -34,7 +33,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.util.GrDeclarationHolder; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; @@ -77,7 +75,7 @@ public abstract class GrIntroduceLocalVariableProcessor { int expressionIndex = ArrayUtilRt.find(myOccurrences, myExpression); final PsiElement[] replaced = myProcessUsages ? processOccurrences() : myOccurrences; PsiElement replacedExpression = replaced[expressionIndex]; - GrStatement anchor = getAnchor(replaced, myContext.getScope()); + GrStatement anchor = GrIntroduceHandlerBase.getAnchor(replaced, myContext.getScope()); RefactoringUtil.highlightAllOccurrences(myContext.getProject(), replaced, myContext.getEditor()); @@ -193,36 +191,6 @@ public abstract class GrIntroduceLocalVariableProcessor { return parent instanceof GrClosableBlock && parent.getParent() instanceof GrStringInjection; } - @NotNull - static GrStatement getAnchor(@NotNull PsiElement[] occurrences, @NotNull PsiElement scope) { - PsiElement parent = PsiTreeUtil.findCommonParent(occurrences); - PsiElement container = getEnclosingContainer(parent); - assert container != null; - PsiElement anchor = GrIntroduceHandlerBase.findAnchor(occurrences, container); - - GrIntroduceHandlerBase.assertStatement(anchor, scope); - return (GrStatement)anchor; - } - - @Nullable - public static PsiElement getEnclosingContainer(PsiElement place) { - PsiElement parent = place; - while (true) { - if (parent == null) { - return null; - } - if (parent instanceof GrDeclarationHolder && !(parent instanceof GrClosableBlock && parent.getParent() instanceof GrStringInjection)) { - return parent; - } - if (parent instanceof GrLoopStatement) { - return parent; - } - - parent = parent.getParent(); - } - } - - @Nullable private static String getFieldName(@Nullable PsiElement element) { if (element instanceof GrAccessorMethod) element = ((GrAccessorMethod)element).getProperty(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java index 2a84dc72b19c..6b016521eb1c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java @@ -15,14 +15,12 @@ */ package org.jetbrains.plugins.groovy.refactoring.introduce.variable; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.util.*; -import com.intellij.psi.*; -import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.openapi.util.Pass; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; import org.jetbrains.annotations.NotNull; @@ -36,7 +34,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; @@ -44,7 +41,6 @@ import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; -import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContextImpl; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase; import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; @@ -153,9 +149,6 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase ref) { - CommandProcessor.getInstance().executeCommand(ref.get().getProject(), new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - GrIntroduceContext context = ref.get(); - - GrExpression expression = cutLiteral(context.getStringPart(), context.getProject()); - - ref.set(new GrIntroduceContextImpl(context.getProject(), context.getEditor(), expression, null, null, new PsiElement[]{expression}, context.getScope())); - } - }); - } - }, REFACTORING_NAME, REFACTORING_NAME); - } - - private static void addBraces(@NotNull final GrStatement anchor, @NotNull final Ref contextRef) { - CommandProcessor.getInstance().executeCommand(contextRef.get().getProject(), new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - GrIntroduceContext context = contextRef.get(); - SmartPointerManager pointManager = SmartPointerManager.getInstance(context.getProject()); - SmartPsiElementPointer expressionRef = context.getExpression() != null ? pointManager.createSmartPsiElementPointer(context.getExpression()) : null; - SmartPsiElementPointer varRef = context.getVar() != null ? pointManager.createSmartPsiElementPointer(context.getVar()) : null; - - SmartPsiElementPointer[] occurrencesRefs = new SmartPsiElementPointer[context.getOccurrences().length]; - PsiElement[] occurrences = context.getOccurrences(); - for (int i = 0; i < occurrences.length; i++) { - occurrencesRefs[i] = pointManager.createSmartPsiElementPointer(occurrences[i]); - } - - - PsiFile file = anchor.getContainingFile(); - SmartPsiFileRange anchorPointer = pointManager.createSmartPsiFileRangePointer(file, anchor.getTextRange()); - - Document document = context.getEditor().getDocument(); - CharSequence sequence = document.getCharsSequence(); - - TextRange range = anchor.getTextRange(); - - int end = range.getEndOffset(); - document.insertString(end, "\n}"); - - int start = range.getStartOffset(); - while (start > 0 && Character.isWhitespace(sequence.charAt(start - 1))) { - start--; - } - document.insertString(start, "{"); - - PsiDocumentManager.getInstance(context.getProject()).commitDocument(document); - - Segment anchorSegment = anchorPointer.getRange(); - PsiElement restoredAnchor = GroovyRefactoringUtil.findElementInRange(file, anchorSegment.getStartOffset(), anchorSegment.getEndOffset(), PsiElement.class); - GrCodeBlock block = (GrCodeBlock)restoredAnchor.getParent(); - CodeStyleManager.getInstance(context.getProject()).reformat(block.getRBrace()); - CodeStyleManager.getInstance(context.getProject()).reformat(block.getLBrace()); - - for (int i = 0; i < occurrencesRefs.length; i++) { - occurrences[i] = occurrencesRefs[i].getElement(); - } - - contextRef.set(new GrIntroduceContextImpl(context.getProject(), context.getEditor(), - expressionRef != null ? expressionRef.getElement() : null, - varRef != null ? varRef.getElement() : null, - null, occurrences, context.getScope())); - } - }); - } - }, REFACTORING_NAME, REFACTORING_NAME); - } - private static GrVariable addVariable(@NotNull GrIntroduceContext context, @NotNull GroovyIntroduceVariableSettings settings) { GrStatement anchor = findAnchor(context, settings.replaceAllOccurrences()); PsiElement parent = anchor.getParent(); @@ -254,17 +171,6 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase() { - @Override - public GrStatement compute() { - PsiElement[] occurrences = replaceAll ? context.getOccurrences() : new GrExpression[]{context.getExpression()}; - return GrIntroduceLocalVariableProcessor.getAnchor(occurrences, context.getScope()); - } - }); - } - @Override protected void showScopeChooser(GrControlFlowOwner[] scopes, Pass callback, Editor editor) { //todo do nothing right now diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldTest.groovy index 0488a0d97e0b..911f3a4118ab 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldTest.groovy @@ -307,6 +307,27 @@ class GroovyLightProjectDescriptor { ''', false, false, false, CUR_METHOD) } + void testInitializeInMethodInThenBranch() { + doTest('''\ +class A { + def foo() { + if (abc) print 2 + } +} +''', '''\ +class A { + def f + + def foo() { + if (abc) { + f = 2 + print f + } + } +} +''', false, false, false, CUR_METHOD, false, null) + } + private void doTest(final boolean isStatic, final boolean removeLocal, diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceVariable/IntroduceVariableValidatorTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceVariable/IntroduceVariableValidatorTest.java index 8771d06e3e32..8e85f1db8776 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceVariable/IntroduceVariableValidatorTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceVariable/IntroduceVariableValidatorTest.java @@ -29,7 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContextImpl; -import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GrIntroduceLocalVariableProcessor; +import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase; import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GroovyVariableValidator; import org.jetbrains.plugins.groovy.util.TestUtils; @@ -84,7 +84,7 @@ public class IntroduceVariableValidatorTest extends LightCodeInsightFixtureTestC Assert.assertNotNull("Selected expression reference points to null", selectedExpr); - final PsiElement tempContainer = GrIntroduceLocalVariableProcessor.getEnclosingContainer(selectedExpr); + final PsiElement tempContainer = GrIntroduceHandlerBase.getEnclosingContainer(selectedExpr); Assert.assertTrue(tempContainer instanceof GroovyPsiElement); PsiElement[] occurences = GroovyRefactoringUtil.getExpressionOccurrences(PsiUtil.skipParentheses(selectedExpr, false), tempContainer);