mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-07 22:09:38 +07:00
[java-refactoring] IDEA-324451 SlowOp for EncapsulateFieldsHandler
GitOrigin-RevId: 9c035597260514a9513fda4e4b6b27ba4b53726d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c8ae1bfdd5
commit
198b2402e6
@@ -1,9 +1,13 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.refactoring.encapsulateFields;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.java.refactoring.JavaRefactoringBundle;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
@@ -22,10 +26,13 @@ import com.intellij.ui.*;
|
||||
import com.intellij.ui.icons.RowIcon;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
@@ -35,7 +42,10 @@ import javax.swing.table.TableCellEditor;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class EncapsulateFieldsDialog extends RefactoringDialog implements EncapsulateFieldsDescriptor {
|
||||
private static final Logger LOG = Logger.getInstance(EncapsulateFieldsDialog.class);
|
||||
@@ -50,13 +60,16 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
private final PsiClass myClass;
|
||||
|
||||
private final PsiField[] myFields;
|
||||
private final ConcurrentHashMap<PsiField, Icon> myIconFields;
|
||||
private final boolean[] myCheckedMarks;
|
||||
private final boolean[] myFinalMarks;
|
||||
private final String[] myFieldNames;
|
||||
private final String[] myGetterNames;
|
||||
private final PsiMethod[] myGetterPrototypes;
|
||||
private final ConcurrentHashMap<Integer, PsiMethod> myGetterPrototypes;
|
||||
private final ConcurrentHashMap<Integer, RowIcon> myGetterPrototypesIcons;
|
||||
private final String[] mySetterNames;
|
||||
private final PsiMethod[] mySetterPrototypes;
|
||||
private final ConcurrentHashMap<Integer, PsiMethod> mySetterPrototypes;
|
||||
private final ConcurrentHashMap<Integer, RowIcon> mySetterPrototypesIcons;
|
||||
|
||||
private JBTable myTable;
|
||||
private MyTableModel myTableModel;
|
||||
@@ -89,9 +102,36 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
}
|
||||
|
||||
public EncapsulateFieldsDialog(Project project, PsiClass aClass, final Set preselectedFields, EncapsulateFieldHelper helper) {
|
||||
this(project, EncapsulateFieldsContainer.create(aClass, preselectedFields, helper));
|
||||
}
|
||||
|
||||
public EncapsulateFieldsDialog(Project project, EncapsulateFieldsContainer container) {
|
||||
super(project, true);
|
||||
myClass = aClass;
|
||||
myHelper = helper;
|
||||
myClass = container.myClass;
|
||||
myHelper = container.myHelper;
|
||||
myFields = container.myFields;
|
||||
myIconFields = new ConcurrentHashMap<>(container.myIconFields);
|
||||
myCheckedMarks = container.myCheckedMarks;
|
||||
myFinalMarks = container.myFinalMarks;
|
||||
myFieldNames = container.myFieldNames;
|
||||
myGetterNames = container.myGetterNames;
|
||||
myGetterPrototypes = new ConcurrentHashMap<>();
|
||||
for (int i = 0; i < container.myGetterPrototypes.length; i++) {
|
||||
PsiMethod prototype = container.myGetterPrototypes[i];
|
||||
if (prototype != null) {
|
||||
myGetterPrototypes.put(i, prototype);
|
||||
}
|
||||
}
|
||||
myGetterPrototypesIcons = new ConcurrentHashMap<>(container.myGetterPrototypesIcons);
|
||||
mySetterNames = container.mySetterNames;
|
||||
mySetterPrototypes = new ConcurrentHashMap<>();
|
||||
for (int i = 0; i < container.mySetterPrototypes.length; i++) {
|
||||
PsiMethod prototype = container.mySetterPrototypes[i];
|
||||
if (prototype != null) {
|
||||
mySetterPrototypes.put(i, prototype);
|
||||
}
|
||||
}
|
||||
mySetterPrototypesIcons = new ConcurrentHashMap<>(container.mySetterPrototypesIcons);
|
||||
|
||||
String title = getRefactoringName();
|
||||
String qName = myClass.getQualifiedName();
|
||||
@@ -99,30 +139,6 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
title += " - " + qName;
|
||||
}
|
||||
setTitle(title);
|
||||
|
||||
myFields = myHelper.getApplicableFields(myClass);
|
||||
myFieldNames = new String[myFields.length];
|
||||
myCheckedMarks = new boolean[myFields.length];
|
||||
myFinalMarks = new boolean[myFields.length];
|
||||
myGetterNames = new String[myFields.length];
|
||||
mySetterNames = new String[myFields.length];
|
||||
myGetterPrototypes = new PsiMethod[myFields.length];
|
||||
mySetterPrototypes = new PsiMethod[myFields.length];
|
||||
for (int idx = 0; idx < myFields.length; idx++) {
|
||||
PsiField field = myFields[idx];
|
||||
myCheckedMarks[idx] = preselectedFields.contains(field);
|
||||
myFinalMarks[idx] = field.hasModifierProperty(PsiModifier.FINAL);
|
||||
myFieldNames[idx] =
|
||||
PsiFormatUtil.formatVariable(field,
|
||||
PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.TYPE_AFTER,
|
||||
PsiSubstitutor.EMPTY
|
||||
);
|
||||
myGetterNames[idx] = myHelper.suggestGetterName(field);
|
||||
mySetterNames[idx] = myHelper.suggestSetterName(field);
|
||||
myGetterPrototypes[idx] = myHelper.generateMethodPrototype(field, myGetterNames[idx], true);
|
||||
mySetterPrototypes[idx] = myHelper.generateMethodPrototype(field, mySetterNames[idx], false);
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -132,16 +148,19 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
FieldDescriptor[] descriptors = new FieldDescriptor[rows.length];
|
||||
|
||||
for (int idx = 0; idx < rows.length; idx++) {
|
||||
String getterName = myGetterNames[rows[idx]];
|
||||
PsiField field = myFields[rows[idx]];
|
||||
String setterName = mySetterNames[rows[idx]];
|
||||
descriptors[idx] = new FieldDescriptorImpl(
|
||||
myFields[rows[idx]],
|
||||
myGetterNames[rows[idx]],
|
||||
mySetterNames[rows[idx]],
|
||||
field,
|
||||
getterName,
|
||||
setterName,
|
||||
isToEncapsulateGet()
|
||||
? myGetterPrototypes[rows[idx]]
|
||||
: null,
|
||||
? myHelper.generateMethodPrototype(field, getterName, true)
|
||||
: null,
|
||||
isToEncapsulateSet()
|
||||
? mySetterPrototypes[rows[idx]]
|
||||
: null
|
||||
? myHelper.generateMethodPrototype(field, setterName, false)
|
||||
: null
|
||||
);
|
||||
}
|
||||
return descriptors;
|
||||
@@ -461,7 +480,10 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
return;
|
||||
}
|
||||
|
||||
invokeRefactoring(new EncapsulateFieldsProcessor(myProject, this));
|
||||
EncapsulateFieldsProcessor processor = ActionUtil.underModalProgress(myProject,
|
||||
CodeInsightBundle.message("progress.title.resolving.reference"),
|
||||
() -> new EncapsulateFieldsProcessor(myProject, this));
|
||||
invokeRefactoring(processor);
|
||||
JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
|
||||
settings.ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE = myCbUseAccessorsWhenAccessible.isSelected();
|
||||
}
|
||||
@@ -575,22 +597,48 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
@Override
|
||||
public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) {
|
||||
if (columnIndex == CHECKED_COLUMN) {
|
||||
myCheckedMarks[rowIndex] = ((Boolean) aValue).booleanValue();
|
||||
myCheckedMarks[rowIndex] = ((Boolean)aValue).booleanValue();
|
||||
fireTableRowsUpdated(rowIndex, rowIndex);
|
||||
} else {
|
||||
String name = (String) aValue;
|
||||
}
|
||||
else {
|
||||
String name = (String)aValue;
|
||||
PsiField field = myFields[rowIndex];
|
||||
switch (columnIndex) {
|
||||
case GETTER_COLUMN -> {
|
||||
myGetterNames[rowIndex] = name;
|
||||
myGetterPrototypes[rowIndex] = myHelper.generateMethodPrototype(field, name, true);
|
||||
}
|
||||
case SETTER_COLUMN -> {
|
||||
mySetterNames[rowIndex] = name;
|
||||
mySetterPrototypes[rowIndex] = myHelper.generateMethodPrototype(field, name, false);
|
||||
}
|
||||
default -> throw new RuntimeException("Incorrect column index");
|
||||
}
|
||||
ReadAction.nonBlocking(() -> {
|
||||
switch (columnIndex) {
|
||||
case GETTER_COLUMN -> {
|
||||
myGetterNames[rowIndex] = name;
|
||||
PsiMethod method = myHelper.generateMethodPrototype(field, name, true);
|
||||
if (method != null) {
|
||||
myGetterPrototypes.put(rowIndex, method);
|
||||
}
|
||||
myGetterPrototypesIcons.put(rowIndex, EncapsulateFieldsContainer.getIcon(myGetterPrototypes.get(rowIndex), myClass));
|
||||
}
|
||||
case SETTER_COLUMN -> {
|
||||
mySetterNames[rowIndex] = name;
|
||||
PsiMethod method = myHelper.generateMethodPrototype(field, name, false);
|
||||
if (method != null) {
|
||||
mySetterPrototypes.put(rowIndex, method);
|
||||
}
|
||||
mySetterPrototypesIcons.put(rowIndex, EncapsulateFieldsContainer.getIcon(mySetterPrototypes.get(rowIndex), myClass));
|
||||
}
|
||||
default -> throw new RuntimeException("Incorrect column index");
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.finishOnUiThread(ModalityState.stateForComponent(EncapsulateFieldsDialog.this.myTable), nill->{
|
||||
EncapsulateFieldsDialog.this.repaint();
|
||||
})
|
||||
.expireWith(EncapsulateFieldsDialog.this.getDisposable())
|
||||
.submit(AppExecutorUtil.getAppExecutorService());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -607,42 +655,29 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
PsiField field = myFields[row];
|
||||
switch (modelColumn) {
|
||||
case FIELD_COLUMN -> {
|
||||
Icon icon = field.getIcon(Iconable.ICON_FLAG_VISIBILITY);
|
||||
setIcon(icon);
|
||||
setDisabledIcon(icon);
|
||||
Icon icon = myIconFields.get(field);
|
||||
if (icon != null) {
|
||||
setIcon(icon);
|
||||
setDisabledIcon(icon);
|
||||
}
|
||||
configureColors(isSelected, table, hasFocus, row, column);
|
||||
}
|
||||
case GETTER_COLUMN, SETTER_COLUMN -> {
|
||||
Icon methodIcon = IconUtil.getEmptyIcon(true);
|
||||
Icon overrideIcon = EmptyIcon.ICON_16;
|
||||
|
||||
PsiMethod prototype = modelColumn == GETTER_COLUMN ? myGetterPrototypes[row] : mySetterPrototypes[row];
|
||||
PsiMethod prototype = modelColumn == GETTER_COLUMN ? myGetterPrototypes.get(row) : mySetterPrototypes.get(row);
|
||||
RowIcon rowIcon = modelColumn == GETTER_COLUMN ? myGetterPrototypesIcons.get(row) : mySetterPrototypesIcons.get(row);
|
||||
if (prototype != null) {
|
||||
// MyTableRenderer.this.setForeground(Color.black);
|
||||
configureColors(isSelected, table, hasFocus, row, column);
|
||||
|
||||
PsiMethod existing = myClass.findMethodBySignature(prototype, false);
|
||||
if (existing != null) {
|
||||
methodIcon = existing.getIcon(Iconable.ICON_FLAG_VISIBILITY);
|
||||
}
|
||||
|
||||
PsiMethod[] superMethods = prototype.findSuperMethods(myClass);
|
||||
if (superMethods.length > 0) {
|
||||
if (!superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
overrideIcon = AllIcons.General.OverridingMethod;
|
||||
}
|
||||
else {
|
||||
overrideIcon = AllIcons.General.ImplementingMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
setForeground(JBColor.RED);
|
||||
}
|
||||
|
||||
RowIcon icon = IconManager.getInstance().createRowIcon(methodIcon, overrideIcon);
|
||||
setIcon(icon);
|
||||
setDisabledIcon(icon);
|
||||
if (rowIcon != null) {
|
||||
setIcon(rowIcon);
|
||||
setDisabledIcon(rowIcon);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
setIcon(null);
|
||||
@@ -676,4 +711,91 @@ public class EncapsulateFieldsDialog extends RefactoringDialog implements Encaps
|
||||
private static @NlsContexts.DialogTitle String getRefactoringName() {
|
||||
return JavaRefactoringBundle.message("encapsulate.fields.title");
|
||||
}
|
||||
|
||||
public record EncapsulateFieldsContainer(
|
||||
EncapsulateFieldHelper myHelper,
|
||||
PsiClass myClass,
|
||||
PsiField[] myFields,
|
||||
Map<PsiField, Icon> myIconFields,
|
||||
boolean[] myCheckedMarks,
|
||||
boolean[] myFinalMarks,
|
||||
String[] myFieldNames,
|
||||
String[] myGetterNames,
|
||||
PsiMethod[] myGetterPrototypes,
|
||||
Map<Integer, RowIcon> myGetterPrototypesIcons,
|
||||
String[] mySetterNames,
|
||||
PsiMethod[] mySetterPrototypes,
|
||||
Map<Integer, RowIcon> mySetterPrototypesIcons
|
||||
) {
|
||||
static EncapsulateFieldsContainer create(@NotNull PsiClass aClass,
|
||||
@NotNull Set preselectedFields,
|
||||
@NotNull EncapsulateFieldHelper helper) {
|
||||
PsiClass myClass = aClass;
|
||||
EncapsulateFieldHelper myHelper = helper;
|
||||
PsiField[] myFields = helper.getApplicableFields(myClass);
|
||||
Map<PsiField, Icon> myIconFields = new HashMap<>();
|
||||
for (PsiField field : myFields) {
|
||||
myIconFields.put(field, field.getIcon(Iconable.ICON_FLAG_VISIBILITY));
|
||||
}
|
||||
String[] myFieldNames = new String[myFields.length];
|
||||
boolean[] myCheckedMarks = new boolean[myFields.length];
|
||||
boolean[] myFinalMarks = new boolean[myFields.length];
|
||||
String[] myGetterNames = new String[myFields.length];
|
||||
String[] mySetterNames = new String[myFields.length];
|
||||
PsiMethod[] myGetterPrototypes = new PsiMethod[myFields.length];
|
||||
PsiMethod[] mySetterPrototypes = new PsiMethod[myFields.length];
|
||||
for (int idx = 0; idx < myFields.length; idx++) {
|
||||
PsiField field = myFields[idx];
|
||||
myCheckedMarks[idx] = preselectedFields.contains(field);
|
||||
myFinalMarks[idx] = field.hasModifierProperty(PsiModifier.FINAL);
|
||||
myFieldNames[idx] =
|
||||
PsiFormatUtil.formatVariable(field,
|
||||
PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE | PsiFormatUtilBase.TYPE_AFTER,
|
||||
PsiSubstitutor.EMPTY
|
||||
);
|
||||
myGetterNames[idx] = myHelper.suggestGetterName(field);
|
||||
mySetterNames[idx] = myHelper.suggestSetterName(field);
|
||||
myGetterPrototypes[idx] = myHelper.generateMethodPrototype(field, myGetterNames[idx], true);
|
||||
mySetterPrototypes[idx] = myHelper.generateMethodPrototype(field, mySetterNames[idx], false);
|
||||
}
|
||||
HashMap<Integer, RowIcon> myGetterPrototypesIcons = new HashMap<>();
|
||||
HashMap<Integer, RowIcon> mySetterPrototypesIcons = new HashMap<>();
|
||||
for (int i = 0; i < myGetterPrototypes.length; i++) {
|
||||
PsiMethod prototype = myGetterPrototypes[i];
|
||||
myGetterPrototypesIcons.put(i, getIcon(prototype, myClass));
|
||||
}
|
||||
for (int i = 0; i < mySetterPrototypes.length; i++) {
|
||||
PsiMethod prototype = mySetterPrototypes[i];
|
||||
mySetterPrototypesIcons.put(i, getIcon(prototype, myClass));
|
||||
}
|
||||
return new EncapsulateFieldsContainer(myHelper, myClass, myFields, myIconFields, myCheckedMarks, myFinalMarks, myFieldNames,
|
||||
myGetterNames, myGetterPrototypes, myGetterPrototypesIcons,
|
||||
mySetterNames, mySetterPrototypes, mySetterPrototypesIcons);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static RowIcon getIcon(@Nullable PsiMethod prototype, @Nullable PsiClass psiClass) {
|
||||
Icon methodIcon = IconUtil.getEmptyIcon(true);
|
||||
Icon overrideIcon = EmptyIcon.ICON_16;
|
||||
|
||||
if (prototype != null && psiClass != null) {
|
||||
|
||||
PsiMethod existing = psiClass.findMethodBySignature(prototype, false);
|
||||
if (existing != null) {
|
||||
methodIcon = existing.getIcon(Iconable.ICON_FLAG_VISIBILITY);
|
||||
}
|
||||
|
||||
PsiMethod[] superMethods = prototype.findSuperMethods(psiClass);
|
||||
if (superMethods.length > 0) {
|
||||
if (!superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
overrideIcon = AllIcons.General.OverridingMethod;
|
||||
}
|
||||
else {
|
||||
overrideIcon = AllIcons.General.ImplementingMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
return IconManager.getInstance().createRowIcon(methodIcon, overrideIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
|
||||
import com.intellij.java.refactoring.JavaRefactoringBundle;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
@@ -17,12 +19,16 @@ import com.intellij.refactoring.PreviewableRefactoringActionHandler;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class EncapsulateFieldsHandler implements PreviewableRefactoringActionHandler {
|
||||
private static final Logger LOG = Logger.getInstance(EncapsulateFieldsHandler.class);
|
||||
@@ -49,66 +55,106 @@ public class EncapsulateFieldsHandler implements PreviewableRefactoringActionHan
|
||||
*/
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, final PsiElement @NotNull [] elements, DataContext dataContext) {
|
||||
PsiClass aClass = null;
|
||||
final HashSet<PsiField> preselectedFields = new HashSet<>();
|
||||
if (elements.length == 1) {
|
||||
if (elements[0] instanceof PsiClass) {
|
||||
aClass = (PsiClass) elements[0];
|
||||
} else if (elements[0] instanceof PsiField field) {
|
||||
aClass = field.getContainingClass();
|
||||
preselectedFields.add(field);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
for (PsiElement element : elements) {
|
||||
if (!(element instanceof PsiField field)) {
|
||||
return;
|
||||
}
|
||||
if (aClass == null) {
|
||||
aClass = field.getContainingClass();
|
||||
preselectedFields.add(field);
|
||||
}
|
||||
else {
|
||||
if (aClass.equals(field.getContainingClass())) {
|
||||
ReadAction.nonBlocking(() -> {
|
||||
PsiClass aClass = null;
|
||||
Runnable callback = null;
|
||||
final HashSet<PsiField> preselectedFields = new HashSet<>();
|
||||
if (elements.length == 1) {
|
||||
if (elements[0] instanceof PsiClass) {
|
||||
aClass = (PsiClass)elements[0];
|
||||
}
|
||||
else if (elements[0] instanceof PsiField field) {
|
||||
aClass = field.getContainingClass();
|
||||
preselectedFields.add(field);
|
||||
}
|
||||
else {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(
|
||||
JavaRefactoringBundle.message("fields.to.be.refactored.should.belong.to.the.same.class"));
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (PsiElement element : elements) {
|
||||
if (!(element instanceof PsiField field)) {
|
||||
return null;
|
||||
}
|
||||
if (aClass == null) {
|
||||
aClass = field.getContainingClass();
|
||||
preselectedFields.add(field);
|
||||
}
|
||||
else {
|
||||
if (aClass.equals(field.getContainingClass())) {
|
||||
preselectedFields.add(field);
|
||||
}
|
||||
else {
|
||||
callback = () ->
|
||||
{
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(
|
||||
JavaRefactoringBundle.message("fields.to.be.refactored.should.belong.to.the.same.class"));
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
|
||||
};
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG.assertTrue(aClass != null);
|
||||
final List<PsiField> fields = ContainerUtil.filter(aClass.getFields(), field -> !(field instanceof PsiEnumConstant));
|
||||
if (fields.isEmpty()) {
|
||||
CommonRefactoringUtil.showErrorHint(project, CommonDataKeys.EDITOR.getData(dataContext),
|
||||
JavaRefactoringBundle.message("encapsulate.fields.nothing.todo.warning.message"),
|
||||
getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
|
||||
return;
|
||||
}
|
||||
LOG.assertTrue(aClass != null);
|
||||
final List<PsiField> fields = ContainerUtil.filter(aClass.getFields(), field -> !(field instanceof PsiEnumConstant));
|
||||
if (fields.isEmpty()) {
|
||||
callback = () -> {
|
||||
CommonRefactoringUtil.showErrorHint(project, CommonDataKeys.EDITOR.getData(dataContext),
|
||||
JavaRefactoringBundle.message("encapsulate.fields.nothing.todo.warning.message"),
|
||||
getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
|
||||
};
|
||||
return callback;
|
||||
}
|
||||
|
||||
if (aClass.isInterface()) {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(
|
||||
JavaRefactoringBundle.message("encapsulate.fields.refactoring.cannot.be.applied.to.interface"));
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, aClass)) return;
|
||||
|
||||
EncapsulateFieldsDialog dialog = createDialog(project, aClass, preselectedFields);
|
||||
dialog.show();
|
||||
if (aClass.isInterface()) {
|
||||
callback = () -> {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(
|
||||
JavaRefactoringBundle.message("encapsulate.fields.refactoring.cannot.be.applied.to.interface"));
|
||||
Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HelpID.ENCAPSULATE_FIELDS);
|
||||
};
|
||||
return callback;
|
||||
}
|
||||
EncapsulateFieldsDialog.EncapsulateFieldsContainer container = prepare( aClass, preselectedFields);
|
||||
PsiClass finalAClass = aClass;
|
||||
callback = () -> {
|
||||
EncapsulateFieldsDialog dialog = getDialog(project, container);
|
||||
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, finalAClass)) return;
|
||||
dialog.show();
|
||||
};
|
||||
return callback;
|
||||
})
|
||||
.finishOnUiThread(ModalityState.defaultModalityState(), callback -> {
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
})
|
||||
.expireWhen(() -> Arrays.stream(elements)
|
||||
.map(t -> t instanceof PsiField field ? field.getContainingClass() : t)
|
||||
.anyMatch(t -> t != null && !t.isValid()))
|
||||
.submit(AppExecutorUtil.getAppExecutorService());
|
||||
}
|
||||
|
||||
protected static EncapsulateFieldsDialog createDialog(Project project, PsiClass aClass, HashSet<PsiField> preselectedFields) {
|
||||
return new EncapsulateFieldsDialog(project, aClass, preselectedFields, new JavaEncapsulateFieldHelper());
|
||||
@NotNull
|
||||
private static EncapsulateFieldsDialog.EncapsulateFieldsContainer prepare(@NotNull PsiClass aClass,
|
||||
@NotNull Set<PsiField> preselectedFields) {
|
||||
return EncapsulateFieldsDialog.EncapsulateFieldsContainer.create(aClass, preselectedFields, new JavaEncapsulateFieldHelper());
|
||||
}
|
||||
|
||||
protected static EncapsulateFieldsDialog createDialog(@Nullable Project project,
|
||||
@NotNull PsiClass aClass,
|
||||
@NotNull Set<PsiField> preselectedFields) {
|
||||
EncapsulateFieldsDialog.EncapsulateFieldsContainer container = prepare(aClass, preselectedFields);
|
||||
return getDialog(project, container);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static EncapsulateFieldsDialog getDialog(@Nullable Project project,
|
||||
@NotNull EncapsulateFieldsDialog.EncapsulateFieldsContainer container) {
|
||||
return new EncapsulateFieldsDialog(project, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user