change signature: conflict if deleted parameter is used in method body, excluding javadoc (IDEA-157603)

This commit is contained in:
Anna Kozlova
2016-06-30 21:02:38 +03:00
parent 4b1ff8c516
commit fe7045debb
7 changed files with 67 additions and 5 deletions
@@ -118,8 +118,11 @@ public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase {
newVisibility = VisibilityUtil.getVisibilityModifier(method.getModifierList());
}
return new JavaChangeInfoImpl(newVisibility, method, newName, newType, parameterInfo, thrownExceptions, generateDelegate,
propagateParametersMethods, propagateExceptionsMethods);
final JavaChangeInfoImpl javaChangeInfo =
new JavaChangeInfoImpl(newVisibility, method, newName, newType, parameterInfo, thrownExceptions, generateDelegate,
propagateParametersMethods, propagateExceptionsMethods);
javaChangeInfo.setRefactoringId(REFACTORING_ID);
return javaChangeInfo;
}
@NotNull
@@ -151,6 +154,7 @@ public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase {
RenameUtil.removeConflictUsages(usagesSet);
if (!conflictDescriptions.isEmpty()) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
if (ConflictsInTestsException.isTestIgnore()) return true;
throw new ConflictsInTestsException(conflictDescriptions.values());
}
if (myPrepareSuccessfulSwingThreadCallback != null) {
@@ -69,6 +69,8 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
final Set<PsiMethod> propagateParametersMethods;
final Set<PsiMethod> propagateExceptionsMethods;
private String myRefactoringId = null;
/**
* @param newExceptions null if not changed
*/
@@ -201,6 +203,14 @@ public class JavaChangeInfoImpl extends UserDataHolderBase implements JavaChange
}
}
public String getRefactoringId() {
return myRefactoringId;
}
public void setRefactoringId(String refactoringId) {
myRefactoringId = refactoringId;
}
protected void fillOldParams(PsiMethod method) {
PsiParameter[] parameters = method.getParameterList().getParameters();
oldParameterNames = new String[parameters.length];
@@ -32,6 +32,8 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.*;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.rename.RenameUtil;
@@ -1001,6 +1003,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
}
}
final boolean[] toRemove = myChangeInfo.toRemoveParm();
final String refactoringId = ((JavaChangeInfoImpl)myChangeInfo).getRefactoringId();
//introduce parameter object deletes parameters but replaces their usages with generated code
final boolean simpleChangeSignature = ChangeSignatureProcessorBase.REFACTORING_ID.equals(refactoringId);
if (simpleChangeSignature) {
checkParametersToDelete(myChangeInfo.getMethod(), toRemove, conflictDescriptions);
}
checkContract(conflictDescriptions, myChangeInfo.getMethod());
for (UsageInfo usageInfo : usagesSet) {
@@ -1010,13 +1019,15 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
final PsiMethod baseMethod = ((OverriderUsageInfo)usageInfo).getBaseMethod();
final int delta = baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount();
if (delta > 0) {
final boolean[] toRemove = myChangeInfo.toRemoveParm();
if (toRemove[toRemove.length - 1]) { //todo check if implicit parameter is not the last one
conflictDescriptions.putValue(baseMethod, "Implicit last parameter should not be deleted");
}
}
else if (prototype != null && baseMethod == myChangeInfo.getMethod()) {
ConflictsUtil.checkMethodConflicts(method.getContainingClass(), method, prototype, conflictDescriptions);
if (simpleChangeSignature) {
checkParametersToDelete(method, toRemove, conflictDescriptions);
}
}
checkContract(conflictDescriptions, method);
@@ -1029,6 +1040,19 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
return conflictDescriptions;
}
private static void checkParametersToDelete(PsiMethod method, boolean[] toRemove, MultiMap<PsiElement, String> conflictDescriptions) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
final PsiCodeBlock body = method.getBody();
if (body != null) {
final LocalSearchScope searchScope = new LocalSearchScope(body);
for (int i = 0; i < toRemove.length; i++) {
if (toRemove[i] && ReferencesSearch.search(parameters[i], searchScope).findFirst() != null) {
conflictDescriptions.putValue(parameters[i], StringUtil.capitalize(RefactoringUIUtil.getDescription(parameters[i], true)) + " is used in method body");
}
}
}
}
private static void checkContract(MultiMap<PsiElement, String> conflictDescriptions, PsiMethod method) {
PsiAnnotation contract = ControlFlowAnalyzer.findContractAnnotation(method);
if (contract != null && !AnnotationUtil.isInferredAnnotation(contract)) {
@@ -0,0 +1,9 @@
class A {
void f<caret>oo(int i) {}
}
class B extends A {
void foo(int i) {
System.out.println(i);
}
}
@@ -169,7 +169,13 @@ public class ChangeSignatureGestureTest extends LightCodeInsightFixtureTestCase
}
public void testDeleteParamInSuperUsed() {
doDeleteTest();
try {
BaseRefactoringProcessor.ConflictsInTestsException.setTestIgnore(true);
doDeleteTest();
}
finally {
BaseRefactoringProcessor.ConflictsInTestsException.setTestIgnore(false);
}
}
private void doDeleteTest() {
@@ -68,6 +68,14 @@ public class ChangeSignatureTest extends ChangeSignatureBaseTest {
catch (BaseRefactoringProcessor.ConflictsInTestsException ignored) { }
}
public void testConflictForUsedParametersInMethodBody() throws Exception {
try {
doTest(null, new ParameterInfoImpl[0], true);
fail("Conflict expected");
}
catch (BaseRefactoringProcessor.ConflictsInTestsException ignored) { }
}
public void testGenericTypes() {
doTest(null, null, "T", method -> new ParameterInfoImpl[]{
new ParameterInfoImpl(-1, "x", myFactory.createTypeFromText("T", method.getParameterList()), "null"),
@@ -50,6 +50,7 @@ import java.util.*;
*/
public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProcessor {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase");
protected static final String REFACTORING_ID = "refactoring.changeSignature";
protected final ChangeInfo myChangeInfo;
protected final PsiManager myManager;
@@ -134,7 +135,7 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces
@Nullable
@Override
protected String getRefactoringId() {
return "refactoring.changeSignature";
return REFACTORING_ID;
}
@Nullable