mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[grazie] IJPL-201996 Reimplement RenameTo to make it more responsive and simplify its usage
Merge-request: IJ-MR-176404 Merged-by: Ilia Permiashkin <ilia.permiashkin@jetbrains.com> GitOrigin-RevId: df6ccbceb44d4d2c2fabb62e92a97007af9d2878
This commit is contained in:
committed by
intellij-monorepo-bot
parent
732b17bc67
commit
0cbe60bb0c
@@ -13,6 +13,8 @@ import com.intellij.spellchecker.settings.SpellCheckerSettings
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.intellij.tools.ide.metrics.benchmark.Benchmark
|
||||
import com.intellij.ui.ChooserInterceptor
|
||||
import com.intellij.ui.UiInterceptors
|
||||
import java.util.function.Consumer
|
||||
|
||||
|
||||
@@ -123,7 +125,7 @@ class JavaSupportTest : GrazieTestBase() {
|
||||
)
|
||||
}
|
||||
|
||||
fun `test meaningful suggestions in RenameTo action`() {
|
||||
fun `test meaningful single suggestion in RenameTo action`() {
|
||||
myFixture.configureByText("a.java", """
|
||||
class A {
|
||||
void foo() {
|
||||
@@ -132,12 +134,32 @@ class JavaSupportTest : GrazieTestBase() {
|
||||
}
|
||||
""")
|
||||
myFixture.checkHighlighting()
|
||||
val intention = myFixture.findSingleIntention("Typo: Rename to 'targetDir'")
|
||||
myFixture.launchAction(intention)
|
||||
myFixture.checkResult("""
|
||||
class A {
|
||||
void foo() {
|
||||
int targetDir = 1;
|
||||
}
|
||||
}
|
||||
""")
|
||||
}
|
||||
|
||||
fun `test multiple suggestions in RenameTo action`() {
|
||||
myFixture.configureByText("a.java", """
|
||||
class A {
|
||||
void foo() {
|
||||
int <TYPO descr="Typo: In word 'barek'">barek<caret></TYPO> = 1;
|
||||
}
|
||||
}
|
||||
""")
|
||||
myFixture.checkHighlighting()
|
||||
val intention = myFixture.findSingleIntention("Typo: Rename to…")
|
||||
myFixture.launchAction(intention)
|
||||
myFixture.checkResult("""
|
||||
class A {
|
||||
void foo() {
|
||||
int targetDir = 1;
|
||||
int bark = 1;
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
+5
-3
@@ -19,6 +19,8 @@ import com.intellij.spellchecker.quickfixes.ChangeTo;
|
||||
import com.intellij.spellchecker.quickfixes.RenameTo;
|
||||
import com.intellij.spellchecker.quickfixes.SaveTo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlainTextSpellCheckerFixesTest extends AbstractSpellCheckerFixesTest {
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
@@ -54,7 +56,7 @@ public class PlainTextSpellCheckerFixesTest extends AbstractSpellCheckerFixesTes
|
||||
}
|
||||
|
||||
public void testEmptyRenameTo() {
|
||||
doNoQuickFixTest(RenameTo.getFixName());
|
||||
doNoQuickFixTest(RenameTo.getFixName(List.of()));
|
||||
}
|
||||
|
||||
public void testEmptySaveTo() {
|
||||
@@ -66,10 +68,10 @@ public class PlainTextSpellCheckerFixesTest extends AbstractSpellCheckerFixesTes
|
||||
}
|
||||
|
||||
public void testNoTypoRenameTo() {
|
||||
doNoQuickFixTest(RenameTo.getFixName());
|
||||
doNoQuickFixTest(RenameTo.getFixName(List.of()));
|
||||
}
|
||||
|
||||
public void testSimpleWordRenameTo() {
|
||||
doNoQuickFixTest(RenameTo.getFixName());
|
||||
doNoQuickFixTest(RenameTo.getFixName(List.of()));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,6 +23,6 @@ class PropertyRenameToTest : BasePlatformTestCase() {
|
||||
myFixture.configureByText("a.properties", "<TYPO descr=\"Typo: In word 'helloworld'\">hellow<caret>orld</TYPO>=value")
|
||||
myFixture.enableInspections(GrazieSpellCheckingInspection())
|
||||
myFixture.checkHighlighting()
|
||||
myFixture.getAvailableIntention("Typo: Rename to…") ?: error("RenameTo intention is not available")
|
||||
myFixture.getAvailableIntention("Typo: Rename to 'hello-world'") ?: error("RenameTo intention is not available")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
change.to.title=Fix typo
|
||||
change.to.tooltip=Replace with ''{0}''
|
||||
rename.to=Typo: Rename to\u2026
|
||||
rename.to.0=Typo: Rename to ''{0}''
|
||||
proofread=Proofreading
|
||||
spelling=Spelling
|
||||
spellchecking.inspection.name=Spelling
|
||||
|
||||
@@ -3,8 +3,10 @@ package com.intellij.spellchecker.quickfixes;
|
||||
|
||||
import com.intellij.codeInsight.intention.EventTrackingIntentionAction;
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewUtils;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
|
||||
import com.intellij.codeInspection.IntentionAndQuickFixAction;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
@@ -12,7 +14,9 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.rename.RenameUtil;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.RefactoringActionHandlerFactory;
|
||||
import com.intellij.refactoring.rename.*;
|
||||
import com.intellij.spellchecker.SpellCheckerManager;
|
||||
import com.intellij.spellchecker.statistics.SpellcheckerActionStatistics;
|
||||
import com.intellij.spellchecker.statistics.SpellcheckerRateTracker;
|
||||
@@ -23,16 +27,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class RenameTo extends PsiUpdateModCommandQuickFix implements Iconable, EventTrackingIntentionAction {
|
||||
public class RenameTo extends IntentionAndQuickFixAction implements Iconable, EventTrackingIntentionAction {
|
||||
|
||||
private final String typo;
|
||||
private final TextRange range;
|
||||
private final SmartPsiElementPointer<PsiElement> pointer;
|
||||
private final SpellcheckerRateTracker tracker;
|
||||
private final List<String> suggestions = new ArrayList<>();
|
||||
private final SequencedSet<String> suggestions = new LinkedHashSet<>();
|
||||
private SmartPsiElementPointer<PsiElement> namedPointer;
|
||||
|
||||
public RenameTo(String typo, TextRange range, PsiElement psi, SpellcheckerRateTracker tracker) {
|
||||
this.typo = typo;
|
||||
@@ -42,16 +46,50 @@ public class RenameTo extends PsiUpdateModCommandQuickFix implements Iconable, E
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return getFixName();
|
||||
public boolean isAvailable(@NotNull Project project, @Nullable Editor editor, PsiFile psiFile) {
|
||||
PsiElement element = Objects.requireNonNull(pointer.getElement());
|
||||
var presentationName = getPresentationName(element);
|
||||
if (presentationName == null) return false;
|
||||
generateSuggestions(presentationName.getSecond(), element);
|
||||
this.namedPointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(presentationName.getFirst());
|
||||
if (suggestions.isEmpty()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyFix(@NotNull Project project, @NotNull PsiElement psiElement, @NotNull ModPsiUpdater updater) {
|
||||
var name = getPresentationName(psiElement);
|
||||
if (name == null) return;
|
||||
generateSuggestions(name.second, psiElement);
|
||||
updater.rename(name.first, psiElement, suggestions);
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return getFixName(suggestions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return getFixName(suggestions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, PsiFile psiFile, @Nullable Editor editor) {
|
||||
PsiElement element = namedPointer.getElement() == null ? null : namedPointer.getElement();
|
||||
if (element == null) return;
|
||||
|
||||
if (suggestions.size() == 1) {
|
||||
runRenamer(element, suggestions.getFirst());
|
||||
}
|
||||
else {
|
||||
var context = DataManager.getInstance().getDataContext(editor.getContentComponent());
|
||||
DataContext contextWithSuggestions = dataId -> {
|
||||
if (PsiElementRenameHandler.NAME_SUGGESTIONS.is(dataId)) return new ArrayList<>(suggestions);
|
||||
if (PlatformCoreDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) return new PsiElement[]{element};
|
||||
return context.getData(dataId);
|
||||
};
|
||||
RefactoringActionHandler handler = getRenameHandler(contextWithSuggestions);
|
||||
handler.invoke(project, editor, psiFile, contextWithSuggestions);
|
||||
}
|
||||
|
||||
if (!IntentionPreviewUtils.isIntentionPreviewActive()) {
|
||||
SpellcheckerActionStatistics.renameToPerformed(tracker, suggestions.size());
|
||||
}
|
||||
@@ -64,8 +102,10 @@ public class RenameTo extends PsiUpdateModCommandQuickFix implements Iconable, E
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nls String getFixName() {
|
||||
return SpellCheckerBundle.message("rename.to");
|
||||
public static @Nls String getFixName(SequencedCollection<String> suggestions) {
|
||||
return suggestions.size() == 1 ?
|
||||
SpellCheckerBundle.message("rename.to.0", suggestions.getFirst()) :
|
||||
SpellCheckerBundle.message("rename.to");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,6 +123,12 @@ public class RenameTo extends PsiUpdateModCommandQuickFix implements Iconable, E
|
||||
return new Pair<>(namedElement, name);
|
||||
}
|
||||
|
||||
private static RefactoringActionHandler getRenameHandler(DataContext dataContext) {
|
||||
RenameHandler handler = RenameHandlerRegistry.getInstance().getRenameHandler(dataContext);
|
||||
if (handler == null) return RefactoringActionHandlerFactory.getInstance().createRenameHandler();
|
||||
return handler;
|
||||
}
|
||||
|
||||
private void generateSuggestions(String name, PsiElement element) {
|
||||
if (suggestions.isEmpty()) {
|
||||
TextRange range = this.range.shiftLeft(element.getText().indexOf(name));
|
||||
@@ -93,4 +139,8 @@ public class RenameTo extends PsiUpdateModCommandQuickFix implements Iconable, E
|
||||
.forEach(suggestions::add);
|
||||
}
|
||||
}
|
||||
|
||||
private void runRenamer(PsiElement element, String suggestion) {
|
||||
new RenameProcessor(pointer.getProject(), element, suggestion, true, true).run();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user