J2K: JetChangeSignatureDialog
This commit is contained in:
+336
-437
@@ -14,525 +14,424 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature.ui;
|
package org.jetbrains.kotlin.idea.refactoring.changeSignature.ui
|
||||||
|
|
||||||
import com.intellij.openapi.editor.Document;
|
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
import com.intellij.openapi.editor.colors.EditorFontType
|
||||||
import com.intellij.openapi.editor.colors.EditorFontType;
|
import com.intellij.openapi.editor.event.DocumentAdapter
|
||||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
import com.intellij.openapi.editor.event.DocumentEvent
|
||||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
import com.intellij.openapi.fileTypes.LanguageFileType
|
||||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
import com.intellij.openapi.options.ConfigurationException
|
||||||
import com.intellij.openapi.options.ConfigurationException;
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.ui.VerticalFlowLayout
|
||||||
import com.intellij.openapi.ui.VerticalFlowLayout;
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.psi.JavaPsiFacade
|
||||||
import com.intellij.psi.JavaPsiFacade;
|
import com.intellij.psi.PsiCodeFragment
|
||||||
import com.intellij.psi.PsiCodeFragment;
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
import com.intellij.refactoring.changeSignature.CallerChooserBase
|
||||||
import com.intellij.refactoring.changeSignature.CallerChooserBase;
|
import com.intellij.refactoring.changeSignature.ChangeSignatureDialogBase
|
||||||
import com.intellij.refactoring.changeSignature.ChangeSignatureDialogBase;
|
import com.intellij.refactoring.changeSignature.MethodDescriptor
|
||||||
import com.intellij.refactoring.changeSignature.MethodDescriptor;
|
import com.intellij.refactoring.changeSignature.ParameterTableModelItemBase
|
||||||
import com.intellij.refactoring.changeSignature.ParameterTableModelItemBase;
|
import com.intellij.refactoring.ui.ComboBoxVisibilityPanel
|
||||||
import com.intellij.refactoring.ui.ComboBoxVisibilityPanel;
|
import com.intellij.refactoring.ui.VisibilityPanelBase
|
||||||
import com.intellij.refactoring.ui.VisibilityPanelBase;
|
import com.intellij.ui.DottedBorder
|
||||||
import com.intellij.ui.DottedBorder;
|
import com.intellij.ui.EditorTextField
|
||||||
import com.intellij.ui.EditorTextField;
|
import com.intellij.ui.components.JBLabel
|
||||||
import com.intellij.ui.components.JBLabel;
|
import com.intellij.ui.treeStructure.Tree
|
||||||
import com.intellij.ui.treeStructure.Tree;
|
import com.intellij.util.Consumer
|
||||||
import com.intellij.util.Consumer;
|
import com.intellij.util.Function
|
||||||
import com.intellij.util.Function;
|
import com.intellij.util.IJSwingUtilities
|
||||||
import com.intellij.util.IJSwingUtilities;
|
import com.intellij.util.ui.UIUtil
|
||||||
import com.intellij.util.ui.ColumnInfo;
|
import com.intellij.util.ui.table.JBTableRow
|
||||||
import com.intellij.util.ui.UIUtil;
|
import com.intellij.util.ui.table.JBTableRowEditor
|
||||||
import com.intellij.util.ui.table.JBTableRow;
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import com.intellij.util.ui.table.JBTableRowEditor;
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.idea.JetFileType
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility;
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMethodDescriptor.Kind
|
||||||
import org.jetbrains.kotlin.idea.JetFileType;
|
import org.jetbrains.kotlin.psi.JetExpressionCodeFragment
|
||||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle;
|
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*;
|
import org.jetbrains.kotlin.psi.JetTypeCodeFragment
|
||||||
import org.jetbrains.kotlin.psi.JetExpression;
|
import org.jetbrains.kotlin.types.JetType
|
||||||
import org.jetbrains.kotlin.psi.JetExpressionCodeFragment;
|
import java.awt.BorderLayout
|
||||||
import org.jetbrains.kotlin.psi.JetTypeCodeFragment;
|
import java.awt.Font
|
||||||
import org.jetbrains.kotlin.types.JetType;
|
import java.awt.Toolkit
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.JetMethodDescriptor.Kind;
|
import java.awt.event.ItemEvent
|
||||||
|
import java.awt.event.ItemListener
|
||||||
|
import java.util.ArrayList
|
||||||
|
import javax.swing.*
|
||||||
|
|
||||||
import javax.swing.*;
|
public class JetChangeSignatureDialog(
|
||||||
import java.awt.*;
|
project: Project,
|
||||||
import java.awt.event.ItemEvent;
|
methodDescriptor: JetMethodDescriptor,
|
||||||
import java.awt.event.ItemListener;
|
context: PsiElement,
|
||||||
import java.awt.event.MouseEvent;
|
private val commandName: String?
|
||||||
import java.util.ArrayList;
|
) : ChangeSignatureDialogBase<
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory;
|
|
||||||
|
|
||||||
public class JetChangeSignatureDialog extends ChangeSignatureDialogBase<
|
|
||||||
JetParameterInfo,
|
JetParameterInfo,
|
||||||
PsiElement,
|
PsiElement,
|
||||||
Visibility,
|
Visibility,
|
||||||
JetMethodDescriptor,
|
JetMethodDescriptor,
|
||||||
ParameterTableModelItemBase<JetParameterInfo>,
|
ParameterTableModelItemBase<JetParameterInfo>,
|
||||||
JetCallableParameterTableModel
|
JetCallableParameterTableModel>(project, methodDescriptor, false, context) {
|
||||||
>
|
override fun getFileType() = JetFileType.INSTANCE
|
||||||
{
|
|
||||||
private final String commandName;
|
|
||||||
|
|
||||||
public JetChangeSignatureDialog(Project project, @NotNull JetMethodDescriptor methodDescriptor, PsiElement context, String commandName) {
|
override fun createParametersInfoModel(descriptor: JetMethodDescriptor) = createParametersInfoModel(descriptor, myDefaultValueContext)
|
||||||
super(project, methodDescriptor, false, context);
|
|
||||||
this.commandName = commandName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
override fun createReturnTypeCodeFragment() = createReturnTypeCodeFragment(myProject, myMethod)
|
||||||
protected LanguageFileType getFileType() {
|
|
||||||
return JetFileType.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public fun getReturnType(): JetType? = getType(myReturnTypeCodeFragment as JetTypeCodeFragment?)
|
||||||
protected JetCallableParameterTableModel createParametersInfoModel(JetMethodDescriptor descriptor) {
|
|
||||||
return createParametersInfoModel(descriptor, myDefaultValueContext);
|
private val parametersTableModel: JetCallableParameterTableModel get() = super.myParametersTableModel
|
||||||
}
|
|
||||||
|
override fun getRowPresentation(item: ParameterTableModelItemBase<JetParameterInfo>, selected: Boolean, focused: Boolean): JComponent? {
|
||||||
|
val panel = JPanel(BorderLayout())
|
||||||
|
|
||||||
@NotNull
|
val valOrVar: String
|
||||||
private static JetCallableParameterTableModel createParametersInfoModel(JetMethodDescriptor descriptor, PsiElement defaultValueContext) {
|
if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) {
|
||||||
switch (descriptor.getKind()) {
|
valOrVar = when (item.parameter.valOrVar) {
|
||||||
case FUNCTION:
|
JetValVar.None -> " "
|
||||||
return new JetFunctionParameterTableModel(descriptor, defaultValueContext);
|
JetValVar.Val -> "val "
|
||||||
case PRIMARY_CONSTRUCTOR:
|
JetValVar.Var -> "var "
|
||||||
return new JetPrimaryConstructorParameterTableModel(descriptor, defaultValueContext);
|
|
||||||
case SECONDARY_CONSTRUCTOR:
|
|
||||||
return new JetSecondaryConstructorParameterTableModel(descriptor, defaultValueContext);
|
|
||||||
}
|
|
||||||
throw new AssertionError("Invalid kind: " + descriptor.getKind());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected PsiCodeFragment createReturnTypeCodeFragment() {
|
|
||||||
return createReturnTypeCodeFragment(myProject, myMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static PsiCodeFragment createReturnTypeCodeFragment(@NotNull Project project, @NotNull JetMethodDescriptor method) {
|
|
||||||
return JetPsiFactory(project).createTypeCodeFragment(
|
|
||||||
ChangeSignaturePackage.renderOriginalReturnType(method), method.getBaseDeclaration()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public JetType getReturnType() {
|
|
||||||
return getType((JetTypeCodeFragment) myReturnTypeCodeFragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JetType getType(JetTypeCodeFragment typeCodeFragment) {
|
|
||||||
return typeCodeFragment != null ? typeCodeFragment.getType() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JComponent getRowPresentation(ParameterTableModelItemBase<JetParameterInfo> item, boolean selected, boolean focused) {
|
|
||||||
JPanel panel = new JPanel(new BorderLayout());
|
|
||||||
String valOrVar = "";
|
|
||||||
|
|
||||||
if (myMethod.getKind() == Kind.PRIMARY_CONSTRUCTOR) {
|
|
||||||
switch (item.parameter.getValOrVar()) {
|
|
||||||
case None:
|
|
||||||
valOrVar = " ";
|
|
||||||
break;
|
|
||||||
case Val:
|
|
||||||
valOrVar = "val ";
|
|
||||||
break;
|
|
||||||
case Var:
|
|
||||||
valOrVar = "var ";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
valOrVar = ""
|
||||||
|
}
|
||||||
|
|
||||||
String parameterName = getPresentationName(item);
|
val parameterName = getPresentationName(item)
|
||||||
String typeText = item.typeCodeFragment.getText();
|
val typeText = item.typeCodeFragment.getText()
|
||||||
String defaultValue = item.defaultValueCodeFragment.getText();
|
val defaultValue = item.defaultValueCodeFragment.getText()
|
||||||
String separator = StringUtil.repeatSymbol(' ', getParamNamesMaxLength() - parameterName.length() + 1);
|
val separator = StringUtil.repeatSymbol(' ', getParamNamesMaxLength() - parameterName.length() + 1)
|
||||||
String text = valOrVar + parameterName + ":" + separator + typeText;
|
var text = "$valOrVar$parameterName:$separator$typeText"
|
||||||
|
|
||||||
if (StringUtil.isNotEmpty(defaultValue))
|
if (StringUtil.isNotEmpty(defaultValue)) {
|
||||||
text += " // default value = " + defaultValue;
|
text += " // default value = $defaultValue"
|
||||||
|
}
|
||||||
|
|
||||||
EditorTextField field = new EditorTextField(" " + text, getProject(), getFileType()) {
|
val field = object : EditorTextField(" $text", getProject(), getFileType()) {
|
||||||
@Override
|
override fun shouldHaveBorder() = false
|
||||||
protected boolean shouldHaveBorder() {
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
|
val plainFont = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN)
|
||||||
font = new Font(font.getFontName(), font.getStyle(), 12);
|
field.setFont(Font(plainFont.getFontName(), plainFont.getStyle(), 12))
|
||||||
field.setFont(font);
|
|
||||||
|
|
||||||
if (selected && focused) {
|
if (selected && focused) {
|
||||||
panel.setBackground(UIUtil.getTableSelectionBackground());
|
panel.setBackground(UIUtil.getTableSelectionBackground())
|
||||||
field.setAsRendererWithSelection(UIUtil.getTableSelectionBackground(), UIUtil.getTableSelectionForeground());
|
field.setAsRendererWithSelection(UIUtil.getTableSelectionBackground(), UIUtil.getTableSelectionForeground())
|
||||||
} else {
|
}
|
||||||
panel.setBackground(UIUtil.getTableBackground());
|
else {
|
||||||
|
panel.setBackground(UIUtil.getTableBackground())
|
||||||
if (selected && !focused) {
|
if (selected && !focused) {
|
||||||
panel.setBorder(new DottedBorder(UIUtil.getTableForeground()));
|
panel.setBorder(DottedBorder(UIUtil.getTableForeground()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panel.add(field, BorderLayout.WEST);
|
panel.add(field, BorderLayout.WEST)
|
||||||
return panel;
|
|
||||||
|
return panel
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPresentationName(ParameterTableModelItemBase<JetParameterInfo> item) {
|
private fun getPresentationName(item: ParameterTableModelItemBase<JetParameterInfo>): String {
|
||||||
JetParameterInfo parameter = item.parameter;
|
val parameter = item.parameter
|
||||||
if (parameter == null) return null;
|
return if (parameter == parametersTableModel.getReceiver()) "<receiver>" else parameter.getName()
|
||||||
if (parameter == myParametersTableModel.getReceiver()) return "<receiver>";
|
|
||||||
return parameter.getName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getColumnTextMaxLength(Function<ParameterTableModelItemBase<JetParameterInfo>, String> nameFunction) {
|
private fun getColumnTextMaxLength(nameFunction: Function1<ParameterTableModelItemBase<JetParameterInfo>, String?>) =
|
||||||
int len = 0;
|
parametersTableModel.getItems().map { nameFunction(it)?.length() ?: 0 }.max() ?: 0
|
||||||
for (ParameterTableModelItemBase<JetParameterInfo> item : myParametersTableModel.getItems()) {
|
|
||||||
String text = nameFunction.fun(item);
|
private fun getParamNamesMaxLength() = getColumnTextMaxLength { getPresentationName(it) }
|
||||||
len = Math.max(len, text == null ? 0 : text.length());
|
|
||||||
}
|
private fun getTypesMaxLength() = getColumnTextMaxLength { it.typeCodeFragment?.getText() }
|
||||||
return len;
|
|
||||||
|
private fun getDefaultValuesMaxLength() = getColumnTextMaxLength { it.defaultValueCodeFragment?.getText() }
|
||||||
|
|
||||||
|
override fun isListTableViewSupported() = true
|
||||||
|
|
||||||
|
override fun isEmptyRow(row: ParameterTableModelItemBase<JetParameterInfo>): Boolean {
|
||||||
|
if (!row.parameter.getName().isNullOrEmpty()) return false
|
||||||
|
if (!row.parameter.getTypeText().isNullOrEmpty()) return false
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getParamNamesMaxLength() {
|
override fun createCallerChooser(title: String, treeToReuse: Tree, callback: Consumer<Set<PsiElement>>) =
|
||||||
return getColumnTextMaxLength(new Function<ParameterTableModelItemBase<JetParameterInfo>, String>() {
|
throw UnsupportedOperationException()
|
||||||
@Override
|
|
||||||
public String fun(ParameterTableModelItemBase<JetParameterInfo> item) {
|
|
||||||
return getPresentationName(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getTypesMaxLength() {
|
override fun getTableEditor(table: JTable, item: ParameterTableModelItemBase<JetParameterInfo>): JBTableRowEditor? {
|
||||||
return getColumnTextMaxLength(new Function<ParameterTableModelItemBase<JetParameterInfo>, String>() {
|
return object : JBTableRowEditor() {
|
||||||
@Override
|
private val components = ArrayList<JComponent>()
|
||||||
public String fun(ParameterTableModelItemBase<JetParameterInfo> item) {
|
private val nameEditor = EditorTextField(item.parameter.getName(), getProject(), getFileType())
|
||||||
return item.typeCodeFragment == null ? null : item.typeCodeFragment.getText();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getDefaultValuesMaxLength() {
|
private fun updateNameEditor() {
|
||||||
return getColumnTextMaxLength(new Function<ParameterTableModelItemBase<JetParameterInfo>, String>() {
|
nameEditor.setEnabled(item.parameter != parametersTableModel.getReceiver())
|
||||||
@Override
|
|
||||||
public String fun(ParameterTableModelItemBase<JetParameterInfo> item) {
|
|
||||||
return item.defaultValueCodeFragment == null ? null : item.defaultValueCodeFragment.getText();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isListTableViewSupported() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isEmptyRow(ParameterTableModelItemBase<JetParameterInfo> row) {
|
|
||||||
if (!StringUtil.isEmpty(row.parameter.getName())) return false;
|
|
||||||
if (!StringUtil.isEmpty(row.parameter.getTypeText())) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected CallerChooserBase<PsiElement> createCallerChooser(String title, Tree treeToReuse, Consumer<Set<PsiElement>> callback) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected JBTableRowEditor getTableEditor(final JTable t, final ParameterTableModelItemBase<JetParameterInfo> item) {
|
|
||||||
return new JBTableRowEditor() {
|
|
||||||
private final List<JComponent> components = new ArrayList<JComponent>();
|
|
||||||
private final EditorTextField nameEditor = new EditorTextField(item.parameter.getName(), getProject(), getFileType());;
|
|
||||||
|
|
||||||
private void updateNameEditor() {
|
|
||||||
nameEditor.setEnabled(item.parameter != myParametersTableModel.getReceiver());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDefaultColumnEnabled() {
|
private fun isDefaultColumnEnabled() =
|
||||||
return item.parameter.getIsNewParameter() && item.parameter != myMethod.getReceiver();
|
item.parameter.isNewParameter && item.parameter != myMethod.receiver
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
override fun prepareEditor(table: JTable, row: Int) {
|
||||||
public void prepareEditor(JTable table, final int row) {
|
setLayout(BoxLayout(this, BoxLayout.X_AXIS))
|
||||||
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
var column = 0
|
||||||
int column = 0;
|
|
||||||
|
|
||||||
for (ColumnInfo columnInfo : myParametersTableModel.getColumnInfos()) {
|
for (columnInfo in parametersTableModel.getColumnInfos()) {
|
||||||
JPanel panel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
|
val panel = JPanel(VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false))
|
||||||
EditorTextField editor = null;
|
val editor: EditorTextField?
|
||||||
JComponent component;
|
val component: JComponent
|
||||||
final int columnFinal = column;
|
val columnFinal = column
|
||||||
|
|
||||||
if (JetCallableParameterTableModel.isTypeColumn(columnInfo)) {
|
if (JetCallableParameterTableModel.isTypeColumn(columnInfo)) {
|
||||||
Document document = PsiDocumentManager.getInstance(getProject()).getDocument(item.typeCodeFragment);
|
val document = PsiDocumentManager.getInstance(getProject()).getDocument(item.typeCodeFragment)
|
||||||
component = editor = new EditorTextField(document, getProject(), getFileType());
|
editor = EditorTextField(document, getProject(), getFileType())
|
||||||
|
component = editor
|
||||||
}
|
}
|
||||||
else if (JetCallableParameterTableModel.isNameColumn(columnInfo)) {
|
else if (JetCallableParameterTableModel.isNameColumn(columnInfo)) {
|
||||||
component = editor = nameEditor;
|
editor = nameEditor
|
||||||
updateNameEditor();
|
component = editor
|
||||||
|
updateNameEditor()
|
||||||
}
|
}
|
||||||
else if (JetCallableParameterTableModel.isDefaultValueColumn(columnInfo) && isDefaultColumnEnabled()) {
|
else if (JetCallableParameterTableModel.isDefaultValueColumn(columnInfo) && isDefaultColumnEnabled()) {
|
||||||
Document document = PsiDocumentManager.getInstance(getProject()).getDocument(item.defaultValueCodeFragment);
|
val document = PsiDocumentManager.getInstance(getProject()).getDocument(item.defaultValueCodeFragment)
|
||||||
component = editor = new EditorTextField(document, getProject(), getFileType());
|
editor = EditorTextField(document, getProject(), getFileType())
|
||||||
|
component = editor
|
||||||
}
|
}
|
||||||
else if (JetPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo)) {
|
else if (JetPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo)) {
|
||||||
JComboBox comboBox = new JComboBox(JetValVar.values());
|
val comboBox = JComboBox(JetValVar.values())
|
||||||
comboBox.setSelectedItem(item.parameter.getValOrVar());
|
comboBox.setSelectedItem(item.parameter.valOrVar)
|
||||||
comboBox.addItemListener(new ItemListener() {
|
comboBox.addItemListener(object : ItemListener {
|
||||||
@Override
|
override fun itemStateChanged(e: ItemEvent) {
|
||||||
public void itemStateChanged(@NotNull ItemEvent e) {
|
parametersTableModel.setValueAtWithoutUpdate(e.getItem(), row, columnFinal)
|
||||||
myParametersTableModel.setValueAtWithoutUpdate(e.getItem(), row, columnFinal);
|
updateSignature()
|
||||||
updateSignature();
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
component = comboBox;
|
component = comboBox
|
||||||
|
editor = null
|
||||||
}
|
}
|
||||||
else if (JetFunctionParameterTableModel.isReceiverColumn(columnInfo)) {
|
else if (JetFunctionParameterTableModel.isReceiverColumn(columnInfo)) {
|
||||||
JCheckBox checkBox = new JCheckBox();
|
val checkBox = JCheckBox()
|
||||||
checkBox.setSelected(myParametersTableModel.getReceiver() == item.parameter);
|
checkBox.setSelected(parametersTableModel.getReceiver() == item.parameter)
|
||||||
checkBox.addItemListener(
|
checkBox.addItemListener {
|
||||||
new ItemListener() {
|
val newReceiver = if (it.getStateChange() == ItemEvent.SELECTED) item.parameter else null
|
||||||
@Override
|
(parametersTableModel as JetFunctionParameterTableModel).setReceiver(newReceiver)
|
||||||
public void itemStateChanged(@NotNull ItemEvent e) {
|
updateSignature()
|
||||||
((JetFunctionParameterTableModel)myParametersTableModel).setReceiver(
|
updateNameEditor()
|
||||||
e.getStateChange() == ItemEvent.SELECTED ? item.parameter : null
|
}
|
||||||
);
|
component = checkBox
|
||||||
updateSignature();
|
editor = null
|
||||||
updateNameEditor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
component = checkBox;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue
|
||||||
|
|
||||||
JBLabel label = new JBLabel(columnInfo.getName(), UIUtil.ComponentStyle.SMALL);
|
val label = JBLabel(columnInfo.getName(), UIUtil.ComponentStyle.SMALL)
|
||||||
panel.add(label);
|
panel.add(label)
|
||||||
|
|
||||||
if (editor != null) {
|
if (editor != null) {
|
||||||
editor.addDocumentListener(new DocumentAdapter() {
|
editor.addDocumentListener(
|
||||||
@Override
|
object : DocumentAdapter() {
|
||||||
public void documentChanged(DocumentEvent e) {
|
override fun documentChanged(e: DocumentEvent?) {
|
||||||
fireDocumentChanged(e, columnFinal);
|
fireDocumentChanged(e, columnFinal)
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
editor.setPreferredWidth(t.getWidth() / myParametersTableModel.getColumnCount());
|
)
|
||||||
|
editor.setPreferredWidth(table.getWidth() / parametersTableModel.getColumnCount())
|
||||||
}
|
}
|
||||||
|
|
||||||
components.add(component);
|
components.add(component)
|
||||||
panel.add(component);
|
panel.add(component)
|
||||||
add(panel);
|
add(panel)
|
||||||
IJSwingUtilities.adjustComponentsOnMac(label, component);
|
IJSwingUtilities.adjustComponentsOnMac(label, component)
|
||||||
column++;
|
column++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getValue(): JBTableRow {
|
||||||
public JBTableRow getValue() {
|
return object : JBTableRow {
|
||||||
return new JBTableRow() {
|
override fun getValueAt(column: Int): Any? {
|
||||||
@Override
|
val columnInfo = parametersTableModel.getColumnInfos()[column]
|
||||||
public Object getValueAt(int column) {
|
|
||||||
ColumnInfo columnInfo = myParametersTableModel.getColumnInfos()[column];
|
|
||||||
|
|
||||||
if (JetPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo))
|
if (JetPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo))
|
||||||
return ((JComboBox) components.get(column)).getSelectedItem();
|
return (components.get(column) as JComboBox).getSelectedItem()
|
||||||
else if (JetCallableParameterTableModel.isTypeColumn(columnInfo))
|
else if (JetCallableParameterTableModel.isTypeColumn(columnInfo))
|
||||||
return item.typeCodeFragment;
|
return item.typeCodeFragment
|
||||||
else if (JetCallableParameterTableModel.isNameColumn(columnInfo))
|
else if (JetCallableParameterTableModel.isNameColumn(columnInfo))
|
||||||
return ((EditorTextField) components.get(column)).getText();
|
return (components.get(column) as EditorTextField).getText()
|
||||||
else if (JetCallableParameterTableModel.isDefaultValueColumn(columnInfo))
|
else if (JetCallableParameterTableModel.isDefaultValueColumn(columnInfo))
|
||||||
return item.defaultValueCodeFragment;
|
return item.defaultValueCodeFragment
|
||||||
else
|
else
|
||||||
return null;
|
return null
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getColumnWidth(int letters) {
|
private fun getColumnWidth(letters: Int): Int {
|
||||||
Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
|
var font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN)
|
||||||
font = new Font(font.getFontName(), font.getStyle(), 12);
|
font = Font(font.getFontName(), font.getStyle(), 12)
|
||||||
return letters * Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W");
|
return letters * Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W")
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getEditorIndex(int x) {
|
private fun getEditorIndex(x: Int): Int {
|
||||||
int[] columnLetters = isDefaultColumnEnabled() ?
|
@suppress("NAME_SHADOWING") var x = x
|
||||||
new int[] { 4, getParamNamesMaxLength(), getTypesMaxLength(), getDefaultValuesMaxLength() } :
|
|
||||||
new int[] { 4, getParamNamesMaxLength(), getTypesMaxLength() };
|
|
||||||
int columnIndex = 0;
|
|
||||||
|
|
||||||
for (int i = myMethod.getKind() == Kind.PRIMARY_CONSTRUCTOR ? 0 : 1; i < columnLetters.length; i ++) {
|
val columnLetters = if (isDefaultColumnEnabled())
|
||||||
int width = getColumnWidth(columnLetters[i]);
|
intArrayOf(4, getParamNamesMaxLength(), getTypesMaxLength(), getDefaultValuesMaxLength())
|
||||||
|
else
|
||||||
|
intArrayOf(4, getParamNamesMaxLength(), getTypesMaxLength())
|
||||||
|
|
||||||
|
var columnIndex = 0
|
||||||
|
for (i in (if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) 0 else 1)..columnLetters.size() - 1) {
|
||||||
|
val width = getColumnWidth(columnLetters[i])
|
||||||
|
|
||||||
if (x <= width)
|
if (x <= width)
|
||||||
return columnIndex;
|
return columnIndex
|
||||||
|
|
||||||
columnIndex ++;
|
columnIndex++
|
||||||
x -= width;
|
x -= width
|
||||||
}
|
}
|
||||||
|
|
||||||
return columnIndex - 1;
|
return columnIndex - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getPreferredFocusedComponent(): JComponent {
|
||||||
public JComponent getPreferredFocusedComponent() {
|
val me = getMouseEvent()
|
||||||
MouseEvent me = getMouseEvent();
|
val index = if (me != null)
|
||||||
int index = me != null
|
getEditorIndex(me.getPoint().getX().toInt())
|
||||||
? getEditorIndex((int) me.getPoint().getX())
|
else if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) 1 else 0
|
||||||
: myMethod.getKind() == Kind.PRIMARY_CONSTRUCTOR ? 1 : 0;
|
val component = components.get(index)
|
||||||
JComponent component = components.get(index);
|
return if (component is EditorTextField) component.getFocusTarget() else component
|
||||||
return component instanceof EditorTextField ? ((EditorTextField) component).getFocusTarget() : component;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun getFocusableComponents(): Array<JComponent> {
|
||||||
public JComponent[] getFocusableComponents() {
|
return Array(components.size()) {
|
||||||
JComponent[] focusable = new JComponent[components.size()];
|
val component = components.get(it)
|
||||||
|
(component as? EditorTextField)?.getFocusTarget() ?: component
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < components.size(); i++) {
|
override fun calculateSignature(): String {
|
||||||
focusable[i] = components.get(i);
|
val changeInfo = evaluateChangeInfo(parametersTableModel,
|
||||||
|
myReturnTypeCodeFragment,
|
||||||
|
getMethodDescriptor(),
|
||||||
|
getVisibility(),
|
||||||
|
getMethodName(),
|
||||||
|
myDefaultValueContext)
|
||||||
|
return changeInfo.getNewSignature(getMethodDescriptor().originalPrimaryCallable)
|
||||||
|
}
|
||||||
|
|
||||||
if (focusable[i] instanceof EditorTextField)
|
override fun createVisibilityControl() = ComboBoxVisibilityPanel(
|
||||||
focusable[i] = ((EditorTextField) focusable[i]).getFocusTarget();
|
arrayOf(Visibilities.INTERNAL, Visibilities.PRIVATE, Visibilities.PROTECTED, Visibilities.PUBLIC)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun updateSignatureAlarmFired() {
|
||||||
|
super.updateSignatureAlarmFired()
|
||||||
|
validateButtons()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun validateAndCommitData() = null
|
||||||
|
|
||||||
|
override fun canRun() {
|
||||||
|
if (myNamePanel.isVisible()
|
||||||
|
&& myMethod.canChangeName()
|
||||||
|
&& !JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getMethodName())) {
|
||||||
|
throw ConfigurationException(JetRefactoringBundle.message("function.name.is.invalid"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myMethod.canChangeReturnType() === MethodDescriptor.ReadWriteOption.ReadWrite && getReturnType() == null) {
|
||||||
|
throw ConfigurationException(JetRefactoringBundle.message("return.type.is.invalid"))
|
||||||
|
}
|
||||||
|
|
||||||
|
val parameterInfos = parametersTableModel.getItems()
|
||||||
|
|
||||||
|
for (item in parameterInfos) {
|
||||||
|
val parameterName = item.parameter.getName()
|
||||||
|
|
||||||
|
if (item.parameter != parametersTableModel.getReceiver()
|
||||||
|
&& !JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(parameterName)) {
|
||||||
|
throw ConfigurationException(JetRefactoringBundle.message("parameter.name.is.invalid", parameterName))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getType(item.typeCodeFragment as JetTypeCodeFragment) == null) {
|
||||||
|
throw ConfigurationException(JetRefactoringBundle.message("parameter.type.is.invalid", item.typeCodeFragment.getText()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createRefactoringProcessor(): BaseRefactoringProcessor {
|
||||||
|
val changeInfo = evaluateChangeInfo(parametersTableModel,
|
||||||
|
myReturnTypeCodeFragment,
|
||||||
|
getMethodDescriptor(),
|
||||||
|
getVisibility(),
|
||||||
|
getMethodName(),
|
||||||
|
myDefaultValueContext)
|
||||||
|
return JetChangeSignatureProcessor(myProject, changeInfo, commandName ?: getTitle())
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getMethodDescriptor(): JetMethodDescriptor = myMethod
|
||||||
|
|
||||||
|
override fun getSelectedIdx(): Int {
|
||||||
|
return myMethod.getParameters().withIndex().firstOrNull { it.value.isNewParameter }?.index
|
||||||
|
?: super.getSelectedIdx()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun createParametersInfoModel(descriptor: JetMethodDescriptor, defaultValueContext: PsiElement): JetCallableParameterTableModel {
|
||||||
|
return when (descriptor.kind) {
|
||||||
|
JetMethodDescriptor.Kind.FUNCTION -> JetFunctionParameterTableModel(descriptor, defaultValueContext)
|
||||||
|
JetMethodDescriptor.Kind.PRIMARY_CONSTRUCTOR -> JetPrimaryConstructorParameterTableModel(descriptor, defaultValueContext)
|
||||||
|
JetMethodDescriptor.Kind.SECONDARY_CONSTRUCTOR -> JetSecondaryConstructorParameterTableModel(descriptor, defaultValueContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createReturnTypeCodeFragment(project: Project, method: JetMethodDescriptor) =
|
||||||
|
JetPsiFactory(project).createTypeCodeFragment(method.renderOriginalReturnType(), method.baseDeclaration)
|
||||||
|
|
||||||
|
private fun getType(typeCodeFragment: JetTypeCodeFragment?) = typeCodeFragment?.getType()
|
||||||
|
|
||||||
|
public fun createRefactoringProcessorForSilentChangeSignature(project: Project,
|
||||||
|
commandName: String,
|
||||||
|
method: JetMethodDescriptor,
|
||||||
|
defaultValueContext: PsiElement): BaseRefactoringProcessor {
|
||||||
|
val parameterTableModel = createParametersInfoModel(method, defaultValueContext)
|
||||||
|
parameterTableModel.setParameterInfos(method.getParameters())
|
||||||
|
val changeInfo = evaluateChangeInfo(parameterTableModel,
|
||||||
|
createReturnTypeCodeFragment(project, method),
|
||||||
|
method,
|
||||||
|
method.getVisibility(),
|
||||||
|
method.getName(),
|
||||||
|
defaultValueContext)
|
||||||
|
return JetChangeSignatureProcessor(project, changeInfo, commandName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun evaluateChangeInfo(parametersModel: JetCallableParameterTableModel,
|
||||||
|
returnTypeCodeFragment: PsiCodeFragment?,
|
||||||
|
methodDescriptor: JetMethodDescriptor,
|
||||||
|
visibility: Visibility,
|
||||||
|
methodName: String,
|
||||||
|
defaultValueContext: PsiElement): JetChangeInfo {
|
||||||
|
val parameters = parametersModel.getItems().map { parameter ->
|
||||||
|
val parameterInfo = parameter.parameter
|
||||||
|
|
||||||
|
parameterInfo.currentTypeText = parameter.typeCodeFragment.getText().trim()
|
||||||
|
val codeFragment = parameter.defaultValueCodeFragment as JetExpressionCodeFragment
|
||||||
|
val oldDefaultValue = parameterInfo.defaultValueForCall
|
||||||
|
if (codeFragment.getText() != (if (oldDefaultValue != null) oldDefaultValue.getText() else "")) {
|
||||||
|
parameterInfo.defaultValueForCall = codeFragment.getContentElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
return focusable;
|
parameterInfo
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
val returnTypeText = if (returnTypeCodeFragment != null) returnTypeCodeFragment.getText().trim() else ""
|
||||||
protected String calculateSignature() {
|
val returnType = getType(returnTypeCodeFragment as JetTypeCodeFragment?)
|
||||||
JetChangeInfo changeInfo = evaluateChangeInfo(
|
return JetChangeInfo(methodDescriptor.original,
|
||||||
myParametersTableModel,
|
methodName,
|
||||||
myReturnTypeCodeFragment,
|
returnType,
|
||||||
getMethodDescriptor(),
|
returnTypeText,
|
||||||
getVisibility(),
|
visibility,
|
||||||
getMethodName(),
|
parameters,
|
||||||
myDefaultValueContext
|
parametersModel.getReceiver(),
|
||||||
);
|
defaultValueContext)
|
||||||
return changeInfo.getNewSignature(getMethodDescriptor().getOriginalPrimaryCallable());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected VisibilityPanelBase<Visibility> createVisibilityControl() {
|
|
||||||
return new ComboBoxVisibilityPanel<Visibility>(new Visibility[]{
|
|
||||||
Visibilities.INTERNAL, Visibilities.PRIVATE, Visibilities.PROTECTED, Visibilities.PUBLIC }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void updateSignatureAlarmFired() {
|
|
||||||
super.updateSignatureAlarmFired();
|
|
||||||
validateButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected String validateAndCommitData() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void canRun() throws ConfigurationException {
|
|
||||||
if (myNamePanel.isVisible() && myMethod.canChangeName() && !JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getMethodName()))
|
|
||||||
throw new ConfigurationException(JetRefactoringBundle.message("function.name.is.invalid"));
|
|
||||||
if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite && getReturnType() == null)
|
|
||||||
throw new ConfigurationException(JetRefactoringBundle.message("return.type.is.invalid"));
|
|
||||||
|
|
||||||
List<ParameterTableModelItemBase<JetParameterInfo>> parameterInfos = myParametersTableModel.getItems();
|
|
||||||
|
|
||||||
for (ParameterTableModelItemBase<JetParameterInfo> item : parameterInfos) {
|
|
||||||
String parameterName = item.parameter.getName();
|
|
||||||
|
|
||||||
if (item.parameter != myParametersTableModel.getReceiver()
|
|
||||||
&& !JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(parameterName))
|
|
||||||
throw new ConfigurationException(JetRefactoringBundle.message("parameter.name.is.invalid", parameterName));
|
|
||||||
if (getType((JetTypeCodeFragment) item.typeCodeFragment) == null)
|
|
||||||
throw new ConfigurationException(JetRefactoringBundle.message("parameter.type.is.invalid", item.typeCodeFragment.getText()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
protected BaseRefactoringProcessor createRefactoringProcessor() {
|
|
||||||
JetChangeInfo changeInfo = evaluateChangeInfo(
|
|
||||||
myParametersTableModel,
|
|
||||||
myReturnTypeCodeFragment,
|
|
||||||
getMethodDescriptor(),
|
|
||||||
getVisibility(),
|
|
||||||
getMethodName(),
|
|
||||||
myDefaultValueContext
|
|
||||||
);
|
|
||||||
return new JetChangeSignatureProcessor(myProject, changeInfo, commandName != null ? commandName : getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static BaseRefactoringProcessor createRefactoringProcessorForSilentChangeSignature(
|
|
||||||
@NotNull Project project,
|
|
||||||
@NotNull String commandName,
|
|
||||||
@NotNull JetMethodDescriptor method,
|
|
||||||
@NotNull PsiElement defaultValueContext
|
|
||||||
) {
|
|
||||||
JetCallableParameterTableModel parameterTableModel = createParametersInfoModel(method, defaultValueContext);
|
|
||||||
parameterTableModel.setParameterInfos(method.getParameters());
|
|
||||||
JetChangeInfo changeInfo = evaluateChangeInfo(
|
|
||||||
parameterTableModel,
|
|
||||||
createReturnTypeCodeFragment(project, method),
|
|
||||||
method,
|
|
||||||
method.getVisibility(),
|
|
||||||
method.getName(),
|
|
||||||
defaultValueContext
|
|
||||||
);
|
|
||||||
return new JetChangeSignatureProcessor(project, changeInfo, commandName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JetMethodDescriptor getMethodDescriptor() {
|
|
||||||
return myMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static JetChangeInfo evaluateChangeInfo(
|
|
||||||
@NotNull JetCallableParameterTableModel parametersModel,
|
|
||||||
@Nullable PsiCodeFragment returnTypeCodeFragment,
|
|
||||||
@NotNull JetMethodDescriptor methodDescriptor,
|
|
||||||
@Nullable Visibility visibility,
|
|
||||||
@NotNull String methodName,
|
|
||||||
@NotNull PsiElement defaultValueContext
|
|
||||||
) {
|
|
||||||
List<JetParameterInfo> parameters = new ArrayList<JetParameterInfo>(parametersModel.getRowCount());
|
|
||||||
|
|
||||||
for (ParameterTableModelItemBase<JetParameterInfo> parameter : parametersModel.getItems()) {
|
|
||||||
parameter.parameter.setCurrentTypeText(parameter.typeCodeFragment.getText().trim());
|
|
||||||
|
|
||||||
parameters.add(parameter.parameter);
|
|
||||||
|
|
||||||
JetExpressionCodeFragment codeFragment = (JetExpressionCodeFragment) parameter.defaultValueCodeFragment;
|
|
||||||
JetExpression oldDefaultValue = parameter.parameter.getDefaultValueForCall();
|
|
||||||
if (!codeFragment.getText().equals(oldDefaultValue != null ? oldDefaultValue.getText() : "")) {
|
|
||||||
parameter.parameter.setDefaultValueForCall(codeFragment.getContentElement());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String returnTypeText = returnTypeCodeFragment != null ? returnTypeCodeFragment.getText().trim() : "";
|
|
||||||
JetType returnType = getType((JetTypeCodeFragment) returnTypeCodeFragment);
|
|
||||||
return new JetChangeInfo(methodDescriptor.getOriginal(), methodName, returnType, returnTypeText,
|
|
||||||
visibility, parameters, parametersModel.getReceiver(), defaultValueContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getSelectedIdx() {
|
|
||||||
List<JetParameterInfo> parameters = myMethod.getParameters();
|
|
||||||
for (int i = 0; i < parameters.size(); i++) {
|
|
||||||
JetParameterInfo info = parameters.get(i);
|
|
||||||
if (info.getIsNewParameter()) return i;
|
|
||||||
}
|
|
||||||
return super.getSelectedIdx();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user