JavaChangeSignatureDialog: signature preview reworked

Only @Contract annotation is shown if any, because others are left intact anyways and would just clutter the preview window
Comments/extra whitespaces between modifiers are ignored
Fixes EA-122639, EA-121611
This commit is contained in:
Tagir Valeev
2018-06-18 11:42:05 +07:00
parent d16937fe55
commit fcc2ee4cf3
@@ -22,7 +22,6 @@ import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
@@ -33,7 +32,6 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
@@ -43,6 +41,7 @@ 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.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.RefactoringBundle;
@@ -70,6 +69,7 @@ import com.intellij.util.ui.table.EditorTextFieldJBTableRowRenderer;
import com.intellij.util.ui.table.JBTableRow;
import com.intellij.util.ui.table.JBTableRowEditor;
import com.intellij.util.ui.table.JBTableRowRenderer;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -92,8 +92,6 @@ import static com.intellij.refactoring.changeSignature.ChangeSignatureHandler.RE
* @author Konstantin Bulenkov
*/
public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<ParameterInfoImpl, PsiMethod, String, JavaMethodDescriptor, ParameterTableModelItemBase<ParameterInfoImpl>, JavaParameterTableModel> {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.JavaChangeSignatureDialog");
private ExceptionsTableModel myExceptionsModel;
protected Set<PsiMethod> myMethodsToPropagateExceptions;
private AnActionButton myPropExceptionsButton;
@@ -160,6 +158,14 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
};
}
@Nullable
@Override
@PsiModifier.ModifierConstant
protected String getVisibility() {
//noinspection MagicConstant
return super.getVisibility();
}
@Override
protected VisibilityPanelBase<String> createVisibilityControl() {
return new JavaComboBoxVisibilityPanel();
@@ -704,44 +710,55 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase<Paramet
return doCalculateSignature(myMethod.getMethod());
}
static String getModifiersText(PsiModifierList list, String newVisibility) {
final String oldVisibility = VisibilityUtil.getVisibilityModifier(list);
List<String> modifierKeywords = StreamEx.of(PsiTreeUtil.findChildrenOfType(list, PsiKeyword.class))
.map(PsiElement::getText)
.toList();
if (!oldVisibility.equals(newVisibility)) {
if (oldVisibility.equals(PsiModifier.PACKAGE_LOCAL)) {
modifierKeywords.add(0, PsiModifier.PACKAGE_LOCAL);
}
if (newVisibility.equals(PsiModifier.PACKAGE_LOCAL)) {
modifierKeywords.remove(oldVisibility);
} else {
modifierKeywords.replaceAll(m -> m.equals(oldVisibility) ? newVisibility : m);
}
}
return String.join(" ", modifierKeywords);
}
private String getAnnotationText(PsiMethod method, PsiModifierList modifierList) {
PsiAnnotation annotation = modifierList.findAnnotation(JavaMethodContractUtil.ORG_JETBRAINS_ANNOTATIONS_CONTRACT);
if (annotation != null) {
String[] oldNames = ContainerUtil.map2Array(method.getParameterList().getParameters(), String.class, PsiParameter::getName);
JavaParameterInfo[] parameters =
ContainerUtil.map2Array(myParametersTableModel.getItems(), JavaParameterInfo.class, item -> item.parameter);
try {
PsiAnnotation converted = ContractConverter.convertContract(method, oldNames, parameters);
if (converted != null && converted != annotation) {
String text = converted.getText();
return text.replaceFirst("^@"+JavaMethodContractUtil.ORG_JETBRAINS_ANNOTATIONS_CONTRACT, "@Contract");
}
}
catch (ContractConverter.ContractConversionException ignored) {
}
return annotation.getText();
}
return "";
}
protected String doCalculateSignature(PsiMethod method) {
final StringBuilder buffer = new StringBuilder();
final PsiModifierList modifierList = method.getModifierList();
PsiModifierList copy = (PsiModifierList)modifierList.copy();
String modifiers = "";
if (copy == null) {
LOG.error(new RuntimeException(
"Unexpected null-copy; original modifier list: " + modifierList.getClass().getName() + ":" + modifierList.getText()));
final String annotationText = getAnnotationText(method, modifierList);
buffer.append(annotationText);
if (!annotationText.isEmpty()) {
buffer.append("\n");
}
else {
PsiAnnotation annotation = copy.findAnnotation(JavaMethodContractUtil.ORG_JETBRAINS_ANNOTATIONS_CONTRACT);
if (annotation != null) {
String[] oldNames = ContainerUtil.map2Array(method.getParameterList().getParameters(), String.class, PsiParameter::getName);
JavaParameterInfo[] parameters =
ContainerUtil.map2Array(myParametersTableModel.getItems(), JavaParameterInfo.class, item -> item.parameter);
try {
PsiAnnotation converted = ContractConverter.convertContract(method, oldNames, parameters);
if (converted != null && converted != annotation) {
annotation.replace(converted);
}
}
catch (ContractConverter.ContractConversionException ignored) {
}
}
final String oldModifier = VisibilityUtil.getVisibilityModifier(modifierList);
@PsiModifier.ModifierConstant final String newModifier = ObjectUtils.notNull(getVisibility(), PsiModifier.PACKAGE_LOCAL);
if (!Comparing.equal(newModifier, oldModifier)) {
copy.setModifierProperty(oldModifier, false);
copy.setModifierProperty(newModifier, true);
}
modifiers = copy.getText().replaceAll("\n\\s+", "\n");
}
final String modifiers = getModifiersText(modifierList, ObjectUtils.notNull(getVisibility(), PsiModifier.PACKAGE_LOCAL));
buffer.append(modifiers);
if (modifiers.length() > 0 &&
!StringUtil.endsWithChar(modifiers, '\n') &&
!StringUtil.endsWithChar(modifiers, '\r') &&
!StringUtil.endsWithChar(modifiers, ' ')) {
if (!modifiers.isEmpty()) {
buffer.append(" ");
}