mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 14:01:44 +07:00
[java-intentions] Remove unused assignment/initializer: preview-friendly
GitOrigin-RevId: de9da180223f231638eb51804b7ed9c26c36d772
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7e1064ea3c
commit
1361a10017
@@ -41,6 +41,13 @@ public final class RemoveUnusedVariableUtil {
|
||||
return !writes.isEmpty();
|
||||
}
|
||||
|
||||
public static RemoveMode getModeForPreview(PsiExpression element, @Nullable PsiVariable variableToIgnore) {
|
||||
List<PsiElement> sideEffects = new ArrayList<>();
|
||||
boolean hasSideEffects = checkSideEffects(element, variableToIgnore, sideEffects);
|
||||
if (!hasSideEffects || sideEffects.isEmpty()) return RemoveMode.DELETE_ALL;
|
||||
return RemoveMode.MAKE_STATEMENT;
|
||||
}
|
||||
|
||||
public static PsiElement replaceElementWithExpression(PsiExpression expression,
|
||||
PsiElementFactory factory,
|
||||
PsiElement element) throws IncorrectOperationException {
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
|
||||
import com.intellij.codeInsight.editorActions.DeclarationJoinLinesHandler;
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -36,15 +39,8 @@ public class RemoveAssignmentFix extends RemoveInitializerFix {
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
final PsiElement parent;
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
parent = element.getParent();
|
||||
} else {
|
||||
parent = element;
|
||||
}
|
||||
if (!(parent instanceof PsiAssignmentExpression)) return;
|
||||
|
||||
PsiAssignmentExpression parentExpr = (PsiAssignmentExpression)parent;
|
||||
PsiAssignmentExpression parentExpr = getAssignment(descriptor);
|
||||
if (parentExpr == null) return;
|
||||
PsiElement gParentExpr = parentExpr.getParent();
|
||||
PsiExpression initializer = getInitializer(parentExpr);
|
||||
if (initializer == null) return;
|
||||
@@ -63,9 +59,37 @@ public class RemoveAssignmentFix extends RemoveInitializerFix {
|
||||
PsiElement resolve = resolveExpression(element, parentExpr);
|
||||
if (!(resolve instanceof PsiVariable)) return;
|
||||
|
||||
sideEffectAwareRemove(project, initializer, parent, (PsiVariable)resolve);
|
||||
sideEffectAwareRemove(project, initializer, parentExpr, (PsiVariable)resolve);
|
||||
}
|
||||
|
||||
PsiAssignmentExpression getAssignment(@NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
final PsiElement parent = element instanceof PsiReferenceExpression ? element.getParent() : element;
|
||||
return ObjectUtils.tryCast(parent, PsiAssignmentExpression.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull ProblemDescriptor previewDescriptor) {
|
||||
final PsiElement element = previewDescriptor.getPsiElement();
|
||||
PsiAssignmentExpression parentExpr = getAssignment(previewDescriptor);
|
||||
if (parentExpr == null) return IntentionPreviewInfo.EMPTY;
|
||||
PsiElement gParentExpr = parentExpr.getParent();
|
||||
PsiExpression initializer = getInitializer(parentExpr);
|
||||
if (initializer == null) return IntentionPreviewInfo.EMPTY;
|
||||
if (mayBeFixedWithoutSideEffect(gParentExpr)) {
|
||||
PsiElement target = gParentExpr instanceof PsiParenthesizedExpression ? gParentExpr : parentExpr;
|
||||
target.replace(initializer);
|
||||
return IntentionPreviewInfo.DIFF;
|
||||
}
|
||||
PsiVariable resolve = ObjectUtils.tryCast(resolveExpression(element, parentExpr), PsiVariable.class);
|
||||
if (resolve == null) return IntentionPreviewInfo.EMPTY;
|
||||
|
||||
RemoveUnusedVariableUtil.RemoveMode res = RemoveUnusedVariableUtil.getModeForPreview(initializer, resolve);
|
||||
doRemove(project, initializer, parentExpr, resolve, resolve.getParent(), res);
|
||||
return IntentionPreviewInfo.DIFF;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static PsiExpression getInitializer(@NotNull PsiAssignmentExpression assignmentExpr) {
|
||||
final IElementType operationSign = assignmentExpr.getOperationTokenType();
|
||||
|
||||
@@ -19,15 +19,16 @@ import com.intellij.codeInsight.BlockUtils;
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiExpressionTrimRenderer;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -36,7 +37,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoveInitializerFix implements LocalQuickFix {
|
||||
private static final Logger LOG = Logger.getInstance(RemoveInitializerFix.class);
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@@ -96,38 +96,56 @@ public class RemoveInitializerFix implements LocalQuickFix {
|
||||
else {
|
||||
res = RemoveUnusedVariableUtil.RemoveMode.DELETE_ALL;
|
||||
}
|
||||
WriteAction.run(() -> {
|
||||
if (res == RemoveUnusedVariableUtil.RemoveMode.DELETE_ALL) {
|
||||
if (elementToDelete instanceof PsiExpression && !ExpressionUtils.isVoidContext((PsiExpression)elementToDelete) &&
|
||||
!PsiTreeUtil.isAncestor(variable, elementToDelete, true)) {
|
||||
String name = variable.getName();
|
||||
if (name != null) {
|
||||
new CommentTracker().replaceAndRestoreComments(elementToDelete, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
elementToDelete.delete();
|
||||
}
|
||||
else if (res == RemoveUnusedVariableUtil.RemoveMode.MAKE_STATEMENT) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiStatement statementFromText = factory.createStatementFromText(psiInitializer.getText() + ";", null);
|
||||
final PsiElement parent = elementToDelete.getParent();
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
parent.replace(statementFromText);
|
||||
}
|
||||
else {
|
||||
elementToDelete.delete();
|
||||
if (declaration instanceof PsiClass) {
|
||||
PsiClassInitializer initializer = factory.createClassInitializer();
|
||||
initializer = (PsiClassInitializer)declaration.addAfter(initializer, variable);
|
||||
initializer.getBody().add(statementFromText);
|
||||
return;
|
||||
}
|
||||
PsiElement grandParent = declaration.getParent();
|
||||
BlockUtils.addBefore(((PsiStatement) (grandParent instanceof PsiForStatement ? grandParent : declaration)), statementFromText);
|
||||
}
|
||||
}
|
||||
});
|
||||
WriteAction.run(() -> doRemove(project, psiInitializer, elementToDelete, variable, declaration, res));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull ProblemDescriptor previewDescriptor) {
|
||||
PsiExpression psiInitializer = ObjectUtils.tryCast(previewDescriptor.getPsiElement(), PsiExpression.class);
|
||||
if (psiInitializer == null) return IntentionPreviewInfo.EMPTY;
|
||||
PsiVariable variable = ObjectUtils.tryCast(psiInitializer.getParent(), PsiVariable.class);
|
||||
if (variable == null) return IntentionPreviewInfo.EMPTY;
|
||||
RemoveUnusedVariableUtil.RemoveMode res = RemoveUnusedVariableUtil.getModeForPreview(psiInitializer, variable);
|
||||
doRemove(project, psiInitializer, psiInitializer, variable, variable.getParent(), res);
|
||||
return IntentionPreviewInfo.DIFF;
|
||||
}
|
||||
|
||||
static void doRemove(@NotNull Project project,
|
||||
@NotNull PsiExpression psiInitializer,
|
||||
@NotNull PsiElement elementToDelete,
|
||||
@NotNull PsiVariable variable,
|
||||
PsiElement declaration,
|
||||
@NotNull RemoveUnusedVariableUtil.RemoveMode res) {
|
||||
if (res == RemoveUnusedVariableUtil.RemoveMode.DELETE_ALL) {
|
||||
if (elementToDelete instanceof PsiExpression && !ExpressionUtils.isVoidContext((PsiExpression)elementToDelete) &&
|
||||
!PsiTreeUtil.isAncestor(variable, elementToDelete, true)) {
|
||||
String name = variable.getName();
|
||||
if (name != null) {
|
||||
new CommentTracker().replaceAndRestoreComments(elementToDelete, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
elementToDelete.delete();
|
||||
}
|
||||
else if (res == RemoveUnusedVariableUtil.RemoveMode.MAKE_STATEMENT) {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiStatement statementFromText = factory.createStatementFromText(psiInitializer.getText() + ";", null);
|
||||
final PsiElement parent = elementToDelete.getParent();
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
parent.replace(statementFromText);
|
||||
}
|
||||
else {
|
||||
elementToDelete.delete();
|
||||
if (declaration instanceof PsiClass) {
|
||||
PsiClassInitializer initializer = factory.createClassInitializer();
|
||||
initializer = (PsiClassInitializer)declaration.addAfter(initializer, variable);
|
||||
initializer.getBody().add(statementFromText);
|
||||
return;
|
||||
}
|
||||
PsiElement grandParent = declaration.getParent();
|
||||
BlockUtils.addBefore(((PsiStatement)(grandParent instanceof PsiForStatement ? grandParent : declaration)), statementFromText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
public String getContexts(final String env) {
|
||||
String contexts = "a";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class Test {
|
||||
void foo() {
|
||||
String var;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
static int n;
|
||||
static {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class Foo {
|
||||
int sent;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant initializer" "true"
|
||||
// "Remove redundant initializer" "true-preview"
|
||||
class A {
|
||||
int n;
|
||||
{ n = 1; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant initializer" "true"
|
||||
// "Remove redundant initializer" "true-preview"
|
||||
class A {
|
||||
private String myFoo;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class X {
|
||||
void test(boolean b) {
|
||||
if (b) {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant initializer" "true"
|
||||
// "Remove redundant initializer" "true-preview"
|
||||
class A {
|
||||
void testFor() {
|
||||
if (true) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
int v() {
|
||||
int x;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
public static void main(String[] args) {
|
||||
int x = 3 * 4;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class Foo {
|
||||
void bar(int begin) {
|
||||
int current;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
void m() {
|
||||
int i;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
void m(int i) {
|
||||
i = 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
record R2(int y) {
|
||||
public R2 {
|
||||
this.y = y;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
A a = null;
|
||||
String m(String str) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
{
|
||||
String ss = "";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
public String getContexts(final String env) {
|
||||
String contexts = "a";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class Test {
|
||||
void foo() {
|
||||
String var;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
static int n;
|
||||
static { <caret>n = 1; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class Foo {
|
||||
int sent;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant initializer" "true"
|
||||
// "Remove redundant initializer" "true-preview"
|
||||
class A {
|
||||
int n = <caret>0;
|
||||
{ n = 1; }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant initializer" "true"
|
||||
// "Remove redundant initializer" "true-preview"
|
||||
class A {
|
||||
private String myFoo = ab<caret>c();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class X {
|
||||
void test(boolean b) {
|
||||
if (<caret>b ^= false) {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant initializer" "true"
|
||||
// "Remove redundant initializer" "true-preview"
|
||||
class A {
|
||||
void testFor() {
|
||||
if (true)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
int v() {
|
||||
int x;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
public static void main(String[] args) {
|
||||
int x = (<caret>x = 3) * 4;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class Foo {
|
||||
void bar(int begin) {
|
||||
int current;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
void m() {
|
||||
int i;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
void m(int i) {
|
||||
<caret>i = 9;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
record R2(int y) {
|
||||
public R2 {
|
||||
this.y = y;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
A a = null;
|
||||
String m(String str) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Remove redundant assignment" "true"
|
||||
// "Remove redundant assignment" "true-preview"
|
||||
class A {
|
||||
{
|
||||
String ss = "";
|
||||
|
||||
Reference in New Issue
Block a user