mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: Safe Delete should not make method private when it does not compile (IDEA-248028, IDEA-365766)
GitOrigin-RevId: 29071dfc72f3bb572d42b1d7f84e5aaa104323c0
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f42116023e
commit
052a9496b9
+11
-8
@@ -3,9 +3,9 @@ package com.intellij.refactoring.safeDelete;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.psi.util.JavaPsiRecordUtil;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.*;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
@@ -15,7 +15,6 @@ import com.intellij.util.JavaPsiConstructorUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -123,13 +122,17 @@ public final class JavaSafeDeleteDelegateImpl implements JavaSafeDeleteDelegate
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createCleanupOverriding(@NotNull PsiElement overriddenFunction, PsiElement @NotNull [] elements2Delete, @NotNull List<? super UsageInfo> result) {
|
||||
if (overriddenFunction instanceof PsiMethod &&
|
||||
JavaSafeDeleteProcessor.canBePrivate((PsiMethod)overriddenFunction, ReferencesSearch.search(overriddenFunction).findAll(), Collections.emptyList(), elements2Delete)) {
|
||||
result.add(new SafeDeletePrivatizeMethod((PsiMethod)overriddenFunction, (PsiMethod)overriddenFunction));
|
||||
} else {
|
||||
result.add(new SafeDeleteOverrideAnnotation(overriddenFunction, overriddenFunction));
|
||||
public void createCleanupOverriding(@NotNull PsiElement overriddenFunction, PsiElement @NotNull [] elements2Delete,
|
||||
@NotNull List<? super UsageInfo> result) {
|
||||
if (overriddenFunction instanceof PsiMethod method) {
|
||||
if (JavaPsiRecordUtil.getRecordComponentForAccessor(method) != null || method.findSuperMethods().length > 1) return;
|
||||
|
||||
if (JavaSafeDeleteProcessor.canBePrivate(method, elements2Delete)) {
|
||||
result.add(new SafeDeletePrivatizeMethod(method, method));
|
||||
return;
|
||||
}
|
||||
}
|
||||
result.add(new SafeDeleteOverrideAnnotation(overriddenFunction, overriddenFunction));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-20
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.refactoring.safeDelete;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
@@ -884,31 +884,20 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
static boolean canBePrivate(@NotNull PsiMethod method,
|
||||
@NotNull Collection<? extends PsiReference> references,
|
||||
@NotNull Collection<? extends PsiElement> deleted,
|
||||
PsiElement @NotNull [] allElementsToDelete) {
|
||||
static boolean canBePrivate(@NotNull PsiMethod method, PsiElement @NotNull [] allElementsToDelete) {
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if(containingClass == null) {
|
||||
if (containingClass == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiManager manager = method.getManager();
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(method.getProject());
|
||||
PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
PsiElementFactory factory = facade.getElementFactory();
|
||||
PsiModifierList privateModifierList;
|
||||
try {
|
||||
PsiMethod newMethod = factory.createMethod("x3", PsiTypes.voidType());
|
||||
privateModifierList = newMethod.getModifierList();
|
||||
privateModifierList.setModifierProperty(PsiModifier.PRIVATE, true);
|
||||
} catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
return false;
|
||||
}
|
||||
for (PsiReference reference : references) {
|
||||
PsiModifierList privateModifierList = factory.createMethod("x3", PsiTypes.voidType()).getModifierList();
|
||||
privateModifierList.setModifierProperty(PsiModifier.PRIVATE, true);
|
||||
for (PsiReference reference : ReferencesSearch.search(method).findAll()) {
|
||||
PsiElement element = reference.getElement();
|
||||
if (!isInside(element, allElementsToDelete) && !isInside(element, deleted)
|
||||
&& !facade.getResolveHelper().isAccessible(method, privateModifierList, element, null, null)) {
|
||||
if (!isInside(element, allElementsToDelete) && !resolveHelper.isAccessible(method, privateModifierList, element, null, null)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class ChildA extends MyAbstractClass implements MyInterface {
|
||||
@Override
|
||||
public void buggyMethod() {
|
||||
System.out.println("ChildA");
|
||||
}
|
||||
public void caller() {
|
||||
buggyMethod();
|
||||
}
|
||||
}
|
||||
abstract class MyAbstractClass {
|
||||
public void buggyMethod() {
|
||||
System.out.println("buggyMethod from MyAbstractClass");
|
||||
}
|
||||
}
|
||||
interface MyInterface {
|
||||
void buggy<caret>Method();
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class ChildA extends MyAbstractClass implements MyInterface {
|
||||
@Override
|
||||
public void buggyMethod() {
|
||||
System.out.println("ChildA");
|
||||
}
|
||||
public void caller() {
|
||||
buggyMethod();
|
||||
}
|
||||
}
|
||||
abstract class MyAbstractClass {
|
||||
public void buggyMethod() {
|
||||
System.out.println("buggyMethod from MyAbstractClass");
|
||||
}
|
||||
}
|
||||
interface MyInterface {
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.refactoring;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
@@ -83,69 +83,23 @@ public class SafeDeleteTest extends MultiFileTestCase {
|
||||
doTest("IFoo");
|
||||
}
|
||||
|
||||
public void testUsageInExtendsList() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeepDeleteParameterSimple() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeepDeleteParameterOtherTypeInBinaryExpression() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeepDeleteFieldAndAssignedParameter() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testImpossibleToDeepDeleteParameter() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testNoDeepDeleteParameterUsedInCallQualifier() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testNoDeepDeleteParameterUsedInNextArgumentExpression() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testToDeepDeleteParameterOverriders() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeleteParameterOfASiblingMethod() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeleteMethodCascade() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeleteMethodKeepEnumValues() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeleteMethodCascadeRecursive() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeleteMethodCascadeOverridden() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeleteParameterAndUpdateJavadocRef() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testDeleteConstructorParameterWithAnonymousClassUsage() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
|
||||
public void testAccidentalPropertyRef() {
|
||||
doSingleFileTest();
|
||||
}
|
||||
public void testUsageInExtendsList() { doSingleFileTest(); }
|
||||
public void testDeepDeleteParameterSimple() { doSingleFileTest(); }
|
||||
public void testDeepDeleteParameterOtherTypeInBinaryExpression() { doSingleFileTest(); }
|
||||
public void testDeepDeleteFieldAndAssignedParameter() { doSingleFileTest(); }
|
||||
public void testImpossibleToDeepDeleteParameter() { doSingleFileTest(); }
|
||||
public void testNoDeepDeleteParameterUsedInCallQualifier() { doSingleFileTest(); }
|
||||
public void testNoDeepDeleteParameterUsedInNextArgumentExpression() { doSingleFileTest(); }
|
||||
public void testToDeepDeleteParameterOverriders() { doSingleFileTest(); }
|
||||
public void testDeleteParameterOfASiblingMethod() { doSingleFileTest(); }
|
||||
public void testDeleteMethodCascade() { doSingleFileTest(); }
|
||||
public void testDeleteMethodKeepEnumValues() { doSingleFileTest(); }
|
||||
public void testDeleteMethodCascadeRecursive() { doSingleFileTest(); }
|
||||
public void testDeleteMethodCascadeOverridden() { doSingleFileTest(); }
|
||||
public void testDeleteParameterAndUpdateJavadocRef() { doSingleFileTest(); }
|
||||
public void testDeleteConstructorParameterWithAnonymousClassUsage() { doSingleFileTest(); }
|
||||
public void testAccidentalPropertyRef() { doSingleFileTest(); }
|
||||
public void testMethodCannotBePrivate() { doSingleFileTest(); }
|
||||
|
||||
public void testDeleteMethodWithPropertyUsage() {
|
||||
doTest("Foo");
|
||||
|
||||
Reference in New Issue
Block a user