mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
safe delete: enable on local variables; treat side effects as conflicts ( IDEA-17366 )
This commit is contained in:
@@ -40,7 +40,7 @@ public class JavaRefactoringSupportProvider extends DefaultRefactoringSupportPro
|
||||
public boolean isSafeDeleteAvailable(PsiElement element) {
|
||||
return element instanceof PsiClass || element instanceof PsiMethod || element instanceof PsiField ||
|
||||
(element instanceof PsiParameter && ((PsiParameter)element).getDeclarationScope() instanceof PsiMethod) ||
|
||||
element instanceof PsiPackage;
|
||||
element instanceof PsiPackage || element instanceof PsiLocalVariable;
|
||||
}
|
||||
|
||||
public RefactoringActionHandler getIntroduceConstantHandler() {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.refactoring.safeDelete;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
|
||||
import com.intellij.ide.util.SuperMethodWarningUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -30,10 +31,7 @@ import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.*;
|
||||
import com.intellij.refactoring.util.RefactoringMessageUtil;
|
||||
@@ -53,7 +51,7 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate {
|
||||
|
||||
public boolean handlesElement(final PsiElement element) {
|
||||
return element instanceof PsiClass || element instanceof PsiMethod ||
|
||||
element instanceof PsiField || element instanceof PsiParameter;
|
||||
element instanceof PsiField || element instanceof PsiParameter || element instanceof PsiLocalVariable;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -75,6 +73,20 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate {
|
||||
LOG.assertTrue(((PsiParameter) element).getDeclarationScope() instanceof PsiMethod);
|
||||
findParameterUsages((PsiParameter)element, usages);
|
||||
}
|
||||
else if (element instanceof PsiLocalVariable) {
|
||||
for (PsiReference reference : ReferencesSearch.search(element)) {
|
||||
PsiReferenceExpression referencedElement = (PsiReferenceExpression)reference.getElement();
|
||||
final PsiStatement statement = PsiTreeUtil.getParentOfType(referencedElement, PsiStatement.class);
|
||||
|
||||
boolean isSafeToDelete = PsiUtil.isAccessedForWriting(referencedElement);
|
||||
boolean hasSideEffects = false;
|
||||
if (PsiUtil.isOnAssignmentLeftHand(referencedElement)) {
|
||||
hasSideEffects =
|
||||
RemoveUnusedVariableFix.checkSideEffects(((PsiAssignmentExpression)referencedElement.getParent()).getRExpression(), ((PsiLocalVariable)element), new ArrayList<PsiElement>());
|
||||
}
|
||||
usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(statement, element, isSafeToDelete && !hasSideEffects));
|
||||
}
|
||||
}
|
||||
return new NonCodeUsageSearchInfo(insideDeletedCondition, element);
|
||||
}
|
||||
|
||||
@@ -468,7 +480,6 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate {
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod getOverridingConstructorOfSuperCall(final PsiElement element) {
|
||||
PsiMethod overridingConstructor = null;
|
||||
if(element instanceof PsiReferenceExpression && "super".equals(element.getText())) {
|
||||
PsiElement parent = element.getParent();
|
||||
if(parent instanceof PsiMethodCallExpression) {
|
||||
@@ -478,13 +489,13 @@ public class JavaSafeDeleteProcessor implements SafeDeleteProcessorDelegate {
|
||||
if(parent instanceof PsiCodeBlock) {
|
||||
parent = parent.getParent();
|
||||
if(parent instanceof PsiMethod && ((PsiMethod) parent).isConstructor()) {
|
||||
overridingConstructor = (PsiMethod) parent;
|
||||
return (PsiMethod) parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return overridingConstructor;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean canBePrivate(PsiMethod method, Collection<PsiReference> references, Collection<? extends PsiElement> deleted,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class Super {
|
||||
void foo() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class Super {
|
||||
void foo() {
|
||||
int var<caret>Name = 0;
|
||||
varName++;
|
||||
varName = 10;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Super {
|
||||
void foo() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class Super {
|
||||
void foo() {
|
||||
int var<caret>Name = 0;
|
||||
varName++;
|
||||
varName = bar();
|
||||
}
|
||||
int bar() {return 0;}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.idea.Bombed;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
@@ -13,7 +12,6 @@ import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class SafeDeleteTest extends MultiFileTestCase {
|
||||
private VirtualFile myRootBefore;
|
||||
@@ -79,6 +77,24 @@ public class SafeDeleteTest extends MultiFileTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testLocalVariable() throws Exception {
|
||||
myDoCompare = false;
|
||||
doTest("Super");
|
||||
}
|
||||
|
||||
public void testLocalVariableSideEffect() throws Exception {
|
||||
myDoCompare = false;
|
||||
try {
|
||||
doTest("Super");
|
||||
fail("Side effect was ignored");
|
||||
}
|
||||
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue(message, message.startsWith("local variable <b><code>varName</code></b> has 1 usage that is not safe to delete.\n" +
|
||||
"Of those 0 usages are in strings, comments, or non-Java files."));
|
||||
}
|
||||
}
|
||||
|
||||
private void doTest(@NonNls final String qClassName) throws Exception {
|
||||
doTest(new PerformAction() {
|
||||
public void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user