From cbbee75ac1e3a9818badbfa4a89a306cda932b80 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 27 May 2010 18:21:11 +0400 Subject: [PATCH] create field from parameter: respect method type parameters ( IDEA-54438) --- .../impl/CreateFieldFromParameterAction.java | 35 +++++++++++++------ .../impl/CreateFieldFromParameterDialog.java | 32 +++++++++++++---- .../src/messages/CodeInsightBundle.properties | 2 +- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java index ccfb73a23796..3ae70612b488 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java @@ -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); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java index b5fa301890ca..64f1f987872e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterDialog.java @@ -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(); + } } diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index 184f610002e8..e697a84eefbd 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -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: