From 1cadb8a667c94d39493824b76841a9fce3e6f128 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 9 May 2025 12:21:49 +0200 Subject: [PATCH] [java-refactoring] Inline delegating variable: an ability to keep the current variable name Fixes IDEA-371649 Inline variable using the later name GitOrigin-RevId: a31d332762af3721245af31841562ff48a0cb3a9 --- .../inline/InlineLocalHandler.java | 68 +++++++++++++++---- .../intellij/refactoring/util/InlineUtil.java | 10 +++ .../util/CommonJavaInlineUtil.java | 7 ++ .../com/siyeh/ig/fixes/InlineVariableFix.java | 43 +++--------- ....after.java => afterArrayInitializer.java} | 1 + ...Needed.after.java => afterCastNeeded.java} | 1 + .../{Comment.after.java => afterComment.java} | 1 + ...=> afterInlineInsideSwitchExpression.java} | 3 +- ...er.java => afterNewLineInInitializer.java} | 3 +- ...ceVar.after.java => afterResourceVar.java} | 1 + ...ter.java => afterResourceVarInMiddle.java} | 1 + ...after.java => afterSingleResourceVar.java} | 1 + .../igfixes/inline/afterTwoVarsNormal.java | 19 ++++++ .../igfixes/inline/afterTwoVarsRename.java | 19 ++++++ .../inline/afterTwoVarsRenameUsed.java | 20 ++++++ ...lizer.java => beforeArrayInitializer.java} | 1 + ...loads.java => beforeCastForOverloads.java} | 1 + ...{CastNeeded.java => beforeCastNeeded.java} | 1 + .../{Comment.java => beforeComment.java} | 1 + ...> beforeInlineInsideSwitchExpression.java} | 1 + ...r.java => beforeNewLineInInitializer.java} | 1 + ...esourceVar.java => beforeResourceVar.java} | 1 + ...le.java => beforeResourceVarInMiddle.java} | 1 + ...eVar.java => beforeSingleResourceVar.java} | 1 + .../igfixes/inline/beforeTwoVarsNormal.java | 20 ++++++ .../igfixes/inline/beforeTwoVarsRename.java | 20 ++++++ .../inline/beforeTwoVarsRenameUsed.java | 21 ++++++ .../siyeh/ig/fixes/InlineVariableFixTest.java | 36 ++++------ .../messages/RefactoringBundle.properties | 2 + 29 files changed, 236 insertions(+), 70 deletions(-) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{ArrayInitializer.after.java => afterArrayInitializer.java} (77%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{CastNeeded.after.java => afterCastNeeded.java} (75%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{Comment.after.java => afterComment.java} (67%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{InlineInsideSwitchExpression.after.java => afterInlineInsideSwitchExpression.java} (73%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{NewLineInInitializer.after.java => afterNewLineInInitializer.java} (70%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{ResourceVar.after.java => afterResourceVar.java} (80%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{ResourceVarInMiddle.after.java => afterResourceVarInMiddle.java} (83%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{SingleResourceVar.after.java => afterSingleResourceVar.java} (80%) create mode 100644 java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsNormal.java create mode 100644 java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRename.java create mode 100644 java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRenameUsed.java rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{ArrayInitializer.java => beforeArrayInitializer.java} (79%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{CastForOverloads.java => beforeCastForOverloads.java} (89%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{CastNeeded.java => beforeCastNeeded.java} (77%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{Comment.java => beforeComment.java} (72%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{InlineInsideSwitchExpression.java => beforeInlineInsideSwitchExpression.java} (85%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{NewLineInInitializer.java => beforeNewLineInInitializer.java} (87%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{ResourceVar.java => beforeResourceVar.java} (83%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{ResourceVarInMiddle.java => beforeResourceVarInMiddle.java} (85%) rename java/java-tests/testData/ig/com/siyeh/igfixes/inline/{SingleResourceVar.java => beforeSingleResourceVar.java} (85%) create mode 100644 java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsNormal.java create mode 100644 java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRename.java create mode 100644 java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRenameUsed.java diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/inline/InlineLocalHandler.java index 735ccc23b874..93426955a4cf 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/inline/InlineLocalHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/inline/InlineLocalHandler.java @@ -16,6 +16,7 @@ import com.intellij.openapi.util.NlsContexts; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.controlFlow.AnalysisCanceledException; +import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.controlFlow.DefUseUtil; import com.intellij.psi.util.JavaPsiPatternUtil; import com.intellij.psi.util.PsiTreeUtil; @@ -41,13 +42,17 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import static java.util.Objects.requireNonNull; + public final class InlineLocalHandler extends JavaInlineActionHandler { - private enum InlineMode { + public enum InlineMode { CHECK_CONFLICTS, ASK, HIGHLIGHT_CONFLICTS, INLINE_ONE, - INLINE_ALL_AND_DELETE + INLINE_ALL_AND_DELETE, + INLINE_ALL_KEEP_OLD_NAME, // the same as INLINE_ALL_AND_DELETE, just display different name + INLINE_ALL_RENAME_INITIALIZER } private static final Logger LOG = Logger.getInstance(InlineLocalHandler.class); @@ -104,10 +109,10 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { return doInline(context, (PsiVariable)Objects.requireNonNull(context.element()), refExpr, mode); } - private static ModCommand doInline(@NotNull ActionContext context, - @NotNull PsiVariable var, - @Nullable PsiReferenceExpression refExpr, - @NotNull InlineMode mode) { + public static @NotNull ModCommand doInline(@NotNull ActionContext context, + @NotNull PsiVariable var, + @Nullable PsiReferenceExpression refExpr, + @NotNull InlineMode mode) { List allRefs = refExpr != null && mode == InlineMode.INLINE_ONE ? List.of(refExpr) : VariableAccessUtils.getVariableReferences(var); @@ -160,6 +165,13 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { new InlineLocalStep(variable, refExpr, InlineMode.INLINE_ALL_AND_DELETE, allRefs)); } + private static @NotNull ModCommand createRenameChooser(@NotNull PsiVariable variable, + @NotNull List allRefs) { + return ModCommand.chooseAction(getRefactoringName(variable), + new InlineLocalStep(variable, null, InlineMode.INLINE_ALL_KEEP_OLD_NAME, allRefs), + new InlineLocalStep(variable, null, InlineMode.INLINE_ALL_RENAME_INITIALIZER, allRefs)); + } + private static ModCommand createConflictChooser(PsiLocalVariable variable, PsiReferenceExpression refExpr, @@ -238,9 +250,18 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { } } - if (mode == InlineMode.ASK && refExpr != null && refsToInlineList.size() > 1 && refsToInlineList.contains(refExpr) && - EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog()) { - return createChooser(local, refExpr, refsToInlineList); + if (mode == InlineMode.ASK) { + if (refExpr != null && refsToInlineList.size() > 1 && refsToInlineList.contains(refExpr) && + EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog()) { + return createChooser(local, refExpr, refsToInlineList); + } + if (defToInline == local.getInitializer() && PsiUtil.skipParenthesizedExprDown(defToInline) instanceof PsiReferenceExpression ref && + ControlFlowUtil.isEffectivelyFinal(local, containerBlock)) { + PsiElement target = ref.resolve(); + if (PsiUtil.isJvmLocalVariable(target)) { + return createRenameChooser(local, refsToInlineList); + } + } } final PsiElement[] refsToInline = PsiUtilCore.toPsiElementArray(refsToInlineList); @@ -302,6 +323,11 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { } Project project = context.project(); + if (mode == InlineMode.INLINE_ALL_RENAME_INITIALIZER && + PsiUtil.skipParenthesizedExprDown(defToInline) instanceof PsiReferenceExpression ref && + ref.resolve() instanceof PsiVariable nextVar) { + return ModCommand.psiUpdate(context, updater -> renameNextVariable(local, nextVar, updater)); + } boolean inlineAll = mode != InlineMode.INLINE_ONE; return ModCommand.psiUpdate(context, updater -> { PsiExpression writableDef = updater.getWritable(defToInline); @@ -339,6 +365,18 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { }); } + private static void renameNextVariable(@NotNull PsiLocalVariable local, @NotNull PsiVariable nextVar, @NotNull ModPsiUpdater updater) { + PsiVariable writableNextVar = updater.getWritable(nextVar); + List refs = VariableAccessUtils.getVariableReferences(writableNextVar); + new CommentTracker().deleteAndRestoreComments(updater.getWritable(local)); + writableNextVar.setName(local.getName()); + for (PsiReferenceExpression nextVarRef : refs) { + if (nextVarRef.isValid()) { + nextVarRef.handleElementRename(local.getName()); + } + } + } + private record InnerClassUsages(List innerClassesWithUsages, List innerClassUsages) { private static @NotNull InnerClassUsages getUsages(@NotNull PsiLocalVariable local, @NotNull List allRefs) { final List innerClassesWithUsages = new ArrayList<>(); @@ -510,16 +548,16 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { } private static class InlineLocalStep implements ModCommandAction { - private final @NotNull PsiVariable myPattern; + private final @NotNull PsiVariable myVariable; private final @Nullable PsiReferenceExpression myRefExpr; private final @NotNull InlineMode myMode; private final @NotNull Collection myAllRefs; - private InlineLocalStep(@NotNull PsiVariable pattern, + private InlineLocalStep(@NotNull PsiVariable variable, @Nullable PsiReferenceExpression refExpr, @NotNull InlineMode mode, @NotNull Collection allRefs) { - myPattern = pattern; + myVariable = variable; myRefExpr = refExpr; myMode = mode; myAllRefs = allRefs; @@ -531,7 +569,7 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { return ModCommand.highlight(myAllRefs.toArray(PsiElement.EMPTY_ARRAY)).andThen( myAllRefs.stream().findFirst().map(ModCommand::select).orElse(ModCommand.nop())); } - return doInline(context, myPattern, myRefExpr, myMode); + return doInline(context, myVariable, myRefExpr, myMode); } @Override @@ -549,6 +587,10 @@ public final class InlineLocalHandler extends JavaInlineActionHandler { case ASK -> JavaRefactoringBundle.message("inline.popup.ignore.conflicts"); case INLINE_ONE -> RefactoringBundle.message("inline.popup.this.only"); case INLINE_ALL_AND_DELETE -> RefactoringBundle.message("inline.popup.all", myAllRefs.size()); + case INLINE_ALL_KEEP_OLD_NAME -> RefactoringBundle.message("inline.popup.all.keep", requireNonNull( + PsiUtil.skipParenthesizedExprDown(myVariable.getInitializer())).getText()); + case INLINE_ALL_RENAME_INITIALIZER -> RefactoringBundle.message("inline.popup.all.rename", requireNonNull( + PsiUtil.skipParenthesizedExprDown(myVariable.getInitializer())).getText(), myVariable.getName()); default -> throw new IllegalStateException("Unexpected value: " + myMode); }; } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/util/InlineUtil.java b/java/java-impl-refactorings/src/com/intellij/refactoring/util/InlineUtil.java index 4c8dc69db7ad..6ed26efe8983 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/util/InlineUtil.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/util/InlineUtil.java @@ -7,6 +7,8 @@ import com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpressionFi import com.intellij.codeInspection.dataFlow.JavaMethodContractUtil; import com.intellij.codeInspection.redundantCast.RemoveRedundantCastUtil; import com.intellij.java.refactoring.JavaRefactoringBundle; +import com.intellij.modcommand.ActionContext; +import com.intellij.modcommand.ModCommand; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; @@ -24,6 +26,7 @@ import com.intellij.psi.util.PsiPrecedenceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.RedundantCastUtil; +import com.intellij.refactoring.inline.InlineLocalHandler; import com.intellij.refactoring.inline.InlineTransformer; import com.intellij.util.ArrayUtil; import com.intellij.util.CommonJavaRefactoringUtil; @@ -895,6 +898,13 @@ public final class InlineUtil implements CommonJavaInlineUtil { } } + @Override + public @NotNull ModCommand inline(@NotNull PsiVariable var) { + return InlineLocalHandler.doInline( + ActionContext.from(null, var.getContainingFile()), + var, null, InlineLocalHandler.InlineMode.CHECK_CONFLICTS); + } + public enum TailCallType { None(null), Simple((methodCopy, callSite, returnType) -> { diff --git a/java/java-impl/src/com/intellij/refactoring/util/CommonJavaInlineUtil.java b/java/java-impl/src/com/intellij/refactoring/util/CommonJavaInlineUtil.java index e5efd699f9d8..cc43d68ae144 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/CommonJavaInlineUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/CommonJavaInlineUtil.java @@ -1,6 +1,7 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.refactoring.util; +import com.intellij.modcommand.ModCommand; import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiJavaCodeReferenceElement; @@ -9,6 +10,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public interface CommonJavaInlineUtil { + /** + * @param var variable to inline (local variable or pattern variable) + * @return a modcommand that inlines this variable (may display UI) + */ + @NotNull ModCommand inline(@NotNull PsiVariable var); + static CommonJavaInlineUtil getInstance() { return ApplicationManager.getApplication().getService(CommonJavaInlineUtil.class); } diff --git a/java/java-impl/src/com/siyeh/ig/fixes/InlineVariableFix.java b/java/java-impl/src/com/siyeh/ig/fixes/InlineVariableFix.java index 6a7e8cbc28aa..986e5c07531f 100644 --- a/java/java-impl/src/com/siyeh/ig/fixes/InlineVariableFix.java +++ b/java/java-impl/src/com/siyeh/ig/fixes/InlineVariableFix.java @@ -15,55 +15,30 @@ */ package com.siyeh.ig.fixes; -import com.intellij.modcommand.ModPsiUpdater; -import com.intellij.modcommand.PsiUpdateModCommandQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.modcommand.ModCommand; +import com.intellij.modcommand.ModCommandQuickFix; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiLocalVariable; -import com.intellij.psi.PsiReferenceExpression; import com.intellij.refactoring.util.CommonJavaInlineUtil; import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.psiutils.CommentTracker; -import com.siyeh.ig.psiutils.VariableAccessUtils; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.Collection; - -public class InlineVariableFix extends PsiUpdateModCommandQuickFix { - +public class InlineVariableFix extends ModCommandQuickFix { @Override public @NotNull String getFamilyName() { return InspectionGadgetsBundle.message("inline.variable.quickfix"); } @Override - protected void applyFix(@NotNull Project project, @NotNull PsiElement nameElement, @NotNull ModPsiUpdater updater) { - final PsiLocalVariable variable = (PsiLocalVariable)nameElement.getParent(); + public @NotNull ModCommand perform(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiLocalVariable variable = (PsiLocalVariable)descriptor.getPsiElement().getParent(); final PsiExpression initializer = variable.getInitializer(); if (initializer == null) { - return; - } - - final Collection references = VariableAccessUtils.getVariableReferences(variable); - final Collection replacedElements = new ArrayList<>(); - for (PsiReferenceExpression reference : references) { - var inlineUtil = CommonJavaInlineUtil.getInstance(); - final PsiExpression expression = inlineUtil.inlineVariable(variable, initializer, reference, null); - replacedElements.add(expression); - } - - new CommentTracker().deleteAndRestoreComments(variable); - boolean positioned = false; - for (PsiElement element : replacedElements) { - if (element.isValid()) { - updater.highlight(element); - if (!positioned) { - positioned = true; - updater.moveCaretTo(element); - } - } + return ModCommand.nop(); } + var inlineUtil = CommonJavaInlineUtil.getInstance(); + return inlineUtil.inline(variable); } } \ No newline at end of file diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ArrayInitializer.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterArrayInitializer.java similarity index 77% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/ArrayInitializer.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterArrayInitializer.java index ce9bff7b1014..3caaca8d9429 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ArrayInitializer.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterArrayInitializer.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" package com.siyeh.igfixes.inline; class ArrayInitializer { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastNeeded.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterCastNeeded.java similarity index 75% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastNeeded.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterCastNeeded.java index d110c7bddcdd..78869b122f49 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastNeeded.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterCastNeeded.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" package com.siyeh.igfixes.inline; class CastNeeded { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/Comment.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterComment.java similarity index 67% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/Comment.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterComment.java index 5cb7d3561bbd..4b1918693a17 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/Comment.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterComment.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class Comment { Object x(String s) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/InlineInsideSwitchExpression.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterInlineInsideSwitchExpression.java similarity index 73% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/InlineInsideSwitchExpression.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterInlineInsideSwitchExpression.java index dae70e4070a0..ec99ddb5c0ff 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/InlineInsideSwitchExpression.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterInlineInsideSwitchExpression.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" import java.util.List; public class Demo { @@ -5,7 +6,7 @@ public class Demo { public static void main(String[] args) { var y = switch (1) { case 1: - yield 3; + yield 3; default: yield 4; }; diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/NewLineInInitializer.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterNewLineInInitializer.java similarity index 70% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/NewLineInInitializer.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterNewLineInInitializer.java index f8f11f3e6838..e75b1df1eb92 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/NewLineInInitializer.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterNewLineInInitializer.java @@ -1,8 +1,9 @@ +// "Inline variable" "true-preview" import java.util.List; public class Demo { List test(List list) { - return list.stream() + return list.stream() .map(String::toUpperCase) .map(String::trim) .toList(); diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVar.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterResourceVar.java similarity index 80% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVar.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterResourceVar.java index 24cd863e2df5..9af13e877156 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVar.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterResourceVar.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class C { void m() throws Exception { try (AutoCloseable r1 = null) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVarInMiddle.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterResourceVarInMiddle.java similarity index 83% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVarInMiddle.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterResourceVarInMiddle.java index 9934c8095502..f54ebee7324f 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVarInMiddle.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterResourceVarInMiddle.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class C { void m() throws Exception { try (AutoCloseable r1 = null; AutoCloseable r3 = null) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/SingleResourceVar.after.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterSingleResourceVar.java similarity index 80% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/SingleResourceVar.after.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterSingleResourceVar.java index 24cd863e2df5..9af13e877156 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/SingleResourceVar.after.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterSingleResourceVar.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class C { void m() throws Exception { try (AutoCloseable r1 = null) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsNormal.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsNormal.java new file mode 100644 index 000000000000..272cabad39a4 --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsNormal.java @@ -0,0 +1,19 @@ +// "Inline variable|->Keep the 'vExposure' variable" "true-preview" +package com.example; + +import java.util.ArrayList; +import java.util.List; + +public class Demo { + static class ExposureSpecification { + } + + public static void main(String[] args) { + List vExposures = new ArrayList<>(); + + for (ExposureSpecification vExposure : vExposures) { + // ... lines of code using exp ... + System.out.println(vExposure); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRename.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRename.java new file mode 100644 index 000000000000..352080291f1a --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRename.java @@ -0,0 +1,19 @@ +// "Inline variable|->Inline and rename 'vExposure' to 'exp'" "true-preview" +package com.example; + +import java.util.ArrayList; +import java.util.List; + +public class Demo { + static class ExposureSpecification { + } + + public static void main(String[] args) { + List vExposures = new ArrayList<>(); + + for (ExposureSpecification exp : vExposures) { + // ... lines of code using exp ... + System.out.println(exp); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRenameUsed.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRenameUsed.java new file mode 100644 index 000000000000..8369513dc46b --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/afterTwoVarsRenameUsed.java @@ -0,0 +1,20 @@ +// "Inline variable|->Inline and rename 'vExposure' to 'exp'" "true-preview" +package com.example; + +import java.util.ArrayList; +import java.util.List; + +public class Demo { + static class ExposureSpecification { + } + + public static void main(String[] args) { + List vExposures = new ArrayList<>(); + + for (ExposureSpecification exp : vExposures) { + System.out.println(exp); + // ... lines of code using exp ... + System.out.println(exp); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ArrayInitializer.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeArrayInitializer.java similarity index 79% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/ArrayInitializer.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeArrayInitializer.java index b213e0c931ab..e6681f8d4d09 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ArrayInitializer.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeArrayInitializer.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" package com.siyeh.igfixes.inline; class ArrayInitializer { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastForOverloads.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeCastForOverloads.java similarity index 89% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastForOverloads.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeCastForOverloads.java index 868dd3e79d68..5276c65997fd 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastForOverloads.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeCastForOverloads.java @@ -1,3 +1,4 @@ +// "Inline variable" "false" class Base { { Descendant descendant = new Descendant(); diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastNeeded.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeCastNeeded.java similarity index 77% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastNeeded.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeCastNeeded.java index 947cfdc1e1b0..fe9bc0d5c5e1 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/CastNeeded.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeCastNeeded.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" package com.siyeh.igfixes.inline; class CastNeeded { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/Comment.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeComment.java similarity index 72% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/Comment.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeComment.java index fb9dbcc0395a..75da2266ded5 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/Comment.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeComment.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class Comment { Object x(String s) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/InlineInsideSwitchExpression.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeInlineInsideSwitchExpression.java similarity index 85% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/InlineInsideSwitchExpression.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeInlineInsideSwitchExpression.java index 5160355f3497..379f03885a1a 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/InlineInsideSwitchExpression.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeInlineInsideSwitchExpression.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" import java.util.List; public class Demo { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/NewLineInInitializer.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeNewLineInInitializer.java similarity index 87% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/NewLineInInitializer.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeNewLineInInitializer.java index 185887f6c4be..8b911a7c1dbe 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/NewLineInInitializer.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeNewLineInInitializer.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" import java.util.List; public class Demo { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVar.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeResourceVar.java similarity index 83% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVar.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeResourceVar.java index 8f2e9f9ebe3c..a2ba23d6b474 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVar.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeResourceVar.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class C { void m() throws Exception { try (AutoCloseable r1 = null; AutoCloseable r2 = r1) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVarInMiddle.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeResourceVarInMiddle.java similarity index 85% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVarInMiddle.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeResourceVarInMiddle.java index 0e42fb6f20a7..403bd9d837f0 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/ResourceVarInMiddle.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeResourceVarInMiddle.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class C { void m() throws Exception { try (AutoCloseable r1 = null; AutoCloseable r2 = r1; AutoCloseable r3 = null) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/SingleResourceVar.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeSingleResourceVar.java similarity index 85% rename from java/java-tests/testData/ig/com/siyeh/igfixes/inline/SingleResourceVar.java rename to java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeSingleResourceVar.java index 2beda8475778..58b30b27801f 100644 --- a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/SingleResourceVar.java +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeSingleResourceVar.java @@ -1,3 +1,4 @@ +// "Inline variable" "true-preview" class C { void m() throws Exception { try (AutoCloseable r1 = null) { diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsNormal.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsNormal.java new file mode 100644 index 000000000000..688d2c15cee8 --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsNormal.java @@ -0,0 +1,20 @@ +// "Inline variable|->Keep the 'vExposure' variable" "true-preview" +package com.example; + +import java.util.ArrayList; +import java.util.List; + +public class Demo { + static class ExposureSpecification { + } + + public static void main(String[] args) { + List vExposures = new ArrayList<>(); + + for (ExposureSpecification vExposure : vExposures) { + ExposureSpecification exp = vExposure; + // ... lines of code using exp ... + System.out.println(exp); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRename.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRename.java new file mode 100644 index 000000000000..d1dd6e2a8c5c --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRename.java @@ -0,0 +1,20 @@ +// "Inline variable|->Inline and rename 'vExposure' to 'exp'" "true-preview" +package com.example; + +import java.util.ArrayList; +import java.util.List; + +public class Demo { + static class ExposureSpecification { + } + + public static void main(String[] args) { + List vExposures = new ArrayList<>(); + + for (ExposureSpecification vExposure : vExposures) { + ExposureSpecification exp = vExposure; + // ... lines of code using exp ... + System.out.println(exp); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRenameUsed.java b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRenameUsed.java new file mode 100644 index 000000000000..493f09bb6673 --- /dev/null +++ b/java/java-tests/testData/ig/com/siyeh/igfixes/inline/beforeTwoVarsRenameUsed.java @@ -0,0 +1,21 @@ +// "Inline variable|->Inline and rename 'vExposure' to 'exp'" "true-preview" +package com.example; + +import java.util.ArrayList; +import java.util.List; + +public class Demo { + static class ExposureSpecification { + } + + public static void main(String[] args) { + List vExposures = new ArrayList<>(); + + for (ExposureSpecification vExposure : vExposures) { + System.out.println(vExposure); + ExposureSpecification exp = vExposure; + // ... lines of code using exp ... + System.out.println(exp); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/siyeh/ig/fixes/InlineVariableFixTest.java b/java/java-tests/testSrc/com/siyeh/ig/fixes/InlineVariableFixTest.java index d2d93ea6cf56..9ea522d1ca0a 100644 --- a/java/java-tests/testSrc/com/siyeh/ig/fixes/InlineVariableFixTest.java +++ b/java/java-tests/testSrc/com/siyeh/ig/fixes/InlineVariableFixTest.java @@ -1,33 +1,27 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.siyeh.ig.fixes; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.IGQuickFixesTestCase; +import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.testFramework.LightProjectDescriptor; import com.siyeh.ig.dataflow.UnnecessaryLocalVariableInspection; +import org.jetbrains.annotations.NotNull; -public class InlineVariableFixTest extends IGQuickFixesTestCase { +import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_21; + +public class InlineVariableFixTest extends LightQuickFixParameterizedTestCase { @Override - public void setUp() throws Exception { - super.setUp(); - myFixture.enableInspections(new UnnecessaryLocalVariableInspection()); - myRelativePath = "inline"; - myDefaultHint = InspectionGadgetsBundle.message("inline.variable.quickfix"); + protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { + return new UnnecessaryLocalVariableInspection[] {new UnnecessaryLocalVariableInspection()}; } @Override - protected void tuneFixture(final JavaModuleFixtureBuilder builder) throws Exception { - builder.setLanguageLevel(LanguageLevel.JDK_21); + protected @NotNull LightProjectDescriptor getProjectDescriptor() { + return JAVA_21; } - public void testResourceVar() { doTest(); } - public void testResourceVarInMiddle() { doTest(); } - public void testSingleResourceVar() { doTest(); } - public void testCastNeeded() { doTest(); } - public void testArrayInitializer() { doTest(); } - public void testCastForOverloads() { assertQuickfixNotAvailable(); } - public void testComment() { doTest(); } - public void testNewLineInInitializer() { doTest(); } - public void testInlineInsideSwitchExpression() { doTest(); } + @Override + protected String getBasePath() { + return "/ig/com/siyeh/igfixes/inline"; + } } diff --git a/platform/refactoring/resources/messages/RefactoringBundle.properties b/platform/refactoring/resources/messages/RefactoringBundle.properties index 2afa97265dfa..675368968c1b 100644 --- a/platform/refactoring/resources/messages/RefactoringBundle.properties +++ b/platform/refactoring/resources/messages/RefactoringBundle.properties @@ -230,6 +230,8 @@ all.references.and.remove.the.local=Inline &all references and remove the variab this.reference.only.and.keep.the.variable=Inline this reference only and &keep the variable inline.popup.this.only=This reference only inline.popup.all=All {0} references and remove the variable +inline.popup.all.keep=Keep the ''{0}'' variable +inline.popup.all.rename=Inline and rename ''{0}'' to ''{1}'' inline.variable.title=Inline Variable variable.is.referenced.in.multiple.files=Variable {0} is referenced in multiple files inline.command=Inline {0}