Extract Function: Show possible types for receiver in Extract Function/Introduce Lambda Parameter dialogs
#KT-7578 Fixed
This commit is contained in:
+17
-5
@@ -28,6 +28,7 @@ import kotlin.Unit;
|
|||||||
import kotlin.jvm.functions.Function0;
|
import kotlin.jvm.functions.Function0;
|
||||||
import kotlin.jvm.functions.Function1;
|
import kotlin.jvm.functions.Function1;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.idea.JetFileType;
|
import org.jetbrains.kotlin.idea.JetFileType;
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester;
|
import org.jetbrains.kotlin.idea.core.refactoring.JetNameSuggester;
|
||||||
import org.jetbrains.kotlin.idea.core.refactoring.RefactoringPackage;
|
import org.jetbrains.kotlin.idea.core.refactoring.RefactoringPackage;
|
||||||
@@ -120,8 +121,10 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
protected void init() {
|
protected void init() {
|
||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
|
ExtractableCodeDescriptor extractableCodeDescriptor = originalDescriptor.getDescriptor();
|
||||||
|
|
||||||
functionNameField = new NameSuggestionsField(
|
functionNameField = new NameSuggestionsField(
|
||||||
ArrayUtil.toStringArray(originalDescriptor.getDescriptor().getSuggestedNames()),
|
ArrayUtil.toStringArray(extractableCodeDescriptor.getSuggestedNames()),
|
||||||
project,
|
project,
|
||||||
JetFileType.INSTANCE
|
JetFileType.INSTANCE
|
||||||
);
|
);
|
||||||
@@ -139,7 +142,7 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
boolean enableVisibility = isVisibilitySectionAvailable();
|
boolean enableVisibility = isVisibilitySectionAvailable();
|
||||||
visibilityBox.setEnabled(enableVisibility);
|
visibilityBox.setEnabled(enableVisibility);
|
||||||
if (enableVisibility) {
|
if (enableVisibility) {
|
||||||
visibilityBox.setSelectedItem(originalDescriptor.getDescriptor().getVisibility());
|
visibilityBox.setSelectedItem(extractableCodeDescriptor.getVisibility());
|
||||||
}
|
}
|
||||||
visibilityBox.addItemListener(
|
visibilityBox.addItemListener(
|
||||||
new ItemListener() {
|
new ItemListener() {
|
||||||
@@ -166,7 +169,7 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
doCancelAction();
|
doCancelAction();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
parameterTablePanel.init(originalDescriptor.getDescriptor().getParameters());
|
parameterTablePanel.init(extractableCodeDescriptor.getReceiverParameter(), extractableCodeDescriptor.getParameters());
|
||||||
|
|
||||||
inputParametersPanel.setText("&Parameters");
|
inputParametersPanel.setText("&Parameters");
|
||||||
inputParametersPanel.setLabelFor(parameterTablePanel.getTable());
|
inputParametersPanel.setLabelFor(parameterTablePanel.getTable());
|
||||||
@@ -213,6 +216,7 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
return createNewDescriptor(originalDescriptor.getDescriptor(),
|
return createNewDescriptor(originalDescriptor.getDescriptor(),
|
||||||
getFunctionName(),
|
getFunctionName(),
|
||||||
getVisibility(),
|
getVisibility(),
|
||||||
|
parameterTablePanel.getReceiverInfo(),
|
||||||
parameterTablePanel.getParameterInfos());
|
parameterTablePanel.getParameterInfos());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,12 +229,20 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
@NotNull ExtractableCodeDescriptor originalDescriptor,
|
@NotNull ExtractableCodeDescriptor originalDescriptor,
|
||||||
@NotNull String newName,
|
@NotNull String newName,
|
||||||
@NotNull String newVisibility,
|
@NotNull String newVisibility,
|
||||||
|
@Nullable KotlinParameterTablePanel.ParameterInfo newReceiverInfo,
|
||||||
@NotNull List<KotlinParameterTablePanel.ParameterInfo> newParameterInfos
|
@NotNull List<KotlinParameterTablePanel.ParameterInfo> newParameterInfos
|
||||||
) {
|
) {
|
||||||
Map<Parameter, Parameter> oldToNewParameters = ContainerUtil.newLinkedHashMap();
|
Map<Parameter, Parameter> oldToNewParameters = ContainerUtil.newLinkedHashMap();
|
||||||
for (KotlinParameterTablePanel.ParameterInfo parameterInfo : newParameterInfos) {
|
for (KotlinParameterTablePanel.ParameterInfo parameterInfo : newParameterInfos) {
|
||||||
oldToNewParameters.put(parameterInfo.getOriginalParameter(), parameterInfo.toParameter());
|
oldToNewParameters.put(parameterInfo.getOriginalParameter(), parameterInfo.toParameter());
|
||||||
}
|
}
|
||||||
|
ArrayList<Parameter> newParameters = ContainerUtil.newArrayList(oldToNewParameters.values());
|
||||||
|
|
||||||
|
Parameter originalReceiver = originalDescriptor.getReceiverParameter();
|
||||||
|
Parameter newReceiver = newReceiverInfo != null ? newReceiverInfo.toParameter() : null;
|
||||||
|
if (originalReceiver != null && newReceiver != null) {
|
||||||
|
oldToNewParameters.put(originalReceiver, newReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
ControlFlow controlFlow = originalDescriptor.getControlFlow();
|
ControlFlow controlFlow = originalDescriptor.getControlFlow();
|
||||||
List<OutputValue> outputValues = new ArrayList<OutputValue>(controlFlow.getOutputValues());
|
List<OutputValue> outputValues = new ArrayList<OutputValue>(controlFlow.getOutputValues());
|
||||||
@@ -267,8 +279,8 @@ public class KotlinExtractFunctionDialog extends DialogWrapper {
|
|||||||
originalDescriptor.getOriginalContext(),
|
originalDescriptor.getOriginalContext(),
|
||||||
Collections.singletonList(newName),
|
Collections.singletonList(newName),
|
||||||
newVisibility,
|
newVisibility,
|
||||||
ContainerUtil.newArrayList(oldToNewParameters.values()),
|
newParameters,
|
||||||
originalDescriptor.getReceiverParameter(),
|
newReceiver,
|
||||||
originalDescriptor.getTypeParameters(),
|
originalDescriptor.getTypeParameters(),
|
||||||
replacementMap,
|
replacementMap,
|
||||||
controlFlow
|
controlFlow
|
||||||
|
|||||||
+29
-7
@@ -43,18 +43,21 @@ import javax.swing.table.TableColumn;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class KotlinParameterTablePanel extends JPanel {
|
public class KotlinParameterTablePanel extends JPanel {
|
||||||
public static class ParameterInfo {
|
public static class ParameterInfo {
|
||||||
private final Parameter originalParameter;
|
private final Parameter originalParameter;
|
||||||
|
private final boolean receiver;
|
||||||
private String name;
|
private String name;
|
||||||
private JetType type;
|
private JetType type;
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
public ParameterInfo(Parameter originalParameter) {
|
public ParameterInfo(Parameter originalParameter, boolean receiver) {
|
||||||
this.originalParameter = originalParameter;
|
this.originalParameter = originalParameter;
|
||||||
this.name = originalParameter.getName();
|
this.receiver = receiver;
|
||||||
|
this.name = receiver ? "<receiver>" : originalParameter.getName();
|
||||||
this.type = originalParameter.getParameterType(false);
|
this.type = originalParameter.getParameterType(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +65,10 @@ public class KotlinParameterTablePanel extends JPanel {
|
|||||||
return originalParameter;
|
return originalParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isReceiver() {
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
@@ -100,13 +107,14 @@ public class KotlinParameterTablePanel extends JPanel {
|
|||||||
super(new BorderLayout());
|
super(new BorderLayout());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(List<Parameter> parameters) {
|
public void init(@Nullable Parameter receiver, @NotNull List<Parameter> parameters) {
|
||||||
parameterInfos = KotlinPackage.map(
|
parameterInfos = KotlinPackage.mapTo(
|
||||||
parameters,
|
parameters,
|
||||||
|
receiver != null ? KotlinPackage.arrayListOf(new ParameterInfo(receiver, true)) : new ArrayList<ParameterInfo>(),
|
||||||
new Function1<Parameter, ParameterInfo>() {
|
new Function1<Parameter, ParameterInfo>() {
|
||||||
@Override
|
@Override
|
||||||
public ParameterInfo invoke(Parameter parameter) {
|
public ParameterInfo invoke(Parameter parameter) {
|
||||||
return new ParameterInfo(parameter);
|
return new ParameterInfo(parameter, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -358,7 +366,7 @@ public class KotlinParameterTablePanel extends JPanel {
|
|||||||
case CHECKMARK_COLUMN:
|
case CHECKMARK_COLUMN:
|
||||||
return isEnabled();
|
return isEnabled();
|
||||||
case PARAMETER_NAME_COLUMN:
|
case PARAMETER_NAME_COLUMN:
|
||||||
return isEnabled() && info.isEnabled();
|
return isEnabled() && info.isEnabled() && !info.isReceiver();
|
||||||
case PARAMETER_TYPE_COLUMN:
|
case PARAMETER_TYPE_COLUMN:
|
||||||
return isEnabled() && info.isEnabled() && info.getOriginalParameter().getParameterTypeCandidates(false).size() > 1;
|
return isEnabled() && info.isEnabled() && info.getOriginalParameter().getParameterTypeCandidates(false).size() > 1;
|
||||||
default:
|
default:
|
||||||
@@ -376,13 +384,27 @@ public class KotlinParameterTablePanel extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ParameterInfo getReceiverInfo() {
|
||||||
|
return KotlinPackage.singleOrNull(
|
||||||
|
parameterInfos,
|
||||||
|
new Function1<ParameterInfo, Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean invoke(ParameterInfo info) {
|
||||||
|
return info.isEnabled() && info.isReceiver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public List<ParameterInfo> getParameterInfos() {
|
public List<ParameterInfo> getParameterInfos() {
|
||||||
return KotlinPackage.filter(
|
return KotlinPackage.filter(
|
||||||
parameterInfos,
|
parameterInfos,
|
||||||
new Function1<ParameterInfo, Boolean>() {
|
new Function1<ParameterInfo, Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean invoke(ParameterInfo info) {
|
public Boolean invoke(ParameterInfo info) {
|
||||||
return info.isEnabled();
|
return info.isEnabled() && !info.isReceiver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
+4
-2
@@ -150,7 +150,8 @@ public class KotlinIntroduceParameterDialog private (
|
|||||||
gbConstraints.fill = GridBagConstraints.BOTH
|
gbConstraints.fill = GridBagConstraints.BOTH
|
||||||
panel.add(typeField, gbConstraints)
|
panel.add(typeField, gbConstraints)
|
||||||
|
|
||||||
if (lambdaExtractionDescriptor != null && lambdaExtractionDescriptor.parameters.isNotEmpty()) {
|
if (lambdaExtractionDescriptor != null
|
||||||
|
&& (lambdaExtractionDescriptor.parameters.isNotEmpty() || lambdaExtractionDescriptor.receiverParameter != null)) {
|
||||||
val parameterTablePanel = object : KotlinParameterTablePanel() {
|
val parameterTablePanel = object : KotlinParameterTablePanel() {
|
||||||
override fun onEnterAction() {
|
override fun onEnterAction() {
|
||||||
doOKAction()
|
doOKAction()
|
||||||
@@ -160,7 +161,7 @@ public class KotlinIntroduceParameterDialog private (
|
|||||||
doCancelAction()
|
doCancelAction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parameterTablePanel.init(lambdaExtractionDescriptor!!.parameters)
|
parameterTablePanel.init(lambdaExtractionDescriptor!!.receiverParameter, lambdaExtractionDescriptor.parameters)
|
||||||
|
|
||||||
gbConstraints.insets = Insets(4, 4, 4, 8)
|
gbConstraints.insets = Insets(4, 4, 4, 8)
|
||||||
gbConstraints.gridwidth = 1
|
gbConstraints.gridwidth = 1
|
||||||
@@ -273,6 +274,7 @@ public class KotlinIntroduceParameterDialog private (
|
|||||||
oldDescriptor,
|
oldDescriptor,
|
||||||
chosenName,
|
chosenName,
|
||||||
"",
|
"",
|
||||||
|
parameterTablePanel?.getReceiverInfo(),
|
||||||
parameterTablePanel?.getParameterInfos() ?: listOf()
|
parameterTablePanel?.getParameterInfos() ?: listOf()
|
||||||
)
|
)
|
||||||
val options = ExtractionGeneratorOptions.DEFAULT.copy(
|
val options = ExtractionGeneratorOptions.DEFAULT.copy(
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// PARAM_DESCRIPTOR: internal fun Bar.foo(): kotlin.Unit defined in root package
|
||||||
|
// PARAM_TYPES: Bar, Foo, kotlin.Any
|
||||||
|
|
||||||
|
open class Foo
|
||||||
|
class Bar : Foo()
|
||||||
|
|
||||||
|
fun Bar.foo() {
|
||||||
|
<selection>toString()</selection>
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// PARAM_DESCRIPTOR: internal fun Bar.foo(): kotlin.Unit defined in root package
|
||||||
|
// PARAM_TYPES: Bar, Foo, kotlin.Any
|
||||||
|
|
||||||
|
open class Foo
|
||||||
|
class Bar : Foo()
|
||||||
|
|
||||||
|
fun Bar.foo() {
|
||||||
|
__dummyTestFun__()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Bar.__dummyTestFun__() {
|
||||||
|
toString()
|
||||||
|
}
|
||||||
+6
@@ -1571,6 +1571,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
|||||||
doExtractFunctionTest(fileName);
|
doExtractFunctionTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("receiverCandidateTypes.kt")
|
||||||
|
public void testReceiverCandidateTypes() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/receiverCandidateTypes.kt");
|
||||||
|
doExtractFunctionTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeHierarchy1.kt")
|
@TestMetadata("typeHierarchy1.kt")
|
||||||
public void testTypeHierarchy1() throws Exception {
|
public void testTypeHierarchy1() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/typeHierarchy1.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/candidateTypes/typeHierarchy1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user