/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.plugin.ij.refactor.signature;
import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.changeSignature.*;
import com.intellij.refactoring.changeSignature.inCallers.JavaCallerChooser;
import com.intellij.refactoring.ui.VisibilityPanelBase;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.refactoring.util.RefactoringMessageUtil;
import com.intellij.ui.DottedBorder;
import com.intellij.ui.EditorTextField;
import com.intellij.ui.TableColumnAnimator;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.table.TableView;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.*;
import com.intellij.util.ui.DialogUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.table.JBTableRow;
import com.intellij.util.ui.table.JBTableRowEditor;
import com.jgoodies.common.base.Strings;
import gw.lang.parser.ITypeUsesMap;
import gw.lang.parser.statements.IClassFileStatement;
import gw.lang.reflect.IType;
import gw.lang.reflect.TypeSystem;
import gw.lang.reflect.gs.IGosuClass;
import gw.lang.reflect.module.IModule;
import gw.plugin.ij.completion.handlers.SymbolCompletionHandler;
import gw.plugin.ij.editors.LightweightGosuEditor;
import gw.plugin.ij.lang.GosuLanguage;
import gw.plugin.ij.lang.psi.api.statements.typedef.IGosuMethod;
import gw.plugin.ij.lang.psi.impl.AbstractGosuClassFileImpl;
import gw.plugin.ij.lang.psi.impl.GosuClassParseData;
import gw.plugin.ij.lang.psi.impl.GosuFragmentFileImpl;
import gw.plugin.ij.lang.psi.impl.types.CompletionVoter;
import gw.plugin.ij.refactor.GosuRefactoringUtil;
import gw.plugin.ij.util.GosuBundle;
import gw.plugin.ij.util.GosuModuleUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List;
import static com.jgoodies.common.base.Strings.isBlank;
import static gw.lang.reflect.TypeSystem.getByFullNameIfValid;
import static gw.plugin.ij.refactor.GosuRefactoringUtil.findFragmentType;
import static gw.plugin.ij.util.ClassLord.purgeClassName;
import static gw.plugin.ij.util.GosuModuleUtil.findModuleForPsiElement;
public class GosuChangeSignatureDialog extends ChangeSignatureDialogBase {
protected GosuChangeSignatureDialog(Project project, GosuMethodDescriptor descriptor, boolean allowDelegation, PsiElement context, ChangeSignatureHandler initSubstisutor) {
super(project, descriptor, allowDelegation, context, initSubstisutor);
}
public static JavaChangeSignatureDialog createAndPreselectNew(final Project project,
final PsiMethod method,
final List<ParameterInfoImpl> parameterInfos,
final boolean allowDelegation, final PsiReferenceExpression refExpr) {
return new JavaChangeSignatureDialog(project, method, allowDelegation, refExpr) {
@Override
protected int getSelectedIdx() {
for (int i = 0; i < parameterInfos.size(); i++) {
ParameterInfoImpl info = parameterInfos.get(i);
if (info.oldParameterIndex < 0) {
return i;
}
}
return super.getSelectedIdx();
}
};
}
@Override
protected VisibilityPanelBase<String> createVisibilityControl() {
return new GosuComboBoxVisibilityPanel();
}
@Override
protected JComponent createCenterPanel() {
final JComponent centerPanel = super.createCenterPanel();
myPropagateParamChangesButton.setVisible(true);
return centerPanel;
}
@Override
protected LanguageFileType getFileType() {
return GosuLanguage.instance().getAssociatedFileType();
}
@Override
protected GosuParameterTableModel createParametersInfoModel(GosuMethodDescriptor descriptor) {
final PsiParameterList parameterList = descriptor.getMethod().getParameterList();
return new GosuParameterTableModel(parameterList, myDefaultValueContext, this);
}
@Override
protected boolean isListTableViewSupported() {
return true;
}
@Override
protected boolean isEmptyRow(ParameterTableModelItem row) {
if (!StringUtil.isEmpty(row.parameter.getName())) return false;
if (!StringUtil.isEmpty(row.parameter.getTypeText())) return false;
return true;
}
@Override
protected JComponent getRowPresentation(ParameterTableModelItem item, boolean selected, final boolean focused) {
final JPanel panel = new JPanel(new BorderLayout());
final String typeText = item.typeCodeFragment.getText();
String name = item.parameter.getName();
final String separator = StringUtil.repeatSymbol(' ', getNamesMaxLength() - name.length() + 2);
String text = name + separator + ": " + typeText;
final String defaultValue = item.defaultValueCodeFragment.getText();
String tail = "";
if (StringUtil.isNotEmpty(defaultValue)) {
tail += " default value = " + defaultValue;
}
if (item.parameter.isUseAnySingleVariable()) {
if (StringUtil.isNotEmpty(defaultValue)) {
tail += ";";
}
tail += " Use any var.";
}
if (!StringUtil.isEmpty(tail)) {
text += " //" + tail;
}
final EditorTextField field = new EditorTextField(" " + text, getProject(), getFileType()) {
@Override
protected boolean shouldHaveBorder() {
return false;
}
};
Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
font = new Font(font.getFontName(), font.getStyle(), 12);
field.setFont(font);
if (selected && focused) {
panel.setBackground(UIUtil.getTableSelectionBackground());
field.setAsRendererWithSelection(UIUtil.getTableSelectionBackground(), UIUtil.getTableSelectionForeground());
} else {
panel.setBackground(UIUtil.getTableBackground());
if (selected && !focused) {
panel.setBorder(new DottedBorder(UIUtil.getTableForeground()));
}
}
panel.add(field, BorderLayout.WEST);
return panel;
}
private int getTypesMaxLength() {
int len = 0;
for (ParameterTableModelItem item : myParametersTableModel.getItems()) {
final String text = item.typeCodeFragment == null ? null : item.typeCodeFragment.getText();
len = Math.max(len, text == null ? 0 : text.length());
}
return len;
}
private int getNamesMaxLength() {
int len = 0;
for (ParameterTableModelItem item : myParametersTableModel.getItems()) {
final String text = item.parameter.getName();
len = Math.max(len, text == null ? 0 : text.length());
}
return len;
}
private int getColumnWidth(int index) {
int letters = getTypesMaxLength() + (index == 0 ? 1 : getNamesMaxLength() + 2);
Font font = EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
font = new Font(font.getFontName(), font.getStyle(), 12);
return letters * Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth("W");
}
private int getTypesColumnWidth() {
return getColumnWidth(0);
}
private int getNamesColumnWidth() {
return getColumnWidth(1);
}
@Override
protected JBTableRowEditor getTableEditor(final JTable t, final ParameterTableModelItem item) {
return new JBTableRowEditor() {
private EditorTextField myTypeEditor;
private EditorTextField myNameEditor;
private EditorTextField myDefaultValueEditor;
private JCheckBox myAnyVar;
class MyDocumentListener extends DocumentAdapter {
private int myColumn;
private MyDocumentListener(int column) {
myColumn = column;
}
@Override
public void documentChanged(DocumentEvent e) {
fireDocumentChanged(e, myColumn);
}
}
@Override
public void prepareEditor(JTable table, int row) {
setLayout(new BorderLayout());
final JPanel typePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
final Document document = item.typeCodeFragment.getDocument();
myTypeEditor = new EditorTextField(document, getProject(), getFileType());
myTypeEditor.addDocumentListener(mySignatureUpdater);
final JBLabel typeLabel = new JBLabel("Type:", UIUtil.ComponentStyle.SMALL);
IJSwingUtilities.adjustComponentsOnMac(typeLabel, myTypeEditor);
typePanel.add(typeLabel);
typePanel.add(myTypeEditor);
myTypeEditor.setPreferredWidth(t.getWidth() / 2);
myTypeEditor.addDocumentListener(new MyDocumentListener(0));
add(typePanel, BorderLayout.WEST);
final JPanel namePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
myNameEditor = new EditorTextField(item.parameter.getName(), getProject(), getFileType());
myNameEditor.addDocumentListener(mySignatureUpdater);
myNameEditor.addDocumentListener(new MyDocumentListener(1));
final JBLabel nameLabel = new JBLabel(GosuBundle.message("new.dlg.name"), UIUtil.ComponentStyle.SMALL);
IJSwingUtilities.adjustComponentsOnMac(nameLabel, myNameEditor);
namePanel.add(nameLabel);
namePanel.add(myNameEditor);
add(namePanel, BorderLayout.CENTER);
new TextFieldCompletionProvider() {
@Override
protected void addCompletionVariants(@NotNull String text,
int offset,
@NotNull String prefix,
@NotNull CompletionResultSet result) {
final PsiType type;
try {
type = findFragmentType(item.typeCodeFragment.getPsiFile());
}
catch (Exception e) {
return;
}
final SuggestedNameInfo info = JavaCodeStyleManager.getInstance(myProject)
.suggestVariableName(VariableKind.PARAMETER, null, null, type);
for (String completionVariant : info.names) {
final LookupElementBuilder element = LookupElementBuilder.create(completionVariant);
result.addElement(element.withLookupString(completionVariant.toLowerCase()));
}
}
}.apply(myNameEditor, item.parameter.getName());
if (item.parameter.getOldIndex() == -1) {
final JPanel additionalPanel = new JPanel(new BorderLayout());
final JPanel defaultValuePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 4, 2, true, false));
final Document doc = item.defaultValueCodeFragment.getDocument();
myDefaultValueEditor = new EditorTextField(doc, getProject(), getFileType());
// ((PsiExpressionCodeFragment)item.defaultValueCodeFragment).setExpectedType(getRowType(item));
final JBLabel defaultValueLabel = new JBLabel("Default value:", UIUtil.ComponentStyle.SMALL);
IJSwingUtilities.adjustComponentsOnMac(defaultValueLabel, myDefaultValueEditor);
defaultValuePanel.add(defaultValueLabel);
defaultValuePanel.add(myDefaultValueEditor);
myDefaultValueEditor.setPreferredWidth(t.getWidth() / 2);
myDefaultValueEditor.addDocumentListener(new MyDocumentListener(2));
additionalPanel.add(defaultValuePanel, BorderLayout.WEST);
if (!isGenerateDelegate()) {
myAnyVar = new JCheckBox("&Use Any Var");
UIUtil.applyStyle(UIUtil.ComponentStyle.SMALL, myAnyVar);
DialogUtil.registerMnemonic(myAnyVar, '&');
myAnyVar.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
item.parameter.setUseAnySingleVariable(myAnyVar.isSelected());
}
});
final JPanel anyVarPanel = new JPanel(new BorderLayout());
anyVarPanel.add(myAnyVar, BorderLayout.SOUTH);
UIUtil.addInsets(anyVarPanel, new Insets(0,0,8,0));
additionalPanel.add(anyVarPanel, BorderLayout.CENTER);
//additionalPanel.setPreferredSize(new Dimension(t.getWidth() / 3, -1));
}
add(additionalPanel, BorderLayout.SOUTH);
}
}
@Override
public JBTableRow getValue() {
return new JBTableRow() {
@Override
public Object getValueAt(int column) {
switch (column) {
case 0: return item.typeCodeFragment;
case 1: return myNameEditor.getText().trim();
case 2: return item.defaultValueCodeFragment;
case 3: return myAnyVar != null && myAnyVar.isSelected();
}
return null;
}
};
}
@Override
public JComponent getPreferredFocusedComponent() {
final MouseEvent me = getMouseEvent();
if (me == null) {
return myTypeEditor.getFocusTarget();
}
final double x = me.getPoint().getX();
return x <= getTypesColumnWidth()
? myTypeEditor.getFocusTarget()
: myDefaultValueEditor == null || x <= getNamesColumnWidth()
? myNameEditor.getFocusTarget()
: myDefaultValueEditor.getFocusTarget();
}
@Override
public JComponent[] getFocusableComponents() {
final List<JComponent> focusable = new ArrayList<JComponent>();
focusable.add(myTypeEditor.getFocusTarget());
focusable.add(myNameEditor.getFocusTarget());
if (myDefaultValueEditor != null) {
focusable.add(myDefaultValueEditor.getFocusTarget());
}
if (myAnyVar != null) {
focusable.add(myAnyVar);
}
return focusable.toArray(new JComponent[focusable.size()]);
}
};
}
@Nullable
private static PsiType getRowType(ParameterTableModelItemBase<ParameterInfoImpl> item) {
try {
return ((PsiTypeCodeFragment)item.typeCodeFragment).getType();
}
catch (PsiTypeCodeFragment.TypeSyntaxException e) {
return null;
}
catch (PsiTypeCodeFragment.NoTypeException e) {
return null;
}
}
@Override
protected void customizeParametersTable(TableView<ParameterTableModelItem> table) {
final JTable t = table.getComponent();
final TableColumn defaultValue = t.getColumnModel().getColumn(2);
final TableColumn varArg = t.getColumnModel().getColumn(3);
t.removeColumn(defaultValue);
t.removeColumn(varArg);
t.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
if (e.getType() == TableModelEvent.INSERT) {
t.getModel().removeTableModelListener(this);
final TableColumnAnimator animator = new TableColumnAnimator(t);
animator.setStep(48);
animator.addColumn(defaultValue, (t.getWidth() - 48) / 3);
animator.addColumn(varArg, 48);
animator.startAndDoWhenDone(new Runnable() {
@Override
public void run() {
t.editCellAt(t.getRowCount() - 1, 0);
}
});
animator.start();
}
}
});
}
@Override
protected BaseRefactoringProcessor createRefactoringProcessor() {
final List<ParameterInfoImpl> parameters = getParameters();
return new GosuChangeSignatureProcessor(myProject,
myMethod.getMethod(),
isGenerateDelegate(),
getVisibility(),
getMethodName(),
getReturnType(),
parameters.toArray(new ParameterInfoImpl[parameters.size()]),
new ThrownExceptionInfo[0],
(Set) myMethodsToPropagateParameters,
Collections.<PsiMethod>emptySet(),
changeSignatureHandler);
}
@Nullable
protected CanonicalTypes.Type getReturnType() {
if (myReturnTypeField != null) {
final PsiType type = findFragmentType(myReturnTypeCodeFragment);
if (type != null) {
return CanonicalTypes.createTypeWrapper(type);
}
}
return null;
}
@Override
protected PsiCodeFragment createReturnTypeCodeFragment() {
final String returnTypeText = StringUtil.notNullize(myMethod.getReturnTypeText());
GosuFragmentFileImpl frag = new GosuFragmentFileImpl(myProject, returnTypeText, myMethod.getMethod());
frag.setAllowedCompletionHandlers(SymbolCompletionHandler.class);
frag.setAllowedCompletionTypes(CompletionVoter.Type.TYPE);
return frag;
}
@Nullable
@Override
protected CallerChooserBase<PsiMethod> createCallerChooser(String title, Tree treeToReuse, Consumer<Set<IGosuMethod>> callback) {
return new JavaCallerChooser(myMethod.getMethod(), myProject, title, treeToReuse, (Consumer) callback);
}
@Override
protected String validateAndCommitData() {
PsiManager manager = PsiManager.getInstance(myProject);
PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
String name = getMethodName();
if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
}
if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite) {
if (!isBlank(myReturnTypeCodeFragment.getText())) {
PsiType returnType = findFragmentType(myReturnTypeCodeFragment);
IType tsType = getByFullNameIfValid(purgeClassName(returnType.getCanonicalText()),
findModuleForPsiElement(myMethod.getMethod()));
if (tsType == null) {
myReturnTypeField.requestFocus();
return RefactoringBundle.message("changeSignature.wrong.return.type", myReturnTypeCodeFragment.getText());
}
}
}
List<ParameterTableModelItem> parameterInfos = myParametersTableModel.getItems();
final int newParametersNumber = parameterInfos.size();
for (int i = 0; i < newParametersNumber; i++) {
final ParameterTableModelItem item = parameterInfos.get(i);
if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(item.parameter.getName())) {
return RefactoringMessageUtil.getIncorrectIdentifierMessage(item.parameter.getName());
}
final PsiType type;
LightweightGosuEditor editor = parameterInfos.get(i).typeCodeFragment;
Document document = editor.getDocument();
if (isBlank(document.getText())) {
return RefactoringBundle.message("changeSignature.no.type.for.parameter", item.parameter.getName());
} else {
IType tsType = null;
type = findFragmentType(editor.getPsiFile());
if (type != null) {
tsType = getByFullNameIfValid(purgeClassName(type.getCanonicalText()), findModuleForPsiElement(myMethod.getMethod()));
}
if (tsType == null) {
return RefactoringBundle.message("changeSignature.wrong.type.for.parameter",
document.getText(),
item.parameter.getName());
}
}
item.parameter.setType(type);
if (type instanceof PsiEllipsisType && i != newParametersNumber - 1) {
return RefactoringBundle.message("changeSignature.vararg.not.last");
}
if (item.parameter.oldParameterIndex < 0) {
String def = ApplicationManager.getApplication().runWriteAction(new Computable<String>() {
@Override
public String compute() {
return JavaCodeStyleManager.getInstance(myProject).qualifyClassReferences(item.defaultValueCodeFragment.getPsiFile()).getText();
}
});
item.parameter.setDefaultValue(def);
def = def.trim();
if (!(type instanceof PsiEllipsisType)) {
try {
if (!StringUtil.isEmpty(def)) {
factory.createExpressionFromText(def, null);
}
}
catch (IncorrectOperationException e) {
return e.getMessage();
}
}
}
}
// warnings
if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite) {
if (!resolveType(myReturnTypeCodeFragment)) {
if (Messages.showOkCancelDialog(myProject, RefactoringBundle
.message("changeSignature.cannot.resolve.return.type", myReturnTypeCodeFragment.getText()),
RefactoringBundle.message("changeSignature.refactoring.name"), Messages.getWarningIcon()) != 0) {
return EXIT_SILENTLY;
}
}
}
for (ParameterTableModelItem item : parameterInfos) {
if (!resolveType(item.typeCodeFragment.getPsiFile())) {
if (Messages.showOkCancelDialog(myProject, RefactoringBundle
.message("changeSignature.cannot.resolve.parameter.type", item.typeCodeFragment.getText(), item.parameter.getName()),
RefactoringBundle.message("changeSignature.refactoring.name"), Messages.getWarningIcon()) !=
0) {
return EXIT_SILENTLY;
}
}
}
return null;
}
public boolean resolveType(PsiElement fragment) {
String typeText = fragment.getText();
if (Strings.isBlank(typeText)) {
return fragment == myReturnTypeCodeFragment;
}
return GosuRefactoringUtil.isResolvableType(findFragmentType(fragment)) || resolveByRelativeName(typeText);
}
public boolean resolveByRelativeName(String typeText) {
IModule module = getModule();
try {
TypeSystem.pushModule(module);
ITypeUsesMap typeUsesMap = getTypeUsesMap();
if (typeUsesMap == null) {
TypeSystem.getByRelativeName(typeText);
} else {
TypeSystem.getByRelativeName(typeText, typeUsesMap);
}
return true;
} catch (ClassNotFoundException e) {
return false;
} finally {
TypeSystem.popModule(module);
}
}
public ITypeUsesMap getTypeUsesMap() {
PsiFile containingFile = myMethod.getMethod().getContainingFile();
if (containingFile instanceof AbstractGosuClassFileImpl) {
GosuClassParseData parseData = ((AbstractGosuClassFileImpl) containingFile).getParseData();
if (parseData != null) {
IClassFileStatement classFileStatement = parseData.getClassFileStatement();
if (classFileStatement != null) {
IGosuClass gosuClass = classFileStatement.getGosuClass();
if (gosuClass != null) {
return gosuClass.getTypeUsesMap();
}
}
}
}
return null;
}
@Override
protected ValidationInfo doValidate() {
if (!getTableComponent().isEditing()) {
for (final ParameterTableModelItem item : myParametersTableModel.getItems()) {
if (item.parameter.oldParameterIndex < 0) {
// if (StringUtil.isEmpty(item.defaultValueCodeFragment.getText()))
//return new ValidationInfo("Default value is missing. In the method call place new parameter value would be leaved blank");
}
}
}
return super.doValidate();
}
@Override
protected boolean postponeValidation() {
return false;
}
@Override
protected String calculateSignature() {
return doCalculateSignature(myMethod.getMethod());
}
protected String doCalculateSignature(PsiMethod method) {
final StringBuilder buffer = new StringBuilder();
final PsiModifierList modifierList = method.getModifierList();
String modifiers = "";
final String oldModifier = VisibilityUtil.getVisibilityModifier(modifierList);
final String newModifier = getVisibility();
String newModifierStr = VisibilityUtil.getVisibilityString(newModifier);
if (!newModifier.equals(oldModifier)) {
int index = modifiers.indexOf(oldModifier);
if (index >= 0) {
final StringBuilder buf = new StringBuilder(modifiers);
buf.replace(index,
index + oldModifier.length() + ("".equals(newModifierStr) ? 1 : 0),
newModifierStr);
modifiers = buf.toString();
} else {
if (!StringUtil.isEmpty(newModifierStr)) {
newModifierStr += " ";
}
modifiers = newModifierStr + modifiers;
}
}
buffer.append(modifiers);
if (modifiers.length() > 0 &&
!StringUtil.endsWithChar(modifiers, '\n') &&
!StringUtil.endsWithChar(modifiers, '\r') &&
!StringUtil.endsWithChar(modifiers, ' ')) {
buffer.append(" ");
}
buffer.append("function ").append(getMethodName());
buffer.append("(");
int paramIndent = buffer.toString().length();
char[] chars = new char[paramIndent];
Arrays.fill(chars, ' ');
String indent = new String(chars);
List<ParameterTableModelItem> items = myParametersTableModel.getItems();
int curIndent = indent.length();
for (int i = 0; i < items.size(); i++) {
final ParameterTableModelItem item = items.get(i);
if (i > 0) {
buffer.append(",");
buffer.append("\n");
buffer.append(indent);
}
final String text = item.typeCodeFragment.getText();
final String name = item.parameter.getName();
buffer.append(name).append(" : ").append(text);
curIndent = indent.length() + text.length() + 1 + name.length();
}
//if (!items.isEmpty()) {
// buffer.append("\n");
//}
buffer.append(")");
if (!method.isConstructor()) {
final CanonicalTypes.Type type = getReturnType();
if (type != null) {
buffer.append(": ").append(type.getTypeText());
}
}
return buffer.toString();
}
public IModule getModule() {
return GosuModuleUtil.findModuleForPsiElement(myMethod.getMethod());
}
public ChangeSignatureHandler getSubstitutor() {
return changeSignatureHandler;
}
}