inplace change signature: add preview
authorAnna.Kozlova <anna.kozlova@jetbrains.com>
Fri, 11 Nov 2016 16:44:19 +0000 (17:44 +0100)
committerAnna.Kozlova <anna.kozlova@jetbrains.com>
Fri, 11 Nov 2016 16:57:24 +0000 (17:57 +0100)
java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDetector.java
platform/lang-impl/src/com/intellij/refactoring/changeSignature/inplace/InplaceChangeSignature.java
platform/lang-impl/src/com/intellij/refactoring/changeSignature/inplace/LanguageChangeSignatureDetector.java
platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java
platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java

index 6e4a21f3b07a94d306eb745632f22cfb2f7ae161..ac7da60d2e3cf276a25c51cc5517bec8ef28dc97 100644 (file)
  */
 package com.intellij.refactoring.changeSignature;
 
+import com.intellij.ide.highlighter.JavaFileType;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.refactoring.changeSignature.inplace.LanguageChangeSignatureDetector;
+import com.intellij.refactoring.util.CanonicalTypes;
+import com.intellij.util.ObjectUtils;
+import com.intellij.util.VisibilityUtil;
 import org.jetbrains.annotations.NotNull;
 
+import java.util.List;
+
 /**
  * User: anna
  * Date: Sep 6, 2010
@@ -64,6 +72,70 @@ public class JavaChangeSignatureDetector implements LanguageChangeSignatureDetec
     return method != null ? getSignatureRange((PsiMethod)method) : null;
   }
 
+  @Override
+  public String getMethodSignaturePreview(DetectedJavaChangeInfo initialChangeInfo,
+                                          final List<TextRange> deleteRanges,
+                                          final List<TextRange> newRanges) {
+    StringBuilder buf = new StringBuilder();
+    String visibility = VisibilityUtil.getVisibilityString(initialChangeInfo.getNewVisibility());
+    buf.append(visibility);
+    if (!StringUtil.isEmptyOrSpaces(visibility)) {
+      buf.append(" ");
+    }
+    CanonicalTypes.Type returnType = initialChangeInfo.getNewReturnType();
+    if (returnType != null) {
+      buf.append(returnType.getTypeText()).append(" ");
+    }
+    buf.append(initialChangeInfo.getNewName()).append("(");
+
+    JavaParameterInfo[] newParameters = initialChangeInfo.getNewParameters();
+    boolean first = true;
+    boolean[] toRemove = initialChangeInfo.toRemoveParm();
+    for (int i = 0; i < toRemove.length; i++) {
+      if (first) {
+        first = false;
+      }
+      else {
+        buf.append(", ");
+      }
+
+      if (toRemove[i]) {
+        String deletedParam = initialChangeInfo.getOldParameterTypes()[i] + " " + initialChangeInfo.getOldParameterNames()[i];
+        deleteRanges.add(new TextRange(buf.length(), buf.length() + deletedParam.length()));
+        buf.append(deletedParam);
+      }
+      else {
+        for (JavaParameterInfo parameter : newParameters) {
+          if (parameter.getOldIndex() == i) {
+            buf.append(parameter.getTypeText()).append(" ").append(parameter.getName());
+            break;
+          }
+        }
+      }
+    }
+
+    for (JavaParameterInfo param : newParameters) {
+      if (param.getOldIndex() == -1) {
+        if (first) {
+          first = false;
+        }
+        else {
+          buf.append(", ");
+        }
+        String paramPresentation = param.getTypeText() + " " + ObjectUtils.notNull(param.getName(), "");
+        newRanges.add(new TextRange(buf.length(), buf.length() + paramPresentation.length()));
+        buf.append(paramPresentation);
+      }
+    }
+    buf.append(")");
+    return buf.toString();
+  }
+
+  @Override
+  public FileType getFileType() {
+    return JavaFileType.INSTANCE;
+  }
+
   @Override
   public DetectedJavaChangeInfo createNextChangeInfo(String signature, @NotNull final DetectedJavaChangeInfo currentInfo, boolean delegate) {
     final PsiElement currentInfoMethod = currentInfo.getMethod();
index f6b8e172f1c982799c2df00cda7ec7c10b385baa..e484f7181a70be5233e632c8b1ba20c35e895e85 100644 (file)
 package com.intellij.refactoring.changeSignature.inplace;
 
 import com.intellij.codeInsight.highlighting.HighlightManager;
+import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.command.impl.FinishMarkAction;
 import com.intellij.openapi.command.impl.StartMarkAction;
 import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
 import com.intellij.openapi.editor.colors.EditorColors;
 import com.intellij.openapi.editor.colors.EditorColorsManager;
 import com.intellij.openapi.editor.event.DocumentEvent;
 import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.editor.markup.HighlighterLayer;
+import com.intellij.openapi.editor.markup.HighlighterTargetArea;
 import com.intellij.openapi.editor.markup.RangeHighlighter;
 import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -44,12 +49,14 @@ import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.changeSignature.ChangeInfo;
 import com.intellij.refactoring.changeSignature.ChangeSignatureHandler;
+import com.intellij.refactoring.rename.inplace.InplaceRefactoring;
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.ui.components.JBCheckBox;
 import com.intellij.util.ui.PositionTracker;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import javax.swing.*;
 import java.awt.*;
 import java.util.ArrayList;
 
@@ -67,6 +74,7 @@ public class InplaceChangeSignature implements DocumentListener {
   private StartMarkAction myMarkAction;
   private Balloon myBalloon;
   private boolean myDelegate;
+  private EditorEx myPreview;
 
   public InplaceChangeSignature(Project project, Editor editor, @NotNull PsiElement element) {
     myDocumentManager = PsiDocumentManager.getInstance(project);
@@ -98,8 +106,9 @@ public class InplaceChangeSignature implements DocumentListener {
       highlighter.setGreedyToLeft(true);
     }
     myEditor.getDocument().addDocumentListener(this);
-    showBalloon();
     myEditor.putUserData(INPLACE_CHANGE_SIGNATURE, this);
+    myPreview = InplaceRefactoring.createPreviewComponent(project, myDetector.getFileType());
+    showBalloon();
   }
 
   @Nullable
@@ -166,14 +175,45 @@ public class InplaceChangeSignature implements DocumentListener {
       if (changeInfo == null && myCurrentInfo != null) {
         myStableChange = myCurrentInfo;
       }
+      if (changeInfo != null) {
+        updateMethodSignature(changeInfo);
+      }
       myCurrentInfo = changeInfo;
     });
   }
 
+  private void updateMethodSignature(ChangeInfo changeInfo) {
+    ArrayList<TextRange> deleteRanges = new ArrayList<>();
+    ArrayList<TextRange> newRanges = new ArrayList<>();
+    String methodSignature = myDetector.getMethodSignaturePreview(changeInfo, deleteRanges, newRanges);
+
+    myPreview.getMarkupModel().removeAllHighlighters();
+    new WriteCommandAction(null) {
+      @Override
+      protected void run(@NotNull Result result) throws Throwable {
+        myPreview.getDocument().replaceString(0, myPreview.getDocument().getTextLength(), methodSignature);
+      }
+    }.execute();
+    TextAttributes deprecatedAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.DEPRECATED_ATTRIBUTES);
+    for (TextRange range : deleteRanges) {
+      myPreview.getMarkupModel().addRangeHighlighter(range.getStartOffset(), range.getEndOffset(), HighlighterLayer.ADDITIONAL_SYNTAX,
+                                                     deprecatedAttributes, HighlighterTargetArea.EXACT_RANGE);
+    }
+    TextAttributes todoAttributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.TODO_DEFAULT_ATTRIBUTES);
+    for (TextRange range : newRanges) {
+      myPreview.getMarkupModel().addRangeHighlighter(range.getStartOffset(), range.getEndOffset(), HighlighterLayer.ADDITIONAL_SYNTAX,
+                                                     todoAttributes, HighlighterTargetArea.EXACT_RANGE);
+    }
+  }
+
   protected void showBalloon() {
     JBCheckBox checkBox = new JBCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method"));
     checkBox.addActionListener(e -> myDelegate = checkBox.isSelected());
-    final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createDialogBalloonBuilder(checkBox, null).setSmallVariant(true);
+    JPanel content = new JPanel(new BorderLayout());
+    content.add(myPreview.getComponent(), BorderLayout.NORTH);
+    updateMethodSignature(myStableChange);
+    content.add(checkBox, BorderLayout.SOUTH);
+    final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createDialogBalloonBuilder(content, null).setSmallVariant(true);
     myBalloon = balloonBuilder.createBalloon();
     myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
     myBalloon.show(new PositionTracker<Balloon>(myEditor.getContentComponent()) {
index eb76bd4d45343e1436458944134bc75ca6bc41a1..82b31338c8036f51631c56c82252873f8e0b45eb 100644 (file)
  */
 package com.intellij.refactoring.changeSignature.inplace;
 
+import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.PsiElement;
 import com.intellij.refactoring.changeSignature.ChangeInfo;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.List;
+
 /**
  * User: anna
  * Date: Sep 6, 2010
@@ -41,4 +44,10 @@ public interface LanguageChangeSignatureDetector<C extends ChangeInfo> {
     final TextRange signatureRange = getHighlightingRange(initialChangeInfo);
     return signatureRange.shiftRight(-signatureRange.getStartOffset()).substring(initialChangeInfo.getMethod().getText());
   }
+
+  default String getMethodSignaturePreview(C info, final List<TextRange> deleteRanges, final List<TextRange> newRanges) {
+    return extractSignature(info);
+  }
+
+  FileType getFileType();
 }
index aa0534f8d2c2fefe13e0124517f241a63bf3e844..b36e319ea5933534f4a59d85e14dfd65a7c8a68c 100644 (file)
@@ -24,7 +24,6 @@ import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.command.impl.StartMarkAction;
-import com.intellij.openapi.command.undo.UndoUtil;
 import com.intellij.openapi.editor.*;
 import com.intellij.openapi.editor.colors.EditorColors;
 import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -35,7 +34,6 @@ import com.intellij.openapi.editor.markup.RangeHighlighter;
 import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.Balloon;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.Ref;
@@ -49,14 +47,12 @@ import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.listeners.RefactoringEventData;
 import com.intellij.refactoring.listeners.RefactoringEventListener;
 import com.intellij.refactoring.rename.inplace.InplaceRefactoring;
-import com.intellij.ui.DottedBorder;
 import com.intellij.util.ui.PositionTracker;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import javax.swing.border.EmptyBorder;
-import javax.swing.border.LineBorder;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
@@ -103,28 +99,7 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
     myExprText = getExpressionText(expr);
     myLocalName = localVariable != null ? localVariable.getName() : null;
 
-    Document document = EditorFactory.getInstance().createDocument("");
-    UndoUtil.disableUndoFor(document);
-    myPreview = (EditorEx)EditorFactory.getInstance().createEditor(document, project, languageFileType, true);
-    myPreview.setOneLineMode(true);
-    final EditorSettings settings = myPreview.getSettings();
-    settings.setAdditionalLinesCount(0);
-    settings.setAdditionalColumnsCount(1);
-    settings.setRightMarginShown(false);
-    settings.setFoldingOutlineShown(false);
-    settings.setLineNumbersShown(false);
-    settings.setLineMarkerAreaShown(false);
-    settings.setIndentGuidesShown(false);
-    settings.setVirtualSpace(false);
-    myPreview.setHorizontalScrollbarVisible(false);
-    myPreview.setVerticalScrollbarVisible(false);
-    myPreview.setCaretEnabled(false);
-    settings.setLineCursorWidth(1);
-
-    final Color bg = myPreview.getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR);
-    myPreview.setBackgroundColor(bg);
-    myPreview.setBorder(BorderFactory.createCompoundBorder(new DottedBorder(Color.gray), new LineBorder(bg, 2)));
-
+    myPreview = createPreviewComponent(project, languageFileType);
     myPreviewComponent = new JPanel(new BorderLayout());
     myPreviewComponent.add(myPreview.getComponent(), BorderLayout.CENTER);
     myPreviewComponent.setBorder(new EmptyBorder(2, 2, 6, 2));
index c556edcbc1dda40f0e3144338bf9e9b825f41e24..ffd622ae530cf210bb89fb5b35b9d8cf2f3a3b65 100644 (file)
@@ -35,13 +35,12 @@ import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.command.impl.FinishMarkAction;
 import com.intellij.openapi.command.impl.StartMarkAction;
+import com.intellij.openapi.command.undo.UndoUtil;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.RangeMarker;
-import com.intellij.openapi.editor.ScrollType;
+import com.intellij.openapi.editor.*;
 import com.intellij.openapi.editor.colors.EditorColors;
 import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.ex.util.EditorUtil;
 import com.intellij.openapi.editor.impl.EditorImpl;
 import com.intellij.openapi.editor.markup.RangeHighlighter;
@@ -50,6 +49,7 @@ import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
 import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.keymap.Keymap;
 import com.intellij.openapi.keymap.KeymapManager;
 import com.intellij.openapi.keymap.KeymapUtil;
@@ -73,6 +73,7 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.refactoring.RefactoringActionHandler;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.util.CommonRefactoringUtil;
+import com.intellij.ui.DottedBorder;
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.ui.popup.PopupFactoryImpl;
 import com.intellij.util.CommonProcessors;
@@ -85,6 +86,7 @@ import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.TestOnly;
 
 import javax.swing.*;
+import javax.swing.border.LineBorder;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
@@ -487,6 +489,32 @@ public abstract class InplaceRefactoring {
     return myElementToRename instanceof PsiNameIdentifierOwner ? ((PsiNameIdentifierOwner)myElementToRename).getNameIdentifier() : null;
   }
 
+  public static EditorEx createPreviewComponent(Project project, FileType languageFileType) {
+    Document document = EditorFactory.getInstance().createDocument("");
+    UndoUtil.disableUndoFor(document);
+    EditorEx previewEditor = (EditorEx)EditorFactory.getInstance().createEditor(document, project, languageFileType, true);
+    previewEditor.setOneLineMode(true);
+    final EditorSettings settings = previewEditor.getSettings();
+    settings.setAdditionalLinesCount(0);
+    settings.setAdditionalColumnsCount(1);
+    settings.setRightMarginShown(false);
+    settings.setFoldingOutlineShown(false);
+    settings.setLineNumbersShown(false);
+    settings.setLineMarkerAreaShown(false);
+    settings.setIndentGuidesShown(false);
+    settings.setVirtualSpace(false);
+    previewEditor.setHorizontalScrollbarVisible(false);
+    previewEditor.setVerticalScrollbarVisible(false);
+    previewEditor.setCaretEnabled(false);
+    settings.setLineCursorWidth(1);
+
+    final Color bg = previewEditor.getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR);
+    previewEditor.setBackgroundColor(bg);
+    previewEditor.setBorder(BorderFactory.createCompoundBorder(new DottedBorder(Color.gray), new LineBorder(bg, 2)));
+
+    return previewEditor;
+  }
+
   @Nullable
   protected StartMarkAction startRename() throws StartMarkAction.AlreadyStartedException {
     final StartMarkAction[] markAction = new StartMarkAction[1];