J2K: JetChangeSignatureDialog

This commit is contained in:
Alexey Sedunov
2015-07-06 16:08:39 +03:00
parent 8b2be72434
commit 058829aa55
@@ -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);
}
@NotNull private val parametersTableModel: JetCallableParameterTableModel get() = super.myParametersTableModel
private static JetCallableParameterTableModel createParametersInfoModel(JetMethodDescriptor descriptor, PsiElement defaultValueContext) {
switch (descriptor.getKind()) {
case FUNCTION:
return new JetFunctionParameterTableModel(descriptor, defaultValueContext);
case PRIMARY_CONSTRUCTOR:
return new JetPrimaryConstructorParameterTableModel(descriptor, defaultValueContext);
case SECONDARY_CONSTRUCTOR:
return new JetSecondaryConstructorParameterTableModel(descriptor, defaultValueContext);
}
throw new AssertionError("Invalid kind: " + descriptor.getKind());
}
@Override override fun getRowPresentation(item: ParameterTableModelItemBase<JetParameterInfo>, selected: Boolean, focused: Boolean): JComponent? {
protected PsiCodeFragment createReturnTypeCodeFragment() { val panel = JPanel(BorderLayout())
return createReturnTypeCodeFragment(myProject, myMethod);
}
@NotNull val valOrVar: String
private static PsiCodeFragment createReturnTypeCodeFragment(@NotNull Project project, @NotNull JetMethodDescriptor method) { if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) {
return JetPsiFactory(project).createTypeCodeFragment( valOrVar = when (item.parameter.valOrVar) {
ChangeSignaturePackage.renderOriginalReturnType(method), method.getBaseDeclaration() JetValVar.None -> " "
); JetValVar.Val -> "val "
} JetValVar.Var -> "var "
@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();
}
} }