mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
inplace introduce field
This commit is contained in:
+260
-208
@@ -32,7 +32,9 @@ import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.ide.util.DirectoryChooserUtil;
|
||||
import com.intellij.ide.util.PackageUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
@@ -70,7 +72,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase implements RefactoringActionHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler");
|
||||
@@ -152,15 +153,6 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
}
|
||||
final PsiType type = tempType;
|
||||
|
||||
final String fieldName = settings.getFieldName();
|
||||
final PsiElement anchorElementIfOne = tempAnchorElement;
|
||||
final boolean replaceAll = settings.isReplaceAll();
|
||||
if (replaceAll) {
|
||||
tempAnchorElement = anchorStatementIfAll;
|
||||
}
|
||||
final PsiElement anchorElement = tempAnchorElement;
|
||||
|
||||
|
||||
if (editor != null) {
|
||||
HighlightManager highlightManager = HighlightManager.getInstance(project);
|
||||
for (RangeHighlighter highlighter : highlighters) {
|
||||
@@ -168,194 +160,18 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement anchor = getNormalizedAnchor(anchorElement);
|
||||
|
||||
final Boolean outOfCodeBlockExtraction = selectedExpr.getUserData(ElementToWorkOn.OUT_OF_CODE_BLOCK);
|
||||
boolean tempDeleteSelf = outOfCodeBlockExtraction != null;
|
||||
if (element.getParent() instanceof PsiExpressionStatement && anchor.equals(anchorElement)) {
|
||||
PsiStatement statement = (PsiStatement)element.getParent();
|
||||
if (statement.getParent() instanceof PsiCodeBlock) {
|
||||
tempDeleteSelf = true;
|
||||
final Runnable runnable =
|
||||
new ConvertToFieldRunnable(selectedExpr, settings, type, occurrences, occurenceManager,
|
||||
anchorStatementIfAll, tempAnchorElement, editor,
|
||||
myParentClass);
|
||||
|
||||
new WriteCommandAction(project, getRefactoringName()){
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
final boolean deleteSelf = tempDeleteSelf;
|
||||
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
PsiExpression expr = selectedExpr;
|
||||
InitializationPlace initializerPlace = settings.getInitializerPlace();
|
||||
final PsiLocalVariable localVariable = settings.getLocalVariable();
|
||||
final boolean deleteLocalVariable = settings.isDeleteLocalVariable();
|
||||
@Nullable PsiExpression initializer;
|
||||
if (localVariable != null) {
|
||||
initializer = localVariable.getInitializer();
|
||||
}
|
||||
else {
|
||||
initializer = expr;
|
||||
}
|
||||
|
||||
final PsiMethod enclosingConstructor = getEnclosingConstructor(myParentClass, anchorElement);
|
||||
final PsiClass destClass = settings.getDestinationClass() == null ? myParentClass : settings.getDestinationClass();
|
||||
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, destClass.getContainingFile())) return;
|
||||
|
||||
if (initializer != null) {
|
||||
ChangeContextUtil.encodeContextInfo(initializer, true);
|
||||
}
|
||||
PsiField field = settings.isIntroduceEnumConstant() ? EnumConstantsUtil.createEnumConstant(destClass, fieldName, initializer) : createField(fieldName, type, initializer, initializerPlace == InitializationPlace.IN_FIELD_DECLARATION && initializer != null);
|
||||
|
||||
PsiElement finalAnchorElement = null;
|
||||
if (destClass == myParentClass) {
|
||||
for (finalAnchorElement = anchorElement;
|
||||
finalAnchorElement != null && finalAnchorElement.getParent() != destClass;
|
||||
finalAnchorElement = finalAnchorElement.getParent()) {
|
||||
|
||||
}
|
||||
}
|
||||
PsiMember anchorMember = finalAnchorElement instanceof PsiMember ? (PsiMember)finalAnchorElement : null;
|
||||
setModifiers(field, settings, settings.isDeclareStatic());
|
||||
if ((anchorMember instanceof PsiField) &&
|
||||
anchorMember.hasModifierProperty(PsiModifier.STATIC) == field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
field = (PsiField)destClass.addBefore(field, anchorMember);
|
||||
}
|
||||
else if (anchorMember instanceof PsiClassInitializer) {
|
||||
field = (PsiField)destClass.addBefore(field, anchorMember);
|
||||
destClass.addBefore(CodeEditUtil.createLineFeed(field.getManager()), anchorMember);
|
||||
}
|
||||
else {
|
||||
final PsiField forwardReference = checkForwardRefs(initializer);
|
||||
if (forwardReference != null) {
|
||||
field = (PsiField)destClass.addAfter(field, forwardReference);
|
||||
} else {
|
||||
field = (PsiField)destClass.add(field);
|
||||
}
|
||||
}
|
||||
if (!settings.isIntroduceEnumConstant()) {
|
||||
VisibilityUtil.fixVisibility(occurrences, field, settings.getFieldVisibility());
|
||||
}
|
||||
PsiStatement assignStatement = null;
|
||||
PsiElement anchorElementHere = null;
|
||||
if (initializerPlace == InitializationPlace.IN_CURRENT_METHOD && initializer != null ||
|
||||
initializerPlace == InitializationPlace.IN_CONSTRUCTOR && enclosingConstructor != null && initializer != null) {
|
||||
if (replaceAll) {
|
||||
if (enclosingConstructor != null) {
|
||||
final PsiElement anchorInConstructor = occurenceManager.getAnchorStatementForAllInScope(enclosingConstructor);
|
||||
anchorElementHere = anchorInConstructor != null ? anchorInConstructor : anchorStatementIfAll;
|
||||
}
|
||||
else {
|
||||
anchorElementHere = anchorStatementIfAll;
|
||||
}
|
||||
}
|
||||
else {
|
||||
anchorElementHere = anchorElementIfOne;
|
||||
}
|
||||
assignStatement = createAssignment(field, initializer, anchorElementHere);
|
||||
if (!IntroduceVariableBase.isLoopOrIf(anchorElementHere.getParent())) {
|
||||
anchorElementHere.getParent().addBefore(assignStatement, getNormalizedAnchor(anchorElementHere));
|
||||
}
|
||||
}
|
||||
if (initializerPlace == InitializationPlace.IN_CONSTRUCTOR && initializer != null) {
|
||||
addInitializationToConstructors(initializer, field, enclosingConstructor);
|
||||
}
|
||||
if (initializerPlace == InitializationPlace.IN_SETUP_METHOD && initializer != null) {
|
||||
addInitializationToSetUp(initializer, field, occurenceManager, replaceAll);
|
||||
}
|
||||
if (expr.getParent() instanceof PsiParenthesizedExpression) {
|
||||
expr = (PsiExpression)expr.getParent();
|
||||
}
|
||||
if (outOfCodeBlockExtraction != null) {
|
||||
final int endOffset = selectedExpr.getUserData(ElementToWorkOn.TEXT_RANGE).getEndOffset();
|
||||
PsiElement endElement = element.getContainingFile().findElementAt(endOffset);
|
||||
while (true) {
|
||||
final PsiElement parent = endElement.getParent();
|
||||
if (parent instanceof PsiClass) break;
|
||||
endElement = parent;
|
||||
}
|
||||
element.getParent().deleteChildRange(element, PsiTreeUtil.skipSiblingsBackward(endElement, PsiWhiteSpace.class));
|
||||
} else if (deleteSelf) {
|
||||
element.getParent().delete();
|
||||
}
|
||||
|
||||
if (replaceAll) {
|
||||
List<PsiElement> array = new ArrayList<PsiElement>();
|
||||
for (PsiExpression occurrence : occurrences) {
|
||||
if (occurrence instanceof PsiExpression) {
|
||||
occurrence = RefactoringUtil.outermostParenthesizedExpression(occurrence);
|
||||
}
|
||||
if (deleteSelf && occurrence.equals(expr)) continue;
|
||||
final PsiElement replaced = RefactoringUtil.replaceOccurenceWithFieldRef(occurrence, field, destClass);
|
||||
if (replaced != null) {
|
||||
array.add(replaced);
|
||||
}
|
||||
}
|
||||
|
||||
if (editor != null) {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
PsiElement[] exprsToHighlight = PsiUtilBase.toPsiElementArray(array);
|
||||
HighlightManager highlightManager = HighlightManager.getInstance(project);
|
||||
highlightManager.addOccurrenceHighlights(editor, exprsToHighlight, highlightAttributes(), true, null);
|
||||
WindowManager.getInstance().getStatusBar(project).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!deleteSelf) {
|
||||
expr = RefactoringUtil.outermostParenthesizedExpression(expr);
|
||||
RefactoringUtil.replaceOccurenceWithFieldRef(expr, field, destClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (anchorElementHere != null && IntroduceVariableBase.isLoopOrIf(anchorElementHere.getParent())) {
|
||||
IntroduceVariableBase.putStatementInLoopBody(assignStatement, anchorElementHere.getParent(), anchorElementHere);
|
||||
}
|
||||
|
||||
|
||||
if (localVariable != null) {
|
||||
if (deleteLocalVariable) {
|
||||
localVariable.normalizeDeclaration();
|
||||
localVariable.getParent().delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (initializer != null) {
|
||||
ChangeContextUtil.clearContextInfo(initializer);
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private PsiField checkForwardRefs(PsiExpression initializer) {
|
||||
final PsiField[] refConstantFields = new PsiField[1];
|
||||
initializer.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiElement resolve = expression.resolve();
|
||||
if (resolve instanceof PsiField &&
|
||||
((PsiField)resolve).hasModifierProperty(PsiModifier.FINAL) &&
|
||||
PsiTreeUtil.isAncestor(myParentClass, resolve, false) && ((PsiField)resolve).hasInitializer()) {
|
||||
if (refConstantFields[0] == null || refConstantFields[0].getTextOffset() < resolve.getTextOffset()) {
|
||||
refConstantFields[0] = (PsiField)resolve;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return refConstantFields[0];
|
||||
}
|
||||
};
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(
|
||||
project,
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
}
|
||||
},
|
||||
getRefactoringName(), null
|
||||
);
|
||||
}.execute();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -452,10 +268,12 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addInitializationToSetUp(final PsiExpression initializer,
|
||||
final PsiField field,
|
||||
final OccurenceManager occurenceManager, final boolean replaceAll) throws IncorrectOperationException {
|
||||
final PsiMethod setupMethod = TestUtil.findOrCreateSetUpMethod(myParentClass);
|
||||
private static void addInitializationToSetUp(final PsiExpression initializer,
|
||||
final PsiField field,
|
||||
final OccurenceManager occurenceManager,
|
||||
final boolean replaceAll,
|
||||
final PsiClass parentClass) throws IncorrectOperationException {
|
||||
final PsiMethod setupMethod = TestUtil.findOrCreateSetUpMethod(parentClass);
|
||||
|
||||
assert setupMethod != null;
|
||||
|
||||
@@ -467,7 +285,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
}
|
||||
|
||||
final PsiExpressionStatement expressionStatement =
|
||||
(PsiExpressionStatement)JavaPsiFacade.getInstance(myParentClass.getProject()).getElementFactory()
|
||||
(PsiExpressionStatement)JavaPsiFacade.getInstance(parentClass.getProject()).getElementFactory()
|
||||
.createStatementFromText(field.getName() + "= expr;", null);
|
||||
PsiAssignmentExpression expr = (PsiAssignmentExpression)expressionStatement.getExpression();
|
||||
final PsiExpression rExpression = expr.getRExpression();
|
||||
@@ -479,7 +297,9 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
body.addBefore(expressionStatement, anchor);
|
||||
}
|
||||
|
||||
private void addInitializationToConstructors(PsiExpression initializerExpression, PsiField field, PsiMethod enclosingConstructor) {
|
||||
private static void addInitializationToConstructors(PsiExpression initializerExpression,
|
||||
PsiField field,
|
||||
PsiMethod enclosingConstructor, final PsiClass parentClass) {
|
||||
try {
|
||||
PsiClass aClass = field.getContainingClass();
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
@@ -502,7 +322,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiStatement assignment = createAssignment(field, initializerExpression, body.getLastChild());
|
||||
PsiStatement assignment = createAssignment(field, initializerExpression, body.getLastChild(), parentClass);
|
||||
assignment = (PsiStatement) body.add(assignment);
|
||||
ChangeContextUtil.decodeContextInfo(assignment, field.getContainingClass(),
|
||||
RefactoringUtil.createThisExpression(field.getManager(), null));
|
||||
@@ -512,7 +332,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();
|
||||
PsiMethod constructor = (PsiMethod)aClass.add(factory.createConstructor());
|
||||
final PsiCodeBlock body = constructor.getBody();
|
||||
PsiStatement assignment = createAssignment(field, initializerExpression, body.getLastChild());
|
||||
PsiStatement assignment = createAssignment(field, initializerExpression, body.getLastChild(), parentClass);
|
||||
assignment = (PsiStatement) body.add(assignment);
|
||||
ChangeContextUtil.decodeContextInfo(assignment, field.getContainingClass(),
|
||||
RefactoringUtil.createThisExpression(field.getManager(), null));
|
||||
@@ -523,7 +343,10 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
}
|
||||
}
|
||||
|
||||
private PsiField createField(String fieldName, PsiType type, PsiExpression initializerExpr, boolean includeInitializer) {
|
||||
private static PsiField createField(String fieldName,
|
||||
PsiType type,
|
||||
PsiExpression initializerExpr,
|
||||
boolean includeInitializer, final PsiClass parentClass) {
|
||||
@NonNls StringBuilder pattern = new StringBuilder();
|
||||
pattern.append("private int ");
|
||||
pattern.append(fieldName);
|
||||
@@ -531,7 +354,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
pattern.append("=0");
|
||||
}
|
||||
pattern.append(";");
|
||||
PsiManager psiManager = myParentClass.getManager();
|
||||
PsiManager psiManager = parentClass.getManager();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
|
||||
try {
|
||||
PsiField field = factory.createFieldFromText(pattern.toString(), null);
|
||||
@@ -548,10 +371,13 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
}
|
||||
}
|
||||
|
||||
private PsiStatement createAssignment(PsiField field, PsiExpression initializerExpr, PsiElement context) {
|
||||
private static PsiStatement createAssignment(PsiField field,
|
||||
PsiExpression initializerExpr,
|
||||
PsiElement context,
|
||||
final PsiClass parentClass) {
|
||||
try {
|
||||
@NonNls String pattern = "x=0;";
|
||||
PsiManager psiManager = myParentClass.getManager();
|
||||
PsiManager psiManager = parentClass.getManager();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
|
||||
PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, null);
|
||||
statement = (PsiExpressionStatement)CodeStyleManager.getInstance(psiManager.getProject()).reformat(statement);
|
||||
@@ -733,4 +559,230 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
|
||||
return myTargetClass;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConvertToFieldRunnable implements Runnable {
|
||||
private PsiExpression mySelectedExpr;
|
||||
private final Settings mySettings;
|
||||
private final PsiElement myAnchorElement;
|
||||
private final Project myProject;
|
||||
private final String myFieldName;
|
||||
private final PsiType myType;
|
||||
private final PsiExpression[] myOccurrences;
|
||||
private final boolean myReplaceAll;
|
||||
private final OccurenceManager myOccurenceManager;
|
||||
private final PsiElement myAnchorStatementIfAll;
|
||||
private final PsiElement myAnchorElementIfOne;
|
||||
private final Boolean myOutOfCodeBlockExtraction;
|
||||
private final PsiElement myElement;
|
||||
private boolean myDeleteSelf;
|
||||
private final Editor myEditor;
|
||||
private final PsiClass myParentClass;
|
||||
|
||||
private PsiField myField;
|
||||
|
||||
public ConvertToFieldRunnable(PsiExpression selectedExpr,
|
||||
Settings settings,
|
||||
PsiType type,
|
||||
PsiExpression[] occurrences,
|
||||
OccurenceManager occurenceManager,
|
||||
PsiElement anchorStatementIfAll,
|
||||
PsiElement anchorElementIfOne,
|
||||
Editor editor,
|
||||
PsiClass parentClass) {
|
||||
mySelectedExpr = selectedExpr;
|
||||
mySettings = settings;
|
||||
myAnchorElement = settings.isReplaceAll() ? anchorStatementIfAll : anchorElementIfOne;
|
||||
myProject = selectedExpr.getProject();
|
||||
myFieldName = settings.getFieldName();
|
||||
myType = type;
|
||||
myOccurrences = occurrences;
|
||||
myReplaceAll = settings.isReplaceAll();
|
||||
myOccurenceManager = occurenceManager;
|
||||
myAnchorStatementIfAll = anchorStatementIfAll;
|
||||
myAnchorElementIfOne = anchorElementIfOne;
|
||||
myOutOfCodeBlockExtraction = selectedExpr.getUserData(ElementToWorkOn.OUT_OF_CODE_BLOCK);
|
||||
myDeleteSelf = myOutOfCodeBlockExtraction != null;
|
||||
myElement = getPhysicalElement(selectedExpr);
|
||||
if (myElement.getParent() instanceof PsiExpressionStatement && getNormalizedAnchor(myAnchorElement).equals(myAnchorElement)) {
|
||||
PsiStatement statement = (PsiStatement)myElement.getParent();
|
||||
if (statement.getParent() instanceof PsiCodeBlock) {
|
||||
myDeleteSelf = true;
|
||||
}
|
||||
}
|
||||
|
||||
myEditor = editor;
|
||||
myParentClass = parentClass;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
InitializationPlace initializerPlace = mySettings.getInitializerPlace();
|
||||
final PsiLocalVariable localVariable = mySettings.getLocalVariable();
|
||||
final boolean deleteLocalVariable = mySettings.isDeleteLocalVariable();
|
||||
@Nullable PsiExpression initializer;
|
||||
if (localVariable != null) {
|
||||
initializer = localVariable.getInitializer();
|
||||
}
|
||||
else {
|
||||
initializer = mySelectedExpr;
|
||||
}
|
||||
|
||||
final PsiMethod enclosingConstructor = getEnclosingConstructor(myParentClass, myAnchorElement);
|
||||
final PsiClass destClass = mySettings.getDestinationClass() == null ? myParentClass : mySettings.getDestinationClass();
|
||||
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, destClass.getContainingFile())) return;
|
||||
|
||||
if (initializer != null) {
|
||||
ChangeContextUtil.encodeContextInfo(initializer, true);
|
||||
}
|
||||
myField = mySettings.isIntroduceEnumConstant() ? EnumConstantsUtil.createEnumConstant(destClass, myFieldName, initializer) :
|
||||
createField(myFieldName, myType, initializer, initializerPlace == InitializationPlace.IN_FIELD_DECLARATION && initializer != null,
|
||||
myParentClass);
|
||||
|
||||
PsiElement finalAnchorElement = null;
|
||||
if (destClass == myParentClass) {
|
||||
for (finalAnchorElement = myAnchorElement;
|
||||
finalAnchorElement != null && finalAnchorElement.getParent() != destClass;
|
||||
finalAnchorElement = finalAnchorElement.getParent()) {
|
||||
|
||||
}
|
||||
}
|
||||
PsiMember anchorMember = finalAnchorElement instanceof PsiMember ? (PsiMember)finalAnchorElement : null;
|
||||
setModifiers(myField, mySettings, mySettings.isDeclareStatic());
|
||||
if ((anchorMember instanceof PsiField) &&
|
||||
anchorMember.hasModifierProperty(PsiModifier.STATIC) == myField.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
myField = (PsiField)destClass.addBefore(myField, anchorMember);
|
||||
}
|
||||
else if (anchorMember instanceof PsiClassInitializer) {
|
||||
myField = (PsiField)destClass.addBefore(myField, anchorMember);
|
||||
destClass.addBefore(CodeEditUtil.createLineFeed(myField.getManager()), anchorMember);
|
||||
}
|
||||
else {
|
||||
final PsiField forwardReference = checkForwardRefs(initializer);
|
||||
if (forwardReference != null) {
|
||||
myField = (PsiField)destClass.addAfter(myField, forwardReference);
|
||||
} else {
|
||||
myField = (PsiField)destClass.add(myField);
|
||||
}
|
||||
}
|
||||
if (!mySettings.isIntroduceEnumConstant()) {
|
||||
VisibilityUtil.fixVisibility(myOccurrences, myField, mySettings.getFieldVisibility());
|
||||
}
|
||||
PsiStatement assignStatement = null;
|
||||
PsiElement anchorElementHere = null;
|
||||
if (initializerPlace == InitializationPlace.IN_CURRENT_METHOD && initializer != null ||
|
||||
initializerPlace == InitializationPlace.IN_CONSTRUCTOR && enclosingConstructor != null && initializer != null) {
|
||||
if (myReplaceAll) {
|
||||
if (enclosingConstructor != null) {
|
||||
final PsiElement anchorInConstructor = myOccurenceManager.getAnchorStatementForAllInScope(enclosingConstructor);
|
||||
anchorElementHere = anchorInConstructor != null ? anchorInConstructor : myAnchorStatementIfAll;
|
||||
}
|
||||
else {
|
||||
anchorElementHere = myAnchorStatementIfAll;
|
||||
}
|
||||
}
|
||||
else {
|
||||
anchorElementHere = myAnchorElementIfOne;
|
||||
}
|
||||
assignStatement = createAssignment(myField, initializer, anchorElementHere, myParentClass);
|
||||
if (!IntroduceVariableBase.isLoopOrIf(anchorElementHere.getParent())) {
|
||||
anchorElementHere.getParent().addBefore(assignStatement, getNormalizedAnchor(anchorElementHere));
|
||||
}
|
||||
}
|
||||
if (initializerPlace == InitializationPlace.IN_CONSTRUCTOR && initializer != null) {
|
||||
addInitializationToConstructors(initializer, myField, enclosingConstructor, myParentClass);
|
||||
}
|
||||
if (initializerPlace == InitializationPlace.IN_SETUP_METHOD && initializer != null) {
|
||||
addInitializationToSetUp(initializer, myField, myOccurenceManager, myReplaceAll, myParentClass);
|
||||
}
|
||||
if (mySelectedExpr.getParent() instanceof PsiParenthesizedExpression) {
|
||||
mySelectedExpr = (PsiExpression)mySelectedExpr.getParent();
|
||||
}
|
||||
if (myOutOfCodeBlockExtraction != null) {
|
||||
final int endOffset = mySelectedExpr.getUserData(ElementToWorkOn.TEXT_RANGE).getEndOffset();
|
||||
PsiElement endElement = myElement.getContainingFile().findElementAt(endOffset);
|
||||
while (true) {
|
||||
final PsiElement parent = endElement.getParent();
|
||||
if (parent instanceof PsiClass) break;
|
||||
endElement = parent;
|
||||
}
|
||||
myElement.getParent().deleteChildRange(myElement, PsiTreeUtil.skipSiblingsBackward(endElement, PsiWhiteSpace.class));
|
||||
} else if (myDeleteSelf) {
|
||||
myElement.getParent().delete();
|
||||
}
|
||||
|
||||
if (myReplaceAll) {
|
||||
List<PsiElement> array = new ArrayList<PsiElement>();
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
if (occurrence instanceof PsiExpression) {
|
||||
occurrence = RefactoringUtil.outermostParenthesizedExpression(occurrence);
|
||||
}
|
||||
if (myDeleteSelf && occurrence.equals(mySelectedExpr)) continue;
|
||||
final PsiElement replaced = RefactoringUtil.replaceOccurenceWithFieldRef(occurrence, myField, destClass);
|
||||
if (replaced != null) {
|
||||
array.add(replaced);
|
||||
}
|
||||
}
|
||||
|
||||
if (myEditor != null) {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
PsiElement[] exprsToHighlight = PsiUtilBase.toPsiElementArray(array);
|
||||
HighlightManager highlightManager = HighlightManager.getInstance(myProject);
|
||||
highlightManager.addOccurrenceHighlights(myEditor, exprsToHighlight, highlightAttributes(), true, null);
|
||||
WindowManager
|
||||
.getInstance().getStatusBar(myProject).setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!myDeleteSelf) {
|
||||
mySelectedExpr = RefactoringUtil.outermostParenthesizedExpression(mySelectedExpr);
|
||||
RefactoringUtil.replaceOccurenceWithFieldRef(mySelectedExpr, myField, destClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (anchorElementHere != null && IntroduceVariableBase.isLoopOrIf(anchorElementHere.getParent())) {
|
||||
IntroduceVariableBase.putStatementInLoopBody(assignStatement, anchorElementHere.getParent(), anchorElementHere);
|
||||
}
|
||||
|
||||
|
||||
if (localVariable != null) {
|
||||
if (deleteLocalVariable) {
|
||||
localVariable.normalizeDeclaration();
|
||||
localVariable.getParent().delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (initializer != null) {
|
||||
ChangeContextUtil.clearContextInfo(initializer);
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private PsiField checkForwardRefs(PsiExpression initializer) {
|
||||
final PsiField[] refConstantFields = new PsiField[1];
|
||||
initializer.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiElement resolve = expression.resolve();
|
||||
if (resolve instanceof PsiField &&
|
||||
((PsiField)resolve).hasModifierProperty(PsiModifier.FINAL) &&
|
||||
PsiTreeUtil.isAncestor(myParentClass, resolve, false) && ((PsiField)resolve).hasInitializer()) {
|
||||
if (refConstantFields[0] == null || refConstantFields[0].getTextOffset() < resolve.getTextOffset()) {
|
||||
refConstantFields[0] = (PsiField)resolve;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return refConstantFields[0];
|
||||
}
|
||||
|
||||
public PsiField getField() {
|
||||
return myField;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-210
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.codeInsight.TestUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
public class InitializerPlaceChooser {
|
||||
private static final Logger LOG = Logger.getInstance("#" + InitializerPlaceChooser.class.getName());
|
||||
static BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace;
|
||||
|
||||
PsiClass myParentClass;
|
||||
|
||||
PsiExpression myInitializerExpression;
|
||||
|
||||
boolean myAllowInitInMethod;
|
||||
boolean myAllowInitInMethodIfAll;
|
||||
|
||||
JRadioButton myRbInConstructor;
|
||||
JRadioButton myRbInCurrentMethod;
|
||||
JRadioButton myRbInFieldDeclaration;
|
||||
JRadioButton myRbInSetUp;
|
||||
|
||||
public InitializerPlaceChooser(PsiClass parentClass,
|
||||
PsiExpression initializerExpression,
|
||||
boolean allowInitInMethod, boolean allowInitInMethodIfAll) {
|
||||
myParentClass = parentClass;
|
||||
myInitializerExpression = initializerExpression;
|
||||
myAllowInitInMethod = allowInitInMethod;
|
||||
myAllowInitInMethodIfAll = allowInitInMethodIfAll;
|
||||
}
|
||||
|
||||
void updateInitializerPlace(boolean replaceAll) {
|
||||
if (myAllowInitInMethod) {
|
||||
myRbInCurrentMethod.setEnabled(myAllowInitInMethodIfAll || !replaceAll);
|
||||
if (!myRbInCurrentMethod.isEnabled() && myRbInCurrentMethod.isSelected()) {
|
||||
myRbInCurrentMethod.setSelected(false);
|
||||
myRbInFieldDeclaration.setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initializeControls(PsiExpression initializerExpression) {
|
||||
if (initializerExpression != null) {
|
||||
if (!setEnabledInitializationPlaces(initializerExpression, initializerExpression)) {
|
||||
myRbInFieldDeclaration.setEnabled(false);
|
||||
myRbInConstructor.setEnabled(false);
|
||||
if (myRbInSetUp != null) myRbInSetUp.setEnabled(false);
|
||||
}
|
||||
if (!myAllowInitInMethod) {
|
||||
myRbInCurrentMethod.setEnabled(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myRbInConstructor.setEnabled(false);
|
||||
myRbInCurrentMethod.setEnabled(false);
|
||||
myRbInFieldDeclaration.setEnabled(false);
|
||||
if (myRbInSetUp != null) myRbInSetUp.setEnabled(false);
|
||||
}
|
||||
|
||||
final PsiMethod setUpMethod = TestUtil.findSetUpMethod(myParentClass);
|
||||
if (myInitializerExpression != null && PsiTreeUtil.isAncestor(setUpMethod, myInitializerExpression, false) && myRbInSetUp.isEnabled() ||
|
||||
ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD &&
|
||||
TestUtil.isTestClass(myParentClass) &&
|
||||
myRbInSetUp.isEnabled()) {
|
||||
myRbInSetUp.setSelected(true);
|
||||
}
|
||||
else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) {
|
||||
if (myRbInConstructor.isEnabled()) {
|
||||
myRbInConstructor.setSelected(true);
|
||||
}
|
||||
else {
|
||||
selectInCurrentMethod();
|
||||
}
|
||||
}
|
||||
else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) {
|
||||
if (myRbInFieldDeclaration.isEnabled()) {
|
||||
myRbInFieldDeclaration.setSelected(true);
|
||||
}
|
||||
else {
|
||||
selectInCurrentMethod();
|
||||
}
|
||||
}
|
||||
else {
|
||||
selectInCurrentMethod();
|
||||
}
|
||||
}
|
||||
|
||||
void selectInCurrentMethod() {
|
||||
if (myRbInCurrentMethod.isEnabled()) {
|
||||
myRbInCurrentMethod.setSelected(true);
|
||||
}
|
||||
else if (myRbInFieldDeclaration.isEnabled()) {
|
||||
myRbInFieldDeclaration.setSelected(true);
|
||||
}
|
||||
else {
|
||||
myRbInCurrentMethod.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
public BaseExpressionToFieldHandler.InitializationPlace getInitializerPlace() {
|
||||
if (myRbInConstructor.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR;
|
||||
}
|
||||
if (myRbInCurrentMethod.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD;
|
||||
}
|
||||
if (myRbInFieldDeclaration.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION;
|
||||
}
|
||||
if (myRbInSetUp != null && myRbInSetUp.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD;
|
||||
}
|
||||
|
||||
LOG.assertTrue(false);
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION;
|
||||
}
|
||||
|
||||
JComponent createInitializerPlacePanel() {
|
||||
|
||||
final JPanel initializationPanel = new JPanel();
|
||||
initializationPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("initialize.in.border.title")));
|
||||
initializationPanel.setLayout(new BoxLayout(initializationPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
myRbInCurrentMethod = new JRadioButton();
|
||||
myRbInCurrentMethod.setFocusable(false);
|
||||
myRbInCurrentMethod.setText(RefactoringBundle.message("current.method.radio"));
|
||||
myRbInCurrentMethod.setEnabled(myAllowInitInMethod);
|
||||
myRbInFieldDeclaration = new JRadioButton();
|
||||
myRbInFieldDeclaration.setFocusable(false);
|
||||
myRbInFieldDeclaration.setText(RefactoringBundle.message("field.declaration.radio"));
|
||||
myRbInConstructor = new JRadioButton();
|
||||
myRbInConstructor.setFocusable(false);
|
||||
myRbInConstructor.setText(RefactoringBundle.message("class.constructors.radio"));
|
||||
|
||||
initializationPanel.add(myRbInCurrentMethod);
|
||||
initializationPanel.add(myRbInFieldDeclaration);
|
||||
initializationPanel.add(myRbInConstructor);
|
||||
|
||||
if (TestUtil.isTestClass(myParentClass)) {
|
||||
myRbInSetUp = new JRadioButton();
|
||||
myRbInSetUp.setFocusable(false);
|
||||
myRbInSetUp.setText(RefactoringBundle.message("setup.method.radio"));
|
||||
initializationPanel.add(myRbInSetUp);
|
||||
}
|
||||
|
||||
ButtonGroup bg = new ButtonGroup();
|
||||
bg.add(myRbInCurrentMethod);
|
||||
bg.add(myRbInFieldDeclaration);
|
||||
bg.add(myRbInConstructor);
|
||||
if (myRbInSetUp != null) bg.add(myRbInSetUp);
|
||||
|
||||
return initializationPanel;
|
||||
}
|
||||
|
||||
static boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) {
|
||||
if (initializerPart instanceof PsiReferenceExpression) {
|
||||
PsiReferenceExpression refExpr = (PsiReferenceExpression)initializerPart;
|
||||
if (refExpr.getQualifierExpression() == null) {
|
||||
PsiElement refElement = refExpr.resolve();
|
||||
if (refElement == null ||
|
||||
(refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) &&
|
||||
!PsiTreeUtil.isAncestor(initializer, refElement, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiElement[] children = initializerPart.getChildren();
|
||||
for (PsiElement child : children) {
|
||||
if (!setEnabledInitializationPlaces(child, initializer)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean allowFinal(boolean willBeDeclaredStatic, boolean isCurrentMethodConstructor) {
|
||||
boolean allowFinal = myRbInFieldDeclaration.isSelected() || (myRbInConstructor.isSelected() && !willBeDeclaredStatic);
|
||||
if (myRbInCurrentMethod.isSelected() && isCurrentMethodConstructor) {
|
||||
final PsiMethod[] constructors = myParentClass.getConstructors();
|
||||
allowFinal = constructors.length <= 1;
|
||||
}
|
||||
return allowFinal;
|
||||
}
|
||||
|
||||
void addItemListener(ItemListener listener) {
|
||||
myRbInConstructor.addItemListener(listener);
|
||||
myRbInCurrentMethod.addItemListener(listener);
|
||||
myRbInFieldDeclaration.addItemListener(listener);
|
||||
if (myRbInSetUp != null) myRbInSetUp.addItemListener(listener);
|
||||
}
|
||||
}
|
||||
+381
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractInplaceIntroducer;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.occurences.OccurenceManager;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/15/11
|
||||
*/
|
||||
public class InplaceIntroduceFieldPopup {
|
||||
|
||||
private PsiLocalVariable myLocalVariable;
|
||||
private PsiClass myParentClass;
|
||||
private boolean myStatic;
|
||||
private PsiExpression[] myOccurrences;
|
||||
private PsiExpression myInitializerExpression;
|
||||
private final Editor myEditor;
|
||||
private Project myProject;
|
||||
|
||||
private final TypeSelectorManagerImpl myTypeSelectorManager;
|
||||
private final PsiElement myAnchorElement;
|
||||
private final PsiElement myAnchorElementIfAll;
|
||||
private final OccurenceManager myOccurenceManager;
|
||||
private List<RangeMarker> myOccurrenceMarkers;
|
||||
|
||||
private final IntroduceFieldCentralPanel myIntroduceFieldPanel;
|
||||
|
||||
private JPanel myWholePanel;
|
||||
private String myExprText;
|
||||
private RangeMarker myExprMarker;
|
||||
private String myFieldName;
|
||||
|
||||
private boolean myInitListeners = false;
|
||||
|
||||
public InplaceIntroduceFieldPopup(PsiLocalVariable localVariable,
|
||||
PsiClass parentClass,
|
||||
boolean aStatic,
|
||||
boolean currentMethodConstructor, PsiExpression[] occurrences,
|
||||
PsiExpression initializerExpression,
|
||||
TypeSelectorManagerImpl typeSelectorManager,
|
||||
Editor editor,
|
||||
final boolean allowInitInMethod,
|
||||
boolean allowInitInMethodIfAll, final PsiElement anchorElement,
|
||||
final PsiElement anchorElementIfAll,
|
||||
final OccurenceManager occurenceManager) {
|
||||
myLocalVariable = localVariable;
|
||||
myParentClass = parentClass;
|
||||
myStatic = aStatic;
|
||||
myOccurrences = occurrences;
|
||||
myInitializerExpression = initializerExpression;
|
||||
myExprText = myInitializerExpression != null ? myInitializerExpression.getText() : null;
|
||||
myExprMarker = myInitializerExpression != null ? editor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null;
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
myAnchorElement = anchorElement;
|
||||
myAnchorElementIfAll = anchorElementIfAll;
|
||||
myOccurenceManager = occurenceManager;
|
||||
myProject = myLocalVariable != null ? myLocalVariable.getProject() : myInitializerExpression.getProject();
|
||||
myEditor = editor;
|
||||
|
||||
myIntroduceFieldPanel =
|
||||
new IntroduceFieldCentralPanel(parentClass, initializerExpression, localVariable, currentMethodConstructor, localVariable != null, aStatic,
|
||||
myOccurrences.length, allowInitInMethod, allowInitInMethodIfAll, typeSelectorManager);
|
||||
|
||||
myWholePanel = new JPanel(new GridBagLayout());
|
||||
myWholePanel.setBorder(null);
|
||||
|
||||
final TitlePanel titlePanel = new TitlePanel();
|
||||
titlePanel.setBorder(null);
|
||||
titlePanel.setText(IntroduceFieldHandler.REFACTORING_NAME);
|
||||
|
||||
GridBagConstraints gc =
|
||||
new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
|
||||
new Insets(0,0,0,0), 0, 0);
|
||||
|
||||
myWholePanel.add(titlePanel, gc);
|
||||
|
||||
gc.gridy++;
|
||||
gc.insets.top = 5;
|
||||
|
||||
myWholePanel.add(myIntroduceFieldPanel.createCenterPanel(), gc);
|
||||
myIntroduceFieldPanel.initializeControls(initializerExpression);
|
||||
myIntroduceFieldPanel.addOccurrenceListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
templateState.gotoEnd(true);
|
||||
startTemplate(myIntroduceFieldPanel.isReplaceAllOccurrences());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public List<RangeMarker> getOccurrenceMarkers() {
|
||||
if (myOccurrenceMarkers == null) {
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
}
|
||||
return myOccurrenceMarkers;
|
||||
}
|
||||
|
||||
public void startTemplate() {
|
||||
startTemplate(false);
|
||||
}
|
||||
|
||||
public void startTemplate(final boolean replaceAllOccurrences) {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
|
||||
final SuggestedNameInfo suggestedNameInfo =
|
||||
IntroduceFieldDialog.createGenerator(myStatic, myLocalVariable, myInitializerExpression, myLocalVariable != null)
|
||||
.getSuggestedNameInfo(defaultType);
|
||||
|
||||
final PsiField field = createFieldToStartTemplateOn(suggestedNameInfo.names, defaultType, null);
|
||||
if (field != null) {
|
||||
myEditor.getCaretModel().moveToOffset(field.getTextOffset());
|
||||
final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<String>();
|
||||
nameSuggestions.add(field.getName());
|
||||
nameSuggestions.addAll(Arrays.asList(suggestedNameInfo.names));
|
||||
final VariableInplaceRenamer renamer = new FieldInplaceIntroducer(field);
|
||||
renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
}
|
||||
}, IntroduceFieldHandler.REFACTORING_NAME, null);
|
||||
}
|
||||
|
||||
private PsiField createFieldToStartTemplateOn(final String[] names,
|
||||
final PsiType defaultType,
|
||||
final PsiElement anchor) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiField>() {
|
||||
@Override
|
||||
public PsiField compute() {
|
||||
PsiField field = elementFactory.createField(myFieldName != null ? myFieldName : names[0], defaultType);
|
||||
field = anchor != null ? (PsiField)myParentClass.addBefore(field, anchor) : (PsiField)myParentClass.add(field);
|
||||
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, myIntroduceFieldPanel.isDeclareFinal());
|
||||
return field;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class FieldInplaceIntroducer extends AbstractInplaceIntroducer {
|
||||
|
||||
private RangeMarker myFieldRangeStart;
|
||||
|
||||
|
||||
private SmartTypePointer myDefaultParameterTypePointer;
|
||||
|
||||
private SmartTypePointer myFieldTypePointer;
|
||||
|
||||
public FieldInplaceIntroducer(PsiVariable psiVariable) {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
myEditor, psiVariable, false,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1,
|
||||
myInitializerExpression != null ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers());
|
||||
myDefaultParameterTypePointer =
|
||||
SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType());
|
||||
myFieldRangeStart = myEditor.getDocument().createRangeMarker(psiVariable.getTextRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReplaceAllOccurrences() {
|
||||
return myIntroduceFieldPanel.isReplaceAllOccurrences();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression getExpr() {
|
||||
return myInitializerExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression[] getOccurrences() {
|
||||
return myOccurrences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<RangeMarker> getOccurrenceMarkers() {
|
||||
return InplaceIntroduceFieldPopup.this.getOccurrenceMarkers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RangeMarker getExprMarker() {
|
||||
return myExprMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), myDefaultParameterTypePointer.getType());
|
||||
JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY = myIntroduceFieldPanel.getFieldVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiElement checkLocalScope() {
|
||||
return myParentClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
if (!myInitListeners) {
|
||||
myInitListeners = true;
|
||||
myIntroduceFieldPanel.addVisibilityListener(new VisibilityListener());
|
||||
final FinalListener finalListener = new FinalListener(myProject);
|
||||
myIntroduceFieldPanel.addFinalListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
finalListener.perform(myIntroduceFieldPanel.isDeclareFinal());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return myWholePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
PsiElement element = myParentClass.getContainingFile().findElementAt(myFieldRangeStart.getStartOffset());
|
||||
if (element instanceof PsiWhiteSpace) {
|
||||
element = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
return PsiTreeUtil.getParentOfType(element, PsiField.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (success) {
|
||||
final BaseExpressionToFieldHandler.Settings settings =
|
||||
new BaseExpressionToFieldHandler.Settings(myFieldName, myIntroduceFieldPanel.isReplaceAllOccurrences(), myStatic,
|
||||
myIntroduceFieldPanel.isDeclareFinal(),
|
||||
myIntroduceFieldPanel.getInitializerPlace(),
|
||||
myIntroduceFieldPanel.getFieldVisibility(), myLocalVariable,
|
||||
myFieldTypePointer.getType(),
|
||||
myIntroduceFieldPanel.isDeleteVariable(),
|
||||
myParentClass, false, false);
|
||||
if (myLocalVariable != null) {
|
||||
final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable =
|
||||
new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, myStatic, myOccurrences);
|
||||
fieldRunnable.run();
|
||||
}
|
||||
else {
|
||||
final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable =
|
||||
new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myInitializerExpression, settings, settings.getForcedType(),
|
||||
myOccurrences, myOccurenceManager,
|
||||
myAnchorElementIfAll, myAnchorElement, myEditor,
|
||||
myParentClass);
|
||||
convertToFieldRunnable.run();
|
||||
}
|
||||
}
|
||||
super.moveOffsetAfter(success);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
final PsiField psiField = (PsiField)getVariable();
|
||||
LOG.assertTrue(psiField != null);
|
||||
myFieldTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(psiField.getType());
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
myFieldName = psiField.getName();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final PsiFile containingFile = myParentClass.getContainingFile();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
myInitializerExpression = restoreExpression(containingFile, psiField, elementFactory, getExprMarker(), myExprText);
|
||||
if (myInitializerExpression != null) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange());
|
||||
}
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) {
|
||||
RangeMarker marker = occurrenceMarkers.get(i);
|
||||
if (getExprMarker() != null && marker.getStartOffset() == getExprMarker().getStartOffset()) {
|
||||
myOccurrences[i] = myInitializerExpression;
|
||||
continue;
|
||||
}
|
||||
final PsiExpression psiExpression = restoreExpression(containingFile, psiField, elementFactory, marker, myExprText);
|
||||
if (psiExpression != null) {
|
||||
myOccurrences[i] = psiExpression;
|
||||
}
|
||||
}
|
||||
myOccurrenceMarkers = null;
|
||||
if (psiField.isValid()) {
|
||||
psiField.delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class VisibilityListener implements ChangeListener {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
new WriteCommandAction(myProject) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final PsiVariable variable = getVariable();
|
||||
LOG.assertTrue(variable != null);
|
||||
final PsiModifierList modifierList = variable.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
int textOffset = modifierList.getTextOffset();
|
||||
|
||||
final Document document = myEditor.getDocument();
|
||||
String visibility = myIntroduceFieldPanel.getFieldVisibility();
|
||||
if (visibility == PsiModifier.PACKAGE_LOCAL) {
|
||||
visibility = "";
|
||||
}
|
||||
final String modifierListText = modifierList.getText();
|
||||
|
||||
int length = PsiModifier.PUBLIC.length();
|
||||
int idx = modifierListText.indexOf(PsiModifier.PUBLIC);
|
||||
|
||||
if (idx == -1) {
|
||||
idx = modifierListText.indexOf(PsiModifier.PROTECTED);
|
||||
length = PsiModifier.PROTECTED.length();
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
idx = modifierListText.indexOf(PsiModifier.PRIVATE);
|
||||
length = PsiModifier.PRIVATE.length();
|
||||
}
|
||||
|
||||
final int startOffset = textOffset + Math.max(idx, 0);
|
||||
final int endOffset = textOffset + (idx > -1 ? length : 0);
|
||||
|
||||
document.replaceString(startOffset, endOffset, visibility + (startOffset == endOffset ? " " : ""));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+394
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.codeInsight.TestUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.ui.JavaVisibilityPanel;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManager;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.ui.StateRestoringCheckBox;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/16/11
|
||||
*/
|
||||
public class IntroduceFieldCentralPanel {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceFieldDialog");
|
||||
|
||||
private static boolean ourLastCbFinalState = false;
|
||||
private static BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace;
|
||||
|
||||
private final PsiClass myParentClass;
|
||||
private final PsiExpression myInitializerExpression;
|
||||
private final PsiLocalVariable myLocalVariable;
|
||||
private final boolean myIsCurrentMethodConstructor;
|
||||
private final boolean myIsInvokedOnDeclaration;
|
||||
private final boolean myWillBeDeclaredStatic;
|
||||
private final int myOccurrencesCount;
|
||||
private final boolean myAllowInitInMethod;
|
||||
private final boolean myAllowInitInMethodIfAll;
|
||||
private final TypeSelectorManager myTypeSelectorManager;
|
||||
|
||||
|
||||
private JCheckBox myCbReplaceAll;
|
||||
private StateRestoringCheckBox myCbDeleteVariable;
|
||||
private StateRestoringCheckBox myCbFinal;
|
||||
|
||||
private JRadioButton myRbInConstructor;
|
||||
private JRadioButton myRbInCurrentMethod;
|
||||
private JRadioButton myRbInFieldDeclaration;
|
||||
private JRadioButton myRbInSetUp;
|
||||
|
||||
private JavaVisibilityPanel myVisibilityPanel;
|
||||
|
||||
public IntroduceFieldCentralPanel(PsiClass parentClass,
|
||||
PsiExpression initializerExpression,
|
||||
PsiLocalVariable localVariable,
|
||||
boolean isCurrentMethodConstructor, boolean isInvokedOnDeclaration, boolean willBeDeclaredStatic,
|
||||
int occurrencesCount, boolean allowInitInMethod, boolean allowInitInMethodIfAll,
|
||||
TypeSelectorManager typeSelectorManager) {
|
||||
myParentClass = parentClass;
|
||||
myInitializerExpression = initializerExpression;
|
||||
myLocalVariable = localVariable;
|
||||
myIsCurrentMethodConstructor = isCurrentMethodConstructor;
|
||||
myIsInvokedOnDeclaration = isInvokedOnDeclaration;
|
||||
myWillBeDeclaredStatic = willBeDeclaredStatic;
|
||||
myOccurrencesCount = occurrencesCount;
|
||||
myAllowInitInMethod = allowInitInMethod;
|
||||
myAllowInitInMethodIfAll = allowInitInMethodIfAll;
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
}
|
||||
|
||||
void initializeControls(PsiExpression initializerExpression) {
|
||||
if (initializerExpression != null) {
|
||||
setEnabledInitializationPlaces(initializerExpression, initializerExpression);
|
||||
if (!myAllowInitInMethod) {
|
||||
myRbInCurrentMethod.setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
myRbInConstructor.setEnabled(false);
|
||||
myRbInCurrentMethod.setEnabled(false);
|
||||
myRbInFieldDeclaration.setEnabled(false);
|
||||
if (myRbInSetUp != null) myRbInSetUp.setEnabled(false);
|
||||
}
|
||||
|
||||
final PsiMethod setUpMethod = TestUtil.findSetUpMethod(myParentClass);
|
||||
if (myInitializerExpression != null && PsiTreeUtil.isAncestor(setUpMethod, myInitializerExpression, false) && myRbInSetUp.isEnabled() ||
|
||||
ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD && TestUtil.isTestClass(myParentClass) && myRbInSetUp.isEnabled()) {
|
||||
myRbInSetUp.setSelected(true);
|
||||
}
|
||||
else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR) {
|
||||
if (myRbInConstructor.isEnabled()) {
|
||||
myRbInConstructor.setSelected(true);
|
||||
} else {
|
||||
selectInCurrentMethod();
|
||||
}
|
||||
} else if (ourLastInitializerPlace == BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION) {
|
||||
if (myRbInFieldDeclaration.isEnabled()) {
|
||||
myRbInFieldDeclaration.setSelected(true);
|
||||
} else {
|
||||
selectInCurrentMethod();
|
||||
}
|
||||
} else {
|
||||
selectInCurrentMethod();
|
||||
}
|
||||
String ourLastVisibility = JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY;
|
||||
myVisibilityPanel.setVisibility(ourLastVisibility);
|
||||
myCbFinal.setSelected(myCbFinal.isEnabled() && ourLastCbFinalState);
|
||||
}
|
||||
|
||||
private void selectInCurrentMethod() {
|
||||
if (myRbInCurrentMethod.isEnabled()) {
|
||||
myRbInCurrentMethod.setSelected(true);
|
||||
}
|
||||
else if (myRbInFieldDeclaration.isEnabled()) {
|
||||
myRbInFieldDeclaration.setSelected(true);
|
||||
}
|
||||
else {
|
||||
myRbInCurrentMethod.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public BaseExpressionToFieldHandler.InitializationPlace getInitializerPlace() {
|
||||
if (myRbInConstructor.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_CONSTRUCTOR;
|
||||
}
|
||||
if (myRbInCurrentMethod.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD;
|
||||
}
|
||||
if (myRbInFieldDeclaration.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION;
|
||||
}
|
||||
if (myRbInSetUp != null && myRbInSetUp.isSelected()) {
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_SETUP_METHOD;
|
||||
}
|
||||
|
||||
LOG.assertTrue(false);
|
||||
return BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION;
|
||||
}
|
||||
|
||||
|
||||
public String getFieldVisibility() {
|
||||
return myVisibilityPanel.getVisibility();
|
||||
}
|
||||
|
||||
public boolean isReplaceAllOccurrences() {
|
||||
if (myIsInvokedOnDeclaration) return true;
|
||||
if (myOccurrencesCount <= 1) return false;
|
||||
return myCbReplaceAll.isSelected();
|
||||
}
|
||||
|
||||
public boolean isDeleteVariable() {
|
||||
if (myIsInvokedOnDeclaration) return true;
|
||||
if (myCbDeleteVariable == null) return false;
|
||||
return myCbDeleteVariable.isSelected();
|
||||
}
|
||||
|
||||
public boolean isDeclareFinal() {
|
||||
return myCbFinal.isSelected();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints();
|
||||
gbConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbConstraints.weightx = 1;
|
||||
gbConstraints.weighty = 0;
|
||||
gbConstraints.gridwidth = 1;
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
final Insets standardInsets = new Insets(0, 0, 0, 0);
|
||||
gbConstraints.insets = standardInsets;
|
||||
|
||||
panel.add(createInitializerPlacePanel(), gbConstraints);
|
||||
ItemListener itemListener = new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (myCbReplaceAll != null && myAllowInitInMethod) {
|
||||
myRbInCurrentMethod.setEnabled(myAllowInitInMethodIfAll || !myCbReplaceAll.isSelected());
|
||||
if (!myRbInCurrentMethod.isEnabled() && myRbInCurrentMethod.isSelected()) {
|
||||
myRbInCurrentMethod.setSelected(false);
|
||||
myRbInFieldDeclaration.setSelected(true);
|
||||
}
|
||||
}
|
||||
updateTypeSelector();
|
||||
}
|
||||
};
|
||||
ItemListener finalUpdater = new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
updateCbFinal();
|
||||
}
|
||||
};
|
||||
myRbInConstructor.addItemListener(itemListener);
|
||||
myRbInCurrentMethod.addItemListener(itemListener);
|
||||
myRbInFieldDeclaration.addItemListener(itemListener);
|
||||
myRbInConstructor.addItemListener(finalUpdater);
|
||||
myRbInCurrentMethod.addItemListener(finalUpdater);
|
||||
myRbInFieldDeclaration.addItemListener(finalUpdater);
|
||||
if (myRbInSetUp != null) myRbInSetUp.addItemListener(finalUpdater);
|
||||
if (myOccurrencesCount > 1) {
|
||||
myCbReplaceAll = new NonFocusableCheckBox();
|
||||
myCbReplaceAll.setText(RefactoringBundle.message("replace.all.occurrences.of.expression.0.occurrences", myOccurrencesCount));
|
||||
gbConstraints.gridy++;
|
||||
panel.add(myCbReplaceAll, gbConstraints);
|
||||
myCbReplaceAll.addItemListener(itemListener);
|
||||
if (myIsInvokedOnDeclaration) {
|
||||
myCbReplaceAll.setEnabled(false);
|
||||
myCbReplaceAll.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (myLocalVariable != null) {
|
||||
gbConstraints.gridy++;
|
||||
if (myCbReplaceAll != null) {
|
||||
gbConstraints.insets = new Insets(0, 8, 0, 0);
|
||||
}
|
||||
myCbDeleteVariable = new StateRestoringCheckBox();
|
||||
myCbDeleteVariable.setText(RefactoringBundle.message("delete.variable.declaration"));
|
||||
panel.add(myCbDeleteVariable, gbConstraints);
|
||||
if (myIsInvokedOnDeclaration) {
|
||||
myCbDeleteVariable.setEnabled(false);
|
||||
myCbDeleteVariable.setSelected(true);
|
||||
} else if (myCbReplaceAll != null) {
|
||||
updateCbDeleteVariable();
|
||||
myCbReplaceAll.addItemListener(
|
||||
new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
updateCbDeleteVariable();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
gbConstraints.insets = standardInsets;
|
||||
}
|
||||
myCbFinal.addItemListener(itemListener);
|
||||
// myCbStatic.addItemListener(itemListener);
|
||||
// myCbStatic.addItemListener(finalUpdater);
|
||||
// myCbStatic.addItemListener(
|
||||
// new ItemListener() {
|
||||
// public void itemStateChanged(ItemEvent e) {
|
||||
// updateNameList();
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
updateTypeSelector();
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void updateTypeSelector() {
|
||||
if (myCbReplaceAll != null) {
|
||||
myTypeSelectorManager.setAllOccurences(myCbReplaceAll.isSelected());
|
||||
} else {
|
||||
myTypeSelectorManager.setAllOccurences(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCbDeleteVariable() {
|
||||
if (!myCbReplaceAll.isSelected()) {
|
||||
myCbDeleteVariable.makeUnselectable(false);
|
||||
} else {
|
||||
myCbDeleteVariable.makeSelectable();
|
||||
}
|
||||
}
|
||||
|
||||
private JComponent createInitializerPlacePanel() {
|
||||
JPanel mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
|
||||
JPanel initializationPanel = new JPanel();
|
||||
initializationPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("initialize.in.border.title")));
|
||||
initializationPanel.setLayout(new BoxLayout(initializationPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
|
||||
myRbInCurrentMethod = new JRadioButton();
|
||||
myRbInCurrentMethod.setFocusable(false);
|
||||
myRbInCurrentMethod.setText(RefactoringBundle.message("current.method.radio"));
|
||||
myRbInCurrentMethod.setEnabled(myAllowInitInMethod);
|
||||
|
||||
myRbInFieldDeclaration = new JRadioButton();
|
||||
myRbInFieldDeclaration.setFocusable(false);
|
||||
myRbInFieldDeclaration.setText(RefactoringBundle.message("field.declaration.radio"));
|
||||
|
||||
myRbInConstructor = new JRadioButton();
|
||||
myRbInConstructor.setFocusable(false);
|
||||
myRbInConstructor.setText(RefactoringBundle.message("class.constructors.radio"));
|
||||
|
||||
myVisibilityPanel = new JavaVisibilityPanel(false, false);
|
||||
|
||||
myCbFinal = new StateRestoringCheckBox();
|
||||
myCbFinal.setFocusable(false);
|
||||
myCbFinal.setText(RefactoringBundle.message("declare.final"));
|
||||
|
||||
initializationPanel.add(myRbInCurrentMethod);
|
||||
initializationPanel.add(myRbInFieldDeclaration);
|
||||
initializationPanel.add(myRbInConstructor);
|
||||
|
||||
if (TestUtil.isTestClass(myParentClass)) {
|
||||
myRbInSetUp = new JRadioButton();
|
||||
myRbInSetUp.setFocusable(false);
|
||||
myRbInSetUp.setText(RefactoringBundle.message("setup.method.radio"));
|
||||
initializationPanel.add(myRbInSetUp);
|
||||
}
|
||||
|
||||
ButtonGroup bg = new ButtonGroup();
|
||||
bg.add(myRbInCurrentMethod);
|
||||
bg.add(myRbInFieldDeclaration);
|
||||
bg.add(myRbInConstructor);
|
||||
if (myRbInSetUp != null) bg.add(myRbInSetUp);
|
||||
|
||||
|
||||
|
||||
// modifiersPanel.add(myCbFinal);
|
||||
// modifiersPanel.add(myCbStatic);
|
||||
|
||||
JPanel groupPanel = new JPanel(new GridLayout(1, 2));
|
||||
groupPanel.add(initializationPanel);
|
||||
groupPanel.add(myVisibilityPanel);
|
||||
mainPanel.add(groupPanel, BorderLayout.CENTER);
|
||||
mainPanel.add(myCbFinal, BorderLayout.SOUTH);
|
||||
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
private void updateCbFinal() {
|
||||
boolean allowFinal = myRbInFieldDeclaration.isSelected() || (myRbInConstructor.isSelected() && !myWillBeDeclaredStatic);
|
||||
if (myRbInCurrentMethod.isSelected() && myIsCurrentMethodConstructor) {
|
||||
final PsiMethod[] constructors = myParentClass.getConstructors();
|
||||
allowFinal = constructors.length <= 1;
|
||||
}
|
||||
if (!allowFinal) {
|
||||
myCbFinal.makeUnselectable(false);
|
||||
} else {
|
||||
myCbFinal.makeSelectable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private boolean setEnabledInitializationPlaces(PsiElement initializerPart, PsiElement initializer) {
|
||||
if (initializerPart instanceof PsiReferenceExpression) {
|
||||
PsiReferenceExpression refExpr = (PsiReferenceExpression) initializerPart;
|
||||
if (refExpr.getQualifierExpression() == null) {
|
||||
PsiElement refElement = refExpr.resolve();
|
||||
if (refElement == null ||
|
||||
(refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter) &&
|
||||
!PsiTreeUtil.isAncestor(initializer, refElement, true)) {
|
||||
myRbInFieldDeclaration.setEnabled(false);
|
||||
myRbInConstructor.setEnabled(false);
|
||||
if (myRbInSetUp != null) myRbInSetUp.setEnabled(false);
|
||||
myCbFinal.setEnabled(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiElement[] children = initializerPart.getChildren();
|
||||
for (PsiElement child : children) {
|
||||
if (!setEnabledInitializationPlaces(child, initializer)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addOccurrenceListener(ItemListener itemListener) {
|
||||
if (myCbReplaceAll != null) {
|
||||
myCbReplaceAll.addItemListener(itemListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void addVisibilityListener(ChangeListener changeListener) {
|
||||
myVisibilityPanel.addListener(changeListener);
|
||||
}
|
||||
|
||||
public void addFinalListener(ItemListener itemListener) {
|
||||
myCbFinal.addItemListener(itemListener);
|
||||
}
|
||||
}
|
||||
+30
-77
@@ -33,30 +33,28 @@ import com.intellij.refactoring.util.RefactoringMessageUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
class IntroduceFieldDialog extends DialogWrapper {
|
||||
|
||||
|
||||
static BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace;
|
||||
static boolean ourLastCbFinalState = false;
|
||||
|
||||
private final Project myProject;
|
||||
private final PsiClass myParentClass;
|
||||
private final PsiExpression myInitializerExpression;
|
||||
private final PsiLocalVariable myLocalVariable;
|
||||
private final boolean myIsCurrentMethodConstructor;
|
||||
private final boolean myIsInvokedOnDeclaration;
|
||||
private final boolean myWillBeDeclaredStatic;
|
||||
private final TypeSelectorManager myTypeSelectorManager;
|
||||
|
||||
private NameSuggestionsField myNameField;
|
||||
|
||||
private IntroduceFieldCentralPanel myCentralPanel;
|
||||
|
||||
private TypeSelector myTypeSelector;
|
||||
private NameSuggestionsManager myNameSuggestionsManager;
|
||||
private static final String REFACTORING_NAME = RefactoringBundle.message("introduce.field.title");
|
||||
private final InitializerPlaceChooser myInitializerPlaceChooser;
|
||||
private JavaVisibilityPanel myVisibilityPanel;
|
||||
private IntroduceFieldPanel myIntroduceFieldPanel;
|
||||
|
||||
public IntroduceFieldDialog(Project project,
|
||||
PsiClass parentClass,
|
||||
@@ -69,10 +67,11 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
myProject = project;
|
||||
myParentClass = parentClass;
|
||||
myInitializerExpression = initializerExpression;
|
||||
myInitializerPlaceChooser = new InitializerPlaceChooser(parentClass, initializerExpression, allowInitInMethod, allowInitInMethodIfAll);
|
||||
myIntroduceFieldPanel = new IntroduceFieldPanel(isInvokedOnDeclaration, occurrencesCount, localVariable);
|
||||
myCentralPanel =
|
||||
new IntroduceFieldCentralPanel(parentClass, initializerExpression, localVariable, isCurrentMethodConstructor, isInvokedOnDeclaration,
|
||||
willBeDeclaredStatic, occurrencesCount, allowInitInMethod, allowInitInMethodIfAll,
|
||||
typeSelectorManager);
|
||||
myLocalVariable = localVariable;
|
||||
myIsCurrentMethodConstructor = isCurrentMethodConstructor;
|
||||
myIsInvokedOnDeclaration = isInvokedOnDeclaration;
|
||||
myWillBeDeclaredStatic = willBeDeclaredStatic;
|
||||
|
||||
@@ -81,44 +80,36 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
setTitle(REFACTORING_NAME);
|
||||
init();
|
||||
|
||||
initializeControls(initializerExpression);
|
||||
myCentralPanel.initializeControls(initializerExpression);
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
private void initializeControls(PsiExpression initializerExpression) {
|
||||
myInitializerPlaceChooser.initializeControls(initializerExpression);
|
||||
myIntroduceFieldPanel.initializeControls(initializerExpression);
|
||||
|
||||
String ourLastVisibility = JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY;
|
||||
myVisibilityPanel.setVisibility(ourLastVisibility);
|
||||
}
|
||||
|
||||
public String getEnteredName() {
|
||||
return myNameField.getEnteredName();
|
||||
}
|
||||
|
||||
public BaseExpressionToFieldHandler.InitializationPlace getInitializerPlace() {
|
||||
|
||||
return myInitializerPlaceChooser.getInitializerPlace();
|
||||
return myCentralPanel.getInitializerPlace();
|
||||
}
|
||||
|
||||
@Modifier
|
||||
public String getFieldVisibility() {
|
||||
return myVisibilityPanel.getVisibility();
|
||||
return myCentralPanel.getFieldVisibility();
|
||||
}
|
||||
|
||||
public boolean isReplaceAllOccurrences() {
|
||||
return myIntroduceFieldPanel.isReplaceAllOccurrences();
|
||||
return myCentralPanel.isReplaceAllOccurrences();
|
||||
|
||||
}
|
||||
|
||||
public boolean isDeleteVariable() {
|
||||
return myIntroduceFieldPanel.isDeleteVariable();
|
||||
return myCentralPanel.isDeleteVariable();
|
||||
|
||||
}
|
||||
|
||||
public boolean isDeclareFinal() {
|
||||
return myIntroduceFieldPanel.isDeclareFinal();
|
||||
return myCentralPanel.isDeclareFinal();
|
||||
}
|
||||
|
||||
public PsiType getFieldType() {
|
||||
@@ -179,7 +170,8 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
});
|
||||
namePrompt.setLabelFor(myNameField.getFocusableComponent());
|
||||
|
||||
myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField, createGenerator());
|
||||
myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField,
|
||||
createGenerator(myWillBeDeclaredStatic, myLocalVariable, myInitializerExpression, myIsInvokedOnDeclaration));
|
||||
myNameSuggestionsManager.setLabelsFor(type, namePrompt);
|
||||
|
||||
return panel;
|
||||
@@ -196,66 +188,27 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
final JPanel panel = new JPanel(new GridBagLayout());
|
||||
final GridBagConstraints gbConstraints = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0, 0);
|
||||
|
||||
final JPanel mainPanel = new JPanel();
|
||||
mainPanel.setLayout(new BorderLayout());
|
||||
|
||||
JPanel groupPanel = new JPanel(new GridLayout(1, 2));
|
||||
|
||||
final JComponent initializerPlacePanel = myInitializerPlaceChooser.createInitializerPlacePanel();
|
||||
myInitializerPlaceChooser.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
myIntroduceFieldPanel.updateTypeSelector(myTypeSelectorManager);
|
||||
myIntroduceFieldPanel.updateCbFinal(myInitializerPlaceChooser.allowFinal(myWillBeDeclaredStatic, myIsCurrentMethodConstructor));
|
||||
}
|
||||
});
|
||||
groupPanel.add(initializerPlacePanel);
|
||||
|
||||
myVisibilityPanel = new JavaVisibilityPanel(false, false);
|
||||
groupPanel.add(myVisibilityPanel);
|
||||
|
||||
mainPanel.add(groupPanel, BorderLayout.CENTER);
|
||||
|
||||
final ItemListener itemListener = new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (myIntroduceFieldPanel.hasOccurrences()) {
|
||||
myInitializerPlaceChooser.updateInitializerPlace(myIntroduceFieldPanel.isReplaceAllOccurrences());
|
||||
}
|
||||
myIntroduceFieldPanel.updateTypeSelector(myTypeSelectorManager);
|
||||
myNameField.requestFocusInWindow();
|
||||
}
|
||||
};
|
||||
panel.add(mainPanel, gbConstraints);
|
||||
myIntroduceFieldPanel.appendFinalCb(panel, gbConstraints, itemListener);
|
||||
myIntroduceFieldPanel.appendOccurrencesCb(panel, gbConstraints, itemListener);
|
||||
myIntroduceFieldPanel.appendDeleteVariableDeclarationCb(panel, gbConstraints);
|
||||
|
||||
myIntroduceFieldPanel.updateTypeSelector(myTypeSelectorManager);
|
||||
return panel;
|
||||
return myCentralPanel.createCenterPanel();
|
||||
}
|
||||
|
||||
|
||||
private NameSuggestionsGenerator createGenerator() {
|
||||
static NameSuggestionsGenerator createGenerator(final boolean willBeDeclaredStatic,
|
||||
final PsiLocalVariable localVariable,
|
||||
final PsiExpression initializerExpression,
|
||||
final boolean isInvokedOnDeclaration) {
|
||||
return new NameSuggestionsGenerator() {
|
||||
private final JavaCodeStyleManager myCodeStyleManager = JavaCodeStyleManager.getInstance(myProject);
|
||||
private final JavaCodeStyleManager myCodeStyleManager = JavaCodeStyleManager.getInstance(localVariable != null ? localVariable.getProject()
|
||||
: initializerExpression.getProject());
|
||||
public SuggestedNameInfo getSuggestedNameInfo(PsiType type) {
|
||||
VariableKind variableKind = myWillBeDeclaredStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
|
||||
VariableKind variableKind = willBeDeclaredStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
|
||||
|
||||
String propertyName = null;
|
||||
if (myIsInvokedOnDeclaration) {
|
||||
propertyName = myCodeStyleManager.variableNameToPropertyName(myLocalVariable.getName(),
|
||||
VariableKind.LOCAL_VARIABLE
|
||||
);
|
||||
if (isInvokedOnDeclaration) {
|
||||
propertyName = myCodeStyleManager.variableNameToPropertyName(localVariable.getName(), VariableKind.LOCAL_VARIABLE);
|
||||
}
|
||||
final SuggestedNameInfo nameInfo = myCodeStyleManager.suggestVariableName(variableKind, propertyName, myInitializerExpression, type);
|
||||
final SuggestedNameInfo nameInfo = myCodeStyleManager.suggestVariableName(variableKind, propertyName, initializerExpression, type);
|
||||
final String[] strings = JavaCompletionUtil.completeVariableNameForRefactoring(myCodeStyleManager, type, VariableKind.LOCAL_VARIABLE, nameInfo);
|
||||
return new SuggestedNameInfo.Delegate(strings, nameInfo);
|
||||
return new SuggestedNameInfo.Delegate(strings, nameInfo);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -293,8 +246,8 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
IntroduceFieldPanel.ourLastCbFinalState = myIntroduceFieldPanel.isFinal();
|
||||
InitializerPlaceChooser.ourLastInitializerPlace = myInitializerPlaceChooser.getInitializerPlace();
|
||||
ourLastCbFinalState = myCentralPanel.isDeclareFinal();
|
||||
ourLastInitializerPlace = myCentralPanel.getInitializerPlace();
|
||||
JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY = getFieldVisibility();
|
||||
|
||||
myNameSuggestionsManager.nameSelected();
|
||||
|
||||
+12
-1
@@ -16,6 +16,8 @@
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
@@ -96,12 +98,21 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
final boolean currentMethodConstructor = containingMethod != null && containingMethod.isConstructor();
|
||||
final boolean allowInitInMethod = (!currentMethodConstructor || !isInSuperOrThis) && (anchorElement instanceof PsiLocalVariable || anchorElement instanceof PsiStatement);
|
||||
final boolean allowInitInMethodIfAll = (!currentMethodConstructor || !isInSuperOrThis) && anchorElementIfAll instanceof PsiStatement;
|
||||
final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurences);
|
||||
|
||||
if (editor != null && editor.getSettings().isVariableInplaceRenameEnabled() && ApplicationManagerEx.getApplicationEx().isInternal()) {
|
||||
new InplaceIntroduceFieldPopup(localVariable, parentClass, declareStatic, currentMethodConstructor, occurences, expr, typeSelectorManager, editor,
|
||||
allowInitInMethod, allowInitInMethodIfAll, anchorElement, anchorElementIfAll, createOccurenceManager(expr, parentClass))
|
||||
.startTemplate();
|
||||
return null;
|
||||
}
|
||||
|
||||
IntroduceFieldDialog dialog = new IntroduceFieldDialog(
|
||||
project, parentClass, expr, localVariable,
|
||||
currentMethodConstructor,
|
||||
localVariable != null, declareStatic, occurencesNumber,
|
||||
allowInitInMethod, allowInitInMethodIfAll,
|
||||
new TypeSelectorManagerImpl(project, type, containingMethod, expr, occurences)
|
||||
typeSelectorManager
|
||||
);
|
||||
dialog.show();
|
||||
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiLocalVariable;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManager;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.ui.StateRestoringCheckBox;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/15/11
|
||||
*/
|
||||
public class IntroduceFieldPanel {
|
||||
static boolean ourLastCbFinalState = false;
|
||||
|
||||
private JCheckBox myCbReplaceAll;
|
||||
private StateRestoringCheckBox myCbDeleteVariable;
|
||||
private StateRestoringCheckBox myCbFinal;
|
||||
private boolean myIsInvokedOnDeclaration;
|
||||
private int myOccurrencesCount;
|
||||
private PsiLocalVariable myLocalVariable;
|
||||
|
||||
public IntroduceFieldPanel(boolean isInvokedOnDeclaration, int occurrencesCount, PsiLocalVariable localVariable) {
|
||||
myIsInvokedOnDeclaration = isInvokedOnDeclaration;
|
||||
myOccurrencesCount = occurrencesCount;
|
||||
myLocalVariable = localVariable;
|
||||
}
|
||||
|
||||
public void initializeControls(PsiExpression initializerExpression) {
|
||||
if (initializerExpression != null && !InitializerPlaceChooser.setEnabledInitializationPlaces(initializerExpression, initializerExpression)) {
|
||||
myCbFinal.setEnabled(false);
|
||||
}
|
||||
myCbFinal.setSelected(myCbFinal.isEnabled() && ourLastCbFinalState);
|
||||
}
|
||||
|
||||
public boolean isReplaceAllOccurrences() {
|
||||
if (myIsInvokedOnDeclaration) return true;
|
||||
if (myOccurrencesCount <= 1) return false;
|
||||
return myCbReplaceAll.isSelected();
|
||||
}
|
||||
|
||||
public boolean isDeclareFinal() {
|
||||
return myCbFinal.isSelected();
|
||||
}
|
||||
|
||||
public boolean isDeleteVariable() {
|
||||
if (myIsInvokedOnDeclaration) return true;
|
||||
if (myCbDeleteVariable == null) return false;
|
||||
return myCbDeleteVariable.isSelected();
|
||||
}
|
||||
|
||||
void appendFinalCb(JPanel mainPanel, GridBagConstraints gbConstraints, ItemListener itemListener) {
|
||||
myCbFinal = new StateRestoringCheckBox();
|
||||
myCbFinal.setText(RefactoringBundle.message("declare.final"));
|
||||
myCbFinal.addItemListener(itemListener);
|
||||
gbConstraints.gridy++;
|
||||
mainPanel.add(myCbFinal, gbConstraints);
|
||||
}
|
||||
|
||||
void appendOccurrencesCb(JPanel panel, GridBagConstraints gbConstraints, ItemListener itemListener) {
|
||||
if (myOccurrencesCount > 1) {
|
||||
myCbReplaceAll = new NonFocusableCheckBox();
|
||||
myCbReplaceAll.setText(RefactoringBundle.message("replace.all.occurrences.of.expression.0.occurrences", myOccurrencesCount));
|
||||
gbConstraints.gridy++;
|
||||
panel.add(myCbReplaceAll, gbConstraints);
|
||||
myCbReplaceAll.addItemListener(itemListener);
|
||||
if (myIsInvokedOnDeclaration) {
|
||||
myCbReplaceAll.setEnabled(false);
|
||||
myCbReplaceAll.setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void appendDeleteVariableDeclarationCb(JPanel panel, GridBagConstraints gbConstraints) {
|
||||
if (myLocalVariable != null) {
|
||||
gbConstraints.gridy++;
|
||||
if (myCbReplaceAll != null) {
|
||||
gbConstraints.insets = new Insets(0, 8, 0, 0);
|
||||
}
|
||||
myCbDeleteVariable = new StateRestoringCheckBox();
|
||||
myCbDeleteVariable.setText(RefactoringBundle.message("delete.variable.declaration"));
|
||||
panel.add(myCbDeleteVariable, gbConstraints);
|
||||
if (myIsInvokedOnDeclaration) {
|
||||
myCbDeleteVariable.setEnabled(false);
|
||||
myCbDeleteVariable.setSelected(true);
|
||||
} else if (myCbReplaceAll != null) {
|
||||
updateCbDeleteVariable();
|
||||
myCbReplaceAll.addItemListener(
|
||||
new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
updateCbDeleteVariable();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
gbConstraints.insets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCbDeleteVariable() {
|
||||
if (!myCbReplaceAll.isSelected()) {
|
||||
myCbDeleteVariable.makeUnselectable(false);
|
||||
} else {
|
||||
myCbDeleteVariable.makeSelectable();
|
||||
}
|
||||
}
|
||||
|
||||
void updateCbFinal(boolean allowFinal) {
|
||||
if (!allowFinal) {
|
||||
myCbFinal.makeUnselectable(false);
|
||||
} else {
|
||||
myCbFinal.makeSelectable();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return myCbFinal.isSelected();
|
||||
}
|
||||
|
||||
void updateTypeSelector(TypeSelectorManager typeSelectorManager) {
|
||||
if (myCbReplaceAll != null) {
|
||||
typeSelectorManager.setAllOccurences(myCbReplaceAll.isSelected());
|
||||
} else {
|
||||
typeSelectorManager.setAllOccurences(false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasOccurrences() {
|
||||
return myCbReplaceAll != null;
|
||||
}
|
||||
}
|
||||
+128
-89
@@ -45,11 +45,9 @@ public abstract class LocalToFieldHandler {
|
||||
private static final String REFACTORING_NAME = RefactoringBundle.message("convert.local.to.field.title");
|
||||
private final Project myProject;
|
||||
private final boolean myIsConstant;
|
||||
private final PsiManager myManager;
|
||||
|
||||
public LocalToFieldHandler(Project project, boolean isConstant) {
|
||||
myProject = project;
|
||||
myManager = PsiManager.getInstance(myProject);
|
||||
myIsConstant = isConstant;
|
||||
}
|
||||
|
||||
@@ -86,9 +84,6 @@ public abstract class LocalToFieldHandler {
|
||||
final BaseExpressionToFieldHandler.Settings settings = showRefactoringDialog(aClass, local, occurences, isStatic);
|
||||
if (settings == null) return false;
|
||||
//LocalToFieldDialog dialog = new LocalToFieldDialog(project, aClass, local, isStatic);
|
||||
final String variableName = local.getName();
|
||||
final String fieldName = settings.getFieldName();
|
||||
final BaseExpressionToFieldHandler.InitializationPlace initializerPlace = settings.getInitializerPlace();
|
||||
final PsiClass destinationClass = settings.getDestinationClass();
|
||||
boolean rebindNeeded = false;
|
||||
if (destinationClass != null) {
|
||||
@@ -98,76 +93,8 @@ public abstract class LocalToFieldHandler {
|
||||
|
||||
final PsiClass aaClass = aClass;
|
||||
final boolean rebindNeeded1 = rebindNeeded;
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final boolean rebindNeeded2 = !variableName.equals(fieldName) || rebindNeeded1;
|
||||
final PsiReference[] refs;
|
||||
if (rebindNeeded2) {
|
||||
refs = ReferencesSearch.search(local, GlobalSearchScope.projectScope(myProject), false).toArray(new PsiReference[0]);
|
||||
}
|
||||
else {
|
||||
refs = null;
|
||||
}
|
||||
|
||||
final PsiMethod enclosingConstructor = BaseExpressionToFieldHandler.getEnclosingConstructor(aaClass, local);
|
||||
PsiField field = settings.isIntroduceEnumConstant() ? EnumConstantsUtil.createEnumConstant(aaClass, local, fieldName)
|
||||
: createField(local, settings.getForcedType(), fieldName, initializerPlace == IN_FIELD_DECLARATION);
|
||||
field = (PsiField)aaClass.add(field);
|
||||
BaseExpressionToFieldHandler.setModifiers(field, settings, isStatic);
|
||||
if (!settings.isIntroduceEnumConstant()) {
|
||||
VisibilityUtil.fixVisibility(occurences, field, settings.getFieldVisibility());
|
||||
}
|
||||
|
||||
local.normalizeDeclaration();
|
||||
PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)local.getParent();
|
||||
final BaseExpressionToFieldHandler.InitializationPlace finalInitializerPlace;
|
||||
if (local.getInitializer() == null) {
|
||||
finalInitializerPlace = IN_FIELD_DECLARATION;
|
||||
}
|
||||
else {
|
||||
finalInitializerPlace = initializerPlace;
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
|
||||
|
||||
switch (finalInitializerPlace) {
|
||||
case IN_FIELD_DECLARATION:
|
||||
declarationStatement.delete();
|
||||
break;
|
||||
|
||||
case IN_CURRENT_METHOD:
|
||||
PsiStatement statement = createAssignment(local, fieldName, factory);
|
||||
declarationStatement.replace(statement);
|
||||
break;
|
||||
|
||||
case IN_CONSTRUCTOR:
|
||||
addInitializationToConstructors(local, field, enclosingConstructor, factory);
|
||||
break;
|
||||
case IN_SETUP_METHOD:
|
||||
addInitializationToSetUp(local, field, factory);
|
||||
}
|
||||
|
||||
if (enclosingConstructor != null && initializerPlace == IN_CONSTRUCTOR) {
|
||||
PsiStatement statement = createAssignment(local, fieldName, factory);
|
||||
declarationStatement.replace(statement);
|
||||
}
|
||||
|
||||
if (rebindNeeded2) {
|
||||
for (final PsiReference reference : refs) {
|
||||
if (reference != null) {
|
||||
//expr = RefactoringUtil.outermostParenthesizedExpression(expr);
|
||||
RefactoringUtil.replaceOccurenceWithFieldRef((PsiExpression)reference, field, aaClass);
|
||||
//replaceOccurenceWithFieldRef((PsiExpression)reference, field, aaClass);
|
||||
}
|
||||
}
|
||||
//RefactoringUtil.renameVariableReferences(local, pPrefix + fieldName, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
final Runnable runnable =
|
||||
new IntroduceFieldRunnable(rebindNeeded1, local, aaClass, settings, isStatic, occurences);
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
@@ -176,7 +103,7 @@ public abstract class LocalToFieldHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private PsiField createField(PsiLocalVariable local, PsiType forcedType, String fieldName, boolean includeInitializer) {
|
||||
private static PsiField createField(PsiLocalVariable local, PsiType forcedType, String fieldName, boolean includeInitializer) {
|
||||
@NonNls StringBuilder pattern = new StringBuilder();
|
||||
pattern.append("private int ");
|
||||
pattern.append(fieldName);
|
||||
@@ -187,10 +114,11 @@ public abstract class LocalToFieldHandler {
|
||||
pattern.append("=0");
|
||||
}
|
||||
pattern.append(";");
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
|
||||
final Project project = local.getProject();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
try {
|
||||
PsiField field = factory.createFieldFromText(pattern.toString(), null);
|
||||
field = (PsiField)CodeStyleManager.getInstance(myProject).reformat(field);
|
||||
field = (PsiField)CodeStyleManager.getInstance(project).reformat(field);
|
||||
|
||||
field.getTypeElement().replace(factory.createTypeElement(forcedType));
|
||||
if (includeInitializer) {
|
||||
@@ -207,11 +135,11 @@ public abstract class LocalToFieldHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private PsiStatement createAssignment(PsiLocalVariable local, String fieldname, PsiElementFactory factory) {
|
||||
private static PsiStatement createAssignment(PsiLocalVariable local, String fieldname, PsiElementFactory factory) {
|
||||
try {
|
||||
String pattern = fieldname + "=0;";
|
||||
PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(pattern, null);
|
||||
statement = (PsiExpressionStatement)CodeStyleManager.getInstance(myProject).reformat(statement);
|
||||
statement = (PsiExpressionStatement)CodeStyleManager.getInstance(local.getProject()).reformat(statement);
|
||||
|
||||
PsiAssignmentExpression expr = (PsiAssignmentExpression)statement.getExpression();
|
||||
final PsiExpression initializer = RefactoringUtil.convertInitializerToNormalExpression(local.getInitializer(), local.getType());
|
||||
@@ -225,7 +153,7 @@ public abstract class LocalToFieldHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void addInitializationToSetUp(final PsiLocalVariable local, final PsiField field, final PsiElementFactory factory)
|
||||
private static PsiStatement addInitializationToSetUp(final PsiLocalVariable local, final PsiField field, final PsiElementFactory factory)
|
||||
throws IncorrectOperationException {
|
||||
PsiMethod inClass = TestUtil.findOrCreateSetUpMethod(field.getContainingClass());
|
||||
assert inClass != null;
|
||||
@@ -233,15 +161,16 @@ public abstract class LocalToFieldHandler {
|
||||
final PsiCodeBlock body = inClass.getBody();
|
||||
assert body != null;
|
||||
if (PsiTreeUtil.isAncestor(body, local, false)) {
|
||||
body.addBefore(assignment, PsiTreeUtil.getParentOfType(local, PsiStatement.class));
|
||||
assignment = (PsiStatement)body.addBefore(assignment, PsiTreeUtil.getParentOfType(local, PsiStatement.class));
|
||||
} else {
|
||||
body.add(assignment);
|
||||
assignment = (PsiStatement)body.add(assignment);
|
||||
}
|
||||
local.delete();
|
||||
return assignment;
|
||||
}
|
||||
|
||||
private void addInitializationToConstructors(PsiLocalVariable local, PsiField field, PsiMethod enclosingConstructor,
|
||||
PsiElementFactory factory) throws IncorrectOperationException {
|
||||
private static PsiStatement addInitializationToConstructors(PsiLocalVariable local, PsiField field, PsiMethod enclosingConstructor,
|
||||
PsiElementFactory factory) throws IncorrectOperationException {
|
||||
PsiClass aClass = field.getContainingClass();
|
||||
PsiMethod[] constructors = aClass.getConstructors();
|
||||
PsiStatement assignment = createAssignment(local, field.getName(), factory);
|
||||
@@ -263,15 +192,125 @@ public abstract class LocalToFieldHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
body.add(assignment);
|
||||
assignment = (PsiStatement)body.add(assignment);
|
||||
added = true;
|
||||
}
|
||||
if (!added && enclosingConstructor == null) {
|
||||
PsiMethod constructor = factory.createConstructor();
|
||||
constructor.getBody().add(assignment);
|
||||
aClass.add(constructor);
|
||||
PsiMethod constructor = (PsiMethod)aClass.add(factory.createConstructor());
|
||||
assignment = (PsiStatement)constructor.getBody().add(assignment);
|
||||
}
|
||||
|
||||
if (enclosingConstructor == null) local.delete();
|
||||
return assignment;
|
||||
}
|
||||
|
||||
static class IntroduceFieldRunnable implements Runnable {
|
||||
private final String myVariableName;
|
||||
private final String myFieldName;
|
||||
private final boolean myRebindNeeded;
|
||||
private final PsiLocalVariable myLocal;
|
||||
private final Project myProject;
|
||||
private final PsiClass myDestinationClass;
|
||||
private final BaseExpressionToFieldHandler.Settings mySettings;
|
||||
private final BaseExpressionToFieldHandler.InitializationPlace myInitializerPlace;
|
||||
private final boolean myStatic;
|
||||
private final PsiExpression[] myOccurences;
|
||||
private PsiField myField;
|
||||
private PsiStatement myAssignmentStatement;
|
||||
|
||||
public IntroduceFieldRunnable(boolean rebindNeeded,
|
||||
PsiLocalVariable local,
|
||||
PsiClass aClass,
|
||||
BaseExpressionToFieldHandler.Settings settings,
|
||||
boolean isStatic,
|
||||
PsiExpression[] occurrences) {
|
||||
myVariableName = local.getName();
|
||||
myFieldName = settings.getFieldName();
|
||||
myRebindNeeded = rebindNeeded;
|
||||
myLocal = local;
|
||||
myProject = local.getProject();
|
||||
myDestinationClass = aClass;
|
||||
mySettings = settings;
|
||||
myInitializerPlace = settings.getInitializerPlace();
|
||||
myStatic = isStatic;
|
||||
myOccurences = occurrences;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
final boolean rebindNeeded2 = !myVariableName.equals(myFieldName) || myRebindNeeded;
|
||||
final PsiReference[] refs;
|
||||
if (rebindNeeded2) {
|
||||
refs = ReferencesSearch.search(myLocal, GlobalSearchScope.projectScope(myProject), false).toArray(new PsiReference[0]);
|
||||
}
|
||||
else {
|
||||
refs = null;
|
||||
}
|
||||
|
||||
final PsiMethod enclosingConstructor = BaseExpressionToFieldHandler.getEnclosingConstructor(myDestinationClass, myLocal);
|
||||
myField = mySettings.isIntroduceEnumConstant() ? EnumConstantsUtil.createEnumConstant(myDestinationClass, myLocal, myFieldName)
|
||||
: createField(myLocal, mySettings.getForcedType(), myFieldName, myInitializerPlace == IN_FIELD_DECLARATION);
|
||||
myField = (PsiField)myDestinationClass.add(myField);
|
||||
BaseExpressionToFieldHandler.setModifiers(myField, mySettings, myStatic);
|
||||
if (!mySettings.isIntroduceEnumConstant()) {
|
||||
VisibilityUtil.fixVisibility(myOccurences, myField, mySettings.getFieldVisibility());
|
||||
}
|
||||
|
||||
myLocal.normalizeDeclaration();
|
||||
PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)myLocal.getParent();
|
||||
final BaseExpressionToFieldHandler.InitializationPlace finalInitializerPlace;
|
||||
if (myLocal.getInitializer() == null) {
|
||||
finalInitializerPlace = IN_FIELD_DECLARATION;
|
||||
}
|
||||
else {
|
||||
finalInitializerPlace = myInitializerPlace;
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
|
||||
|
||||
switch (finalInitializerPlace) {
|
||||
case IN_FIELD_DECLARATION:
|
||||
declarationStatement.delete();
|
||||
break;
|
||||
|
||||
case IN_CURRENT_METHOD:
|
||||
PsiStatement statement = createAssignment(myLocal, myFieldName, factory);
|
||||
myAssignmentStatement = (PsiStatement)declarationStatement.replace(statement);
|
||||
break;
|
||||
|
||||
case IN_CONSTRUCTOR:
|
||||
myAssignmentStatement = addInitializationToConstructors(myLocal, myField, enclosingConstructor, factory);
|
||||
break;
|
||||
case IN_SETUP_METHOD:
|
||||
myAssignmentStatement = addInitializationToSetUp(myLocal, myField, factory);
|
||||
}
|
||||
|
||||
if (enclosingConstructor != null && myInitializerPlace == IN_CONSTRUCTOR) {
|
||||
PsiStatement statement = createAssignment(myLocal, myFieldName, factory);
|
||||
myAssignmentStatement = (PsiStatement)declarationStatement.replace(statement);
|
||||
}
|
||||
|
||||
if (rebindNeeded2) {
|
||||
for (final PsiReference reference : refs) {
|
||||
if (reference != null) {
|
||||
//expr = RefactoringUtil.outermostParenthesizedExpression(expr);
|
||||
RefactoringUtil.replaceOccurenceWithFieldRef((PsiExpression)reference, myField, myDestinationClass);
|
||||
//replaceOccurenceWithFieldRef((PsiExpression)reference, field, aaClass);
|
||||
}
|
||||
}
|
||||
//RefactoringUtil.renameVariableReferences(local, pPrefix + fieldName, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public PsiField getField() {
|
||||
return myField;
|
||||
}
|
||||
|
||||
public PsiStatement getAssignmentStatement() {
|
||||
return myAssignmentStatement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
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.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.introduceVariable.VariableInplaceIntroducer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/15/11
|
||||
*/
|
||||
public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroducer {
|
||||
public AbstractInplaceIntroducer(Project project,
|
||||
TypeExpression expression,
|
||||
Editor editor,
|
||||
PsiVariable elementToRename,
|
||||
boolean cantChangeFinalModifier,
|
||||
boolean hasTypeSuggestion,
|
||||
RangeMarker exprMarker,
|
||||
List<RangeMarker> occurrenceMarkers) {
|
||||
super(project, expression, editor, elementToRename, cantChangeFinalModifier, hasTypeSuggestion, exprMarker, occurrenceMarkers);
|
||||
}
|
||||
|
||||
protected abstract boolean isReplaceAllOccurrences();
|
||||
|
||||
protected abstract PsiExpression getExpr();
|
||||
|
||||
protected abstract PsiExpression[] getOccurrences();
|
||||
|
||||
|
||||
|
||||
protected abstract List<RangeMarker> getOccurrenceMarkers();
|
||||
|
||||
@Override
|
||||
protected void addReferenceAtCaret(Collection<PsiReference> refs) {
|
||||
final PsiVariable variable = getVariable();
|
||||
if (variable != null) {
|
||||
for (PsiReference reference : ReferencesSearch.search(variable)) {
|
||||
refs.remove(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean appendAdditionalElement(List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAdditionalElementsToRename(boolean processTextOccurrences, List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
if (isReplaceAllOccurrences()) {
|
||||
for (PsiExpression expression : getOccurrences()) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(expression, new TextRange(0, expression.getTextLength())));
|
||||
}
|
||||
}
|
||||
else if (getExpr() != null) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(getExpr(), new TextRange(0, getExpr().getTextLength())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAdditionalRangesToHighlight(Map<TextRange, TextAttributes> rangesToHighlight,
|
||||
Collection<Pair<PsiElement, TextRange>> stringUsages,
|
||||
EditorColorsManager colorsManager) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addHighlights(@NotNull Map<TextRange, TextAttributes> ranges,
|
||||
@NotNull Editor editor,
|
||||
@NotNull Collection<RangeHighlighter> highlighters,
|
||||
@NotNull HighlightManager highlightManager) {
|
||||
final TextAttributes attributes =
|
||||
EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
|
||||
final int variableNameLength = getVariable().getName().length();
|
||||
if (isReplaceAllOccurrences()) {
|
||||
for (RangeMarker marker : getOccurrenceMarkers()) {
|
||||
final int startOffset = marker.getStartOffset();
|
||||
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null);
|
||||
}
|
||||
}
|
||||
else if (getExpr() != null) {
|
||||
final int startOffset = getExprMarker().getStartOffset();
|
||||
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null);
|
||||
}
|
||||
super.addHighlights(ranges, editor, highlighters, highlightManager);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static PsiExpression restoreExpression(PsiFile containingFile,
|
||||
PsiVariable psiVariable,
|
||||
PsiElementFactory elementFactory,
|
||||
RangeMarker marker, String exprText) {
|
||||
if (exprText == null) return null;
|
||||
if (psiVariable == null || !psiVariable.isValid()) return null;
|
||||
final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
|
||||
final PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() == psiVariable) {
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+25
-89
@@ -15,43 +15,28 @@
|
||||
*/
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.IdeTooltipManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
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.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.introduceVariable.VariableInplaceIntroducer;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManager;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -64,7 +49,6 @@ import java.util.List;
|
||||
*/
|
||||
class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
|
||||
private Balloon myBalloon;
|
||||
private final Project myProject;
|
||||
private final Editor myEditor;
|
||||
private final TypeSelectorManagerImpl myTypeSelectorManager;
|
||||
@@ -104,7 +88,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
myMethodToSearchFor = methodToSearchFor;
|
||||
myOccurrences = occurrences;
|
||||
myMustBeFinal = mustBeFinal;
|
||||
myExprMarker = expr != null ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null;
|
||||
myExprMarker = expr != null ? myEditor.getDocument().createRangeMarker(expr.getTextRange()) : null;
|
||||
myExprText = myExpr != null ? myExpr.getText() : null;
|
||||
|
||||
myWholePanel = new JPanel(new GridBagLayout());
|
||||
@@ -180,7 +164,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
return myOccurrenceMarkers;
|
||||
}
|
||||
|
||||
private class ParameterInplaceIntroducer extends VariableInplaceIntroducer {
|
||||
private class ParameterInplaceIntroducer extends AbstractInplaceIntroducer {
|
||||
|
||||
private SmartTypePointer myParameterTypePointer;
|
||||
private SmartTypePointer myDefaultParameterTypePointer;
|
||||
@@ -190,7 +174,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
public ParameterInplaceIntroducer(PsiParameter parameter) {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
myEditor, parameter, myMustBeFinal,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, getOccurrenceMarkers());
|
||||
myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, InplaceIntroduceParameterPopup.this.getOccurrenceMarkers());
|
||||
myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(parameter.getType());
|
||||
}
|
||||
|
||||
@@ -207,64 +191,31 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReplaceAllOccurrences() {
|
||||
return InplaceIntroduceParameterPopup.this.isReplaceAllOccurences();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression getExpr() {
|
||||
return myExpr;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression[] getOccurrences() {
|
||||
return myOccurrences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<RangeMarker> getOccurrenceMarkers() {
|
||||
return InplaceIntroduceParameterPopup.this.getOccurrenceMarkers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
return getParameter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addReferenceAtCaret(Collection<PsiReference> refs) {
|
||||
final PsiVariable variable = getVariable();
|
||||
if (variable != null) {
|
||||
for (PsiReference reference : ReferencesSearch.search(variable)) {
|
||||
refs.remove(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean appendAdditionalElement(List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAdditionalElementsToRename(boolean processTextOccurrences, List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
if (isReplaceAllOccurences()) {
|
||||
for (PsiExpression expression : myOccurrences) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(expression, new TextRange(0, expression.getTextLength())));
|
||||
}
|
||||
}
|
||||
else if (myExpr != null) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(myExpr, new TextRange(0, myExpr.getTextLength())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectAdditionalRangesToHighlight(Map<TextRange, TextAttributes> rangesToHighlight,
|
||||
Collection<Pair<PsiElement, TextRange>> stringUsages,
|
||||
EditorColorsManager colorsManager) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addHighlights(@NotNull Map<TextRange, TextAttributes> ranges,
|
||||
@NotNull Editor editor,
|
||||
@NotNull Collection<RangeHighlighter> highlighters,
|
||||
@NotNull HighlightManager highlightManager) {
|
||||
final TextAttributes attributes =
|
||||
EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
|
||||
final int variableNameLength = getVariable().getName().length();
|
||||
if (isReplaceAllOccurences()) {
|
||||
for (RangeMarker marker : getOccurrenceMarkers()) {
|
||||
final int startOffset = marker.getStartOffset();
|
||||
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null);
|
||||
}
|
||||
}
|
||||
else if (myExpr != null) {
|
||||
final int startOffset = myExprMarker.getStartOffset();
|
||||
highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null);
|
||||
}
|
||||
super.addHighlights(ranges, editor, highlighters, highlightManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
@@ -336,7 +287,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
public void run() {
|
||||
final PsiFile containingFile = myMethod.getContainingFile();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
myExpr = restoreExpression(containingFile, psiParameter, elementFactory, myExprMarker);
|
||||
myExpr = restoreExpression(containingFile, psiParameter, elementFactory, myExprMarker, myExprText);
|
||||
if (myExpr != null) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange());
|
||||
}
|
||||
@@ -347,7 +298,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
myOccurrences[i] = myExpr;
|
||||
continue;
|
||||
}
|
||||
final PsiExpression psiExpression = restoreExpression(containingFile, psiParameter, elementFactory, marker);
|
||||
final PsiExpression psiExpression = restoreExpression(containingFile, psiParameter, elementFactory, marker, myExprText);
|
||||
if (psiExpression != null) {
|
||||
myOccurrences[i] = psiExpression;
|
||||
}
|
||||
@@ -360,21 +311,6 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiExpression restoreExpression(PsiFile containingFile,
|
||||
PsiParameter psiParameter,
|
||||
PsiElementFactory elementFactory,
|
||||
RangeMarker marker) {
|
||||
if (myExprText == null) return null;
|
||||
if (psiParameter == null || !psiParameter.isValid()) return null;
|
||||
final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
|
||||
final PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() == psiParameter) {
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(myExprText, myMethod));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public boolean createFinals() {
|
||||
return hasFinalModifier();
|
||||
|
||||
+42
-24
@@ -109,30 +109,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
myCanBeFinal = new NonFocusableCheckBox("Declare final");
|
||||
myCanBeFinal.setSelected(createFinals());
|
||||
myCanBeFinal.setMnemonic('f');
|
||||
myCanBeFinal.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new WriteCommandAction(project){
|
||||
@Override
|
||||
protected void run(com.intellij.openapi.application.Result result) throws Throwable {
|
||||
final PsiModifierList modifierList = getVariable().getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
final Document document = myEditor.getDocument();
|
||||
final int textOffset = modifierList.getTextOffset();
|
||||
if (myCanBeFinal.isSelected()) {
|
||||
if (StringUtil.isEmptyOrSpaces(document.getText(new TextRange(textOffset - 1, textOffset)))) {
|
||||
document.insertString(textOffset - 1, "final");
|
||||
} else {
|
||||
document.insertString(textOffset, "final ");
|
||||
}
|
||||
}
|
||||
else {
|
||||
document.deleteString(textOffset, textOffset + modifierList.getTextLength());
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
myCanBeFinal.addActionListener(new FinalListener(project));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +163,10 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
return super.performInplaceRename(processTextOccurrences, nameSuggestions);
|
||||
}
|
||||
|
||||
public RangeMarker getExprMarker() {
|
||||
return myExprMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
try {
|
||||
@@ -382,4 +363,41 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
myBalloon
|
||||
.show(new RelativePoint(new Point(screenPoint.x, screenPoint.y - myEditor.getLineHeight())), Balloon.Position.above);
|
||||
}
|
||||
|
||||
public class FinalListener implements ActionListener {
|
||||
private final Project myProject;
|
||||
|
||||
public FinalListener(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
perform(myCanBeFinal.isSelected());
|
||||
}
|
||||
|
||||
public void perform(final boolean generateFinal) {
|
||||
new WriteCommandAction(myProject){
|
||||
@Override
|
||||
protected void run(com.intellij.openapi.application.Result result) throws Throwable {
|
||||
final PsiVariable variable = getVariable();
|
||||
LOG.assertTrue(variable != null);
|
||||
final PsiModifierList modifierList = variable.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
final int textOffset = modifierList.getTextOffset();
|
||||
|
||||
final Document document = myEditor.getDocument();
|
||||
if (generateFinal) {
|
||||
final PsiTypeElement typeElement = variable.getTypeElement();
|
||||
final int typeOffset = typeElement != null ? typeElement.getTextOffset() : textOffset;
|
||||
document.insertString(typeOffset, PsiModifier.FINAL + " ");
|
||||
}
|
||||
else {
|
||||
final int idx = modifierList.getText().indexOf(PsiModifier.FINAL);
|
||||
document.deleteString(textOffset + idx, textOffset + idx + PsiModifier.FINAL.length() + 1);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-6
@@ -144,12 +144,7 @@ public class VariableInplaceRenamer {
|
||||
|
||||
ourRenamersStack.push(this);
|
||||
|
||||
PsiElement scope = null;
|
||||
final SearchScope searchScope = myElementToRename.getManager().getSearchHelper().getUseScope(myElementToRename);
|
||||
if (searchScope instanceof LocalSearchScope) {
|
||||
final PsiElement[] elements = ((LocalSearchScope)searchScope).getScope();
|
||||
scope = PsiTreeUtil.findCommonParent(elements);
|
||||
}
|
||||
PsiElement scope = checkLocalScope();
|
||||
|
||||
if (scope == null) {
|
||||
return false; // Should have valid local search scope for inplace rename
|
||||
@@ -173,6 +168,17 @@ public class VariableInplaceRenamer {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected PsiElement checkLocalScope() {
|
||||
final SearchScope searchScope = myElementToRename.getManager().getSearchHelper().getUseScope(myElementToRename);
|
||||
if (searchScope instanceof LocalSearchScope) {
|
||||
final PsiElement[] elements = ((LocalSearchScope)searchScope).getScope();
|
||||
return PsiTreeUtil.findCommonParent(elements);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean appendAdditionalElement(List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
return stringUsages.isEmpty();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user