inline local with rename conflicts inside lambda (IDEA-143340)

This commit is contained in:
Anna Kozlova
2015-08-18 12:34:35 +02:00
parent c58dd5c881
commit 67bfb2b357
5 changed files with 61 additions and 26 deletions
@@ -570,7 +570,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
PsiSubstitutor callSubstitutor = getCallSubstitutor(methodCall);
BlockData blockData = prepareBlock(ref, callSubstitutor, methodCall.getArgumentList(), tailCall);
solveVariableNameConflicts(blockData.block, ref);
InlineUtil.solveVariableNameConflicts(blockData.block, ref, myMethodCopy.getBody());
if (callSubstitutor != PsiSubstitutor.EMPTY) {
substituteMethodTypeParams(blockData.block, callSubstitutor);
}
@@ -851,31 +851,6 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
return new BlockData(block, thisVar, parmVars, resultVar);
}
private void solveVariableNameConflicts(PsiElement scope, final PsiElement placeToInsert) throws IncorrectOperationException {
if (scope instanceof PsiVariable) {
PsiVariable var = (PsiVariable)scope;
String name = var.getName();
String oldName = name;
while (true) {
String newName = myJavaCodeStyle.suggestUniqueVariableName(name, placeToInsert, true);
if (newName.equals(name)) break;
name = newName;
newName = myJavaCodeStyle.suggestUniqueVariableName(name, var, true);
if (newName.equals(name)) break;
name = newName;
}
if (!name.equals(oldName)) {
RefactoringUtil.renameVariableReferences(var, name, new LocalSearchScope(myMethodCopy.getBody()), true);
var.getNameIdentifier().replace(myFactory.createIdentifier(name));
}
}
PsiElement[] children = scope.getChildren();
for (PsiElement child : children) {
solveVariableNameConflicts(child, placeToInsert);
}
}
private void addParmAndThisVarInitializers(BlockData blockData, PsiMethodCallExpression methodCall) throws IncorrectOperationException {
PsiExpression[] args = methodCall.getArgumentList().getExpressions();
if (blockData.parmVars.length > 0) {
@@ -22,6 +22,8 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.RedundantCastUtil;
@@ -52,6 +54,7 @@ public class InlineUtil {
boolean insertCastWhenUnchecked = ref.getParent() instanceof PsiForeachStatement;
final PsiType varType = variable.getType();
initializer = RefactoringUtil.convertInitializerToNormalExpression(initializer, varType);
solveVariableNameConflicts(initializer, ref, initializer);
ChangeContextUtil.encodeContextInfo(initializer, false);
PsiExpression expr = (PsiExpression)replaceDiamondWithInferredTypesIfNeeded(initializer, ref);
@@ -400,6 +403,34 @@ public class InlineUtil {
return ref != initializer ? ref.replace(initializer) : initializer;
}
public static void solveVariableNameConflicts(final PsiElement scope,
final PsiElement placeToInsert,
final PsiElement renameScope) throws IncorrectOperationException {
if (scope instanceof PsiVariable) {
PsiVariable var = (PsiVariable)scope;
String name = var.getName();
String oldName = name;
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(scope.getProject());
while (true) {
String newName = codeStyleManager.suggestUniqueVariableName(name, placeToInsert, true);
if (newName.equals(name)) break;
name = newName;
newName = codeStyleManager.suggestUniqueVariableName(name, var, true);
if (newName.equals(name)) break;
name = newName;
}
if (!name.equals(oldName)) {
RefactoringUtil.renameVariableReferences(var, name, new LocalSearchScope(renameScope), true);
var.getNameIdentifier().replace(JavaPsiFacade.getElementFactory(scope.getProject()).createIdentifier(name));
}
}
PsiElement[] children = scope.getChildren();
for (PsiElement child : children) {
solveVariableNameConflicts(child, placeToInsert, renameScope);
}
}
public enum TailCallType {
None, Simple, Return
}
@@ -0,0 +1,13 @@
class MyClass {
void m() {
Consumer c = o -> {
System.out.println(o);
};
Object o = null;
Consumer cc = <caret>c;
}
}
interface Consumer {
void accept(Object o);
}
@@ -0,0 +1,12 @@
class MyClass {
void m() {
Object o = null;
Consumer cc = o1 -> {
System.out.println(o1);
};
}
}
interface Consumer {
void accept(Object o);
}
@@ -240,6 +240,10 @@ public class InlineLocalTest extends LightCodeInsightTestCase {
doTest(true);
}
public void testRenameLambdaParamsToAvoidConflicts() throws Exception {
doTest(true);
}
public void testLocalVarInsideLambdaBodyWriteUsage() throws Exception {
doTest(true, "Cannot perform refactoring.\n" +
"Variable 'hello' is accessed for writing");