mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
create field from parameter: respect method type parameters ( IDEA-54438)
This commit is contained in:
+24
-11
@@ -32,9 +32,11 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -51,11 +53,19 @@ public class CreateFieldFromParameterAction implements IntentionAction {
|
||||
private String myName = "";
|
||||
|
||||
@Nullable
|
||||
private static PsiType getType(final PsiParameter parameter) {
|
||||
private static PsiType[] getTypes(final PsiParameter parameter) {
|
||||
if (parameter == null) return null;
|
||||
PsiType type = parameter.getType();
|
||||
if (type instanceof PsiEllipsisType) type = ((PsiEllipsisType)type).toArrayType();
|
||||
return type;
|
||||
final PsiClass psiClass = PsiUtil.resolveClassInType(type);
|
||||
if (psiClass instanceof PsiTypeParameter && parameter.getDeclarationScope() == ((PsiTypeParameter)psiClass).getOwner()) {
|
||||
final PsiReferenceList extendsList = psiClass.getExtendsList();
|
||||
LOG.assertTrue(extendsList != null);
|
||||
final PsiClassType[] types = extendsList.getReferencedTypes();
|
||||
if (types.length > 0) return types;
|
||||
return new PsiType[]{PsiType.getJavaLangObject(parameter.getManager(), GlobalSearchScope.allScope(parameter.getProject()))};
|
||||
}
|
||||
return new PsiType[]{type};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -67,15 +77,15 @@ public class CreateFieldFromParameterAction implements IntentionAction {
|
||||
PsiParameter myParameter = findParameterAtCursor(file, editor);
|
||||
if (myParameter == null) return false;
|
||||
myName = myParameter.getName();
|
||||
final PsiType type = getType(myParameter);
|
||||
final PsiType[] types = getTypes(myParameter);
|
||||
PsiClass targetClass = PsiTreeUtil.getParentOfType(myParameter, PsiClass.class);
|
||||
return
|
||||
myParameter.isValid()
|
||||
&& myParameter.getDeclarationScope() instanceof PsiMethod
|
||||
&& ((PsiMethod)myParameter.getDeclarationScope()).getBody() != null
|
||||
&& myParameter.getManager().isInProject(myParameter)
|
||||
&& type != null
|
||||
&& type.isValid()
|
||||
&& types != null
|
||||
&& types[0].isValid()
|
||||
&& !isParameterAssignedToField(myParameter)
|
||||
&& targetClass != null
|
||||
&& !targetClass.isInterface()
|
||||
@@ -125,21 +135,21 @@ public class CreateFieldFromParameterAction implements IntentionAction {
|
||||
if (!CodeInsightUtilBase.prepareFileForWrite(myParameter.getContainingFile())) return;
|
||||
|
||||
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
|
||||
final PsiType type = getType(myParameter);
|
||||
final PsiType[] types = getTypes(myParameter);
|
||||
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
|
||||
final String parameterName = myParameter.getName();
|
||||
String propertyName = styleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER);
|
||||
|
||||
String fieldNameToCalc;
|
||||
boolean isFinalToCalc;
|
||||
|
||||
PsiType type;
|
||||
final PsiClass targetClass = PsiTreeUtil.getParentOfType(myParameter, PsiClass.class);
|
||||
final PsiMethod method = (PsiMethod)myParameter.getDeclarationScope();
|
||||
|
||||
final boolean isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
|
||||
|
||||
VariableKind kind = isMethodStatic ? VariableKind.STATIC_FIELD : VariableKind.FIELD;
|
||||
SuggestedNameInfo suggestedNameInfo = styleManager.suggestVariableName(kind, propertyName, null, type);
|
||||
SuggestedNameInfo suggestedNameInfo = styleManager.suggestVariableName(kind, propertyName, null, types[0]);
|
||||
String[] names = suggestedNameInfo.names;
|
||||
|
||||
if (isInteractive) {
|
||||
@@ -158,11 +168,12 @@ public class CreateFieldFromParameterAction implements IntentionAction {
|
||||
CreateFieldFromParameterDialog dialog = new CreateFieldFromParameterDialog(
|
||||
project,
|
||||
names,
|
||||
type.getCanonicalText(), targetClass, myBeFinal);
|
||||
targetClass, myBeFinal, types);
|
||||
dialog.show();
|
||||
|
||||
if (!dialog.isOK()) return;
|
||||
|
||||
type = dialog.getType();
|
||||
if (type == null) return;
|
||||
fieldNameToCalc = dialog.getEnteredName();
|
||||
isFinalToCalc = dialog.isDeclareFinal();
|
||||
|
||||
@@ -171,17 +182,19 @@ public class CreateFieldFromParameterAction implements IntentionAction {
|
||||
else {
|
||||
isFinalToCalc = !isMethodStatic;
|
||||
fieldNameToCalc = names[0];
|
||||
type= types[0];
|
||||
}
|
||||
|
||||
final boolean isFinal = isFinalToCalc;
|
||||
final String fieldName = fieldNameToCalc;
|
||||
final PsiType fieldType = type;
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
PsiManager psiManager = PsiManager.getInstance(project);
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
|
||||
|
||||
PsiField field = factory.createField(fieldName, type);
|
||||
PsiField field = factory.createField(fieldName, fieldType);
|
||||
PsiModifierList modifierList = field.getModifierList();
|
||||
modifierList.setModifierProperty(PsiModifier.STATIC, isMethodStatic);
|
||||
modifierList.setModifierProperty(PsiModifier.FINAL, isFinal);
|
||||
|
||||
+26
-6
@@ -24,8 +24,11 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.refactoring.ui.TypeSelector;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
@@ -35,19 +38,23 @@ import java.awt.event.*;
|
||||
class CreateFieldFromParameterDialog extends DialogWrapper {
|
||||
private final Project myProject;
|
||||
private final String[] myNames;
|
||||
private final String myType;
|
||||
private final PsiType[] myTypes;
|
||||
private final PsiClass myTargetClass;
|
||||
private final boolean myFieldMayBeFinal;
|
||||
|
||||
private JComponent myNameField;
|
||||
private JCheckBox myCbFinal;
|
||||
private static final @NonNls String PROPERTY_NAME = "CREATE_FIELD_FROM_PARAMETER_DECLARE_FINAL";
|
||||
private TypeSelector myTypeSelector;
|
||||
|
||||
public CreateFieldFromParameterDialog(Project project, String[] names, String type, PsiClass targetClass, final boolean fieldMayBeFinal) {
|
||||
public CreateFieldFromParameterDialog(Project project,
|
||||
String[] names,
|
||||
PsiClass targetClass,
|
||||
final boolean fieldMayBeFinal, PsiType... types) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
myNames = names;
|
||||
myType = type;
|
||||
myTypes = types;
|
||||
myTargetClass = targetClass;
|
||||
myFieldMayBeFinal = fieldMayBeFinal;
|
||||
|
||||
@@ -175,13 +182,21 @@ class CreateFieldFromParameterDialog extends DialogWrapper {
|
||||
gbConstraints.anchor = GridBagConstraints.EAST;
|
||||
gbConstraints.fill = GridBagConstraints.BOTH;
|
||||
|
||||
gbConstraints.gridwidth = 2;
|
||||
gbConstraints.gridwidth = 1;
|
||||
gbConstraints.weightx = 1;
|
||||
gbConstraints.weighty = 1;
|
||||
gbConstraints.gridx = 0;
|
||||
gbConstraints.gridy = 0;
|
||||
JLabel type = new JLabel(CodeInsightBundle.message("dialog.create.field.from.parameter.field.type.label", myType));
|
||||
panel.add(type, gbConstraints);
|
||||
final JLabel typeLabel = new JLabel(CodeInsightBundle.message("dialog.create.field.from.parameter.field.type.label"));
|
||||
panel.add(typeLabel, gbConstraints);
|
||||
gbConstraints.gridx = 1;
|
||||
if (myTypes.length > 1) {
|
||||
myTypeSelector = new TypeSelector();
|
||||
myTypeSelector.setTypes(myTypes);
|
||||
} else {
|
||||
myTypeSelector = new TypeSelector(myTypes[0]);
|
||||
}
|
||||
panel.add(myTypeSelector.getComponent(), gbConstraints);
|
||||
|
||||
gbConstraints.gridwidth = 1;
|
||||
gbConstraints.weightx = 0;
|
||||
@@ -249,4 +264,9 @@ class CreateFieldFromParameterDialog extends DialogWrapper {
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myNameField;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiType getType() {
|
||||
return myTypeSelector.getSelectedType();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ intention.color.chooser.dialog=Choose Color
|
||||
dialog.create.field.from.parameter.title=Create Field
|
||||
dialog.create.field.from.parameter.already.exists.text=Use existing field {0}?
|
||||
dialog.create.field.from.parameter.already.exists.title=Field Already Exists
|
||||
dialog.create.field.from.parameter.field.type.label=Field of type {0}
|
||||
dialog.create.field.from.parameter.field.type.label=Field of type:
|
||||
dialog.create.field.from.parameter.field.name.label=Name:
|
||||
dialog.create.field.from.parameter.declare.final.checkbox=Declare &final
|
||||
dialog.create.class.destination.package.label=Destination package:
|
||||
|
||||
Reference in New Issue
Block a user