do not fold parameters if folded expression depends on local variables ( IDEA-54488 )

This commit is contained in:
anna
2010-05-06 21:01:22 +04:00
parent 37574d8f5a
commit 9b301801a6
4 changed files with 50 additions and 2 deletions
@@ -111,7 +111,7 @@ public class ParametersFolder {
public boolean isParameterFoldable(@NotNull ParameterTablePanel.VariableData data,
@NotNull LocalSearchScope scope,
@NotNull final List<? extends PsiVariable> inputVariables) {
final List<PsiExpression> mentionedInExpressions = getMentionedExpressions(data.variable, scope);
final List<PsiExpression> mentionedInExpressions = getMentionedExpressions(data.variable, scope, inputVariables);
if (mentionedInExpressions == null) return false;
int currentRank = 0;
@@ -174,7 +174,7 @@ public class ParametersFolder {
}
@Nullable
private List<PsiExpression> getMentionedExpressions(PsiVariable var, LocalSearchScope scope) {
private List<PsiExpression> getMentionedExpressions(PsiVariable var, LocalSearchScope scope, final List<? extends PsiVariable> inputVariables) {
if (myMentionedInExpressions.containsKey(var)) return myMentionedInExpressions.get(var);
final PsiElement[] scopeElements = scope.getScope();
List<PsiExpression> expressions = null;
@@ -194,6 +194,9 @@ public class ParametersFolder {
final PsiType expressionType = ((PsiExpression)expression).getType();
if (expressionType != null && expressionType != PsiType.VOID && !(expression.getParent() instanceof PsiExpressionStatement)) {
if (dependsOnLocals(expression, inputVariables)) {
break;
}
expressions.add((PsiExpression)expression);
}
expression = PsiTreeUtil.getParentOfType(expression, PsiExpression.class);
@@ -211,6 +214,25 @@ public class ParametersFolder {
return expressions;
}
private static boolean dependsOnLocals(final PsiElement expression, final List<? extends PsiVariable> inputVariables) {
final boolean[] localVarsUsed = new boolean[]{false};
expression.accept(new JavaRecursiveElementWalkingVisitor(){
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
final PsiElement resolved = expression.resolve();
if (resolved instanceof PsiVariable) {
final PsiVariable variable = (PsiVariable)resolved;
if (!inputVariables.contains(variable)) {
localVarsUsed[0] = true;
return;
}
}
super.visitReferenceExpression(expression);
}
});
return localVarsUsed[0];
}
@NotNull
public String getGeneratedCallArgument(@NotNull ParameterTablePanel.VariableData data) {
return myExpressions.containsKey(data.variable) ? myExpressions.get(data.variable).getText() : data.variable.getName();
@@ -0,0 +1,9 @@
class Test {
void foo(String[] ss) {
Integer[] levels = new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3),};
Integer[] nextWinNumber = new Integer[6];
<selection>for (Integer level : levels) {
Integer nextWinNum = nextWinNumber[level - 1];
}</selection>
}
}
@@ -0,0 +1,13 @@
class Test {
void foo(String[] ss) {
Integer[] levels = new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3),};
Integer[] nextWinNumber = new Integer[6];
newMethod(levels, nextWinNumber);
}
private void newMethod(Integer[] levels, Integer[] nextWinNumber) {
for (Integer level : levels) {
Integer nextWinNum = nextWinNumber[level - 1];
}
}
}
@@ -404,6 +404,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
doTest();
}
public void testArrayAccessWithLocalIndex() throws Exception {
doTest();
}
public void testArrayAccessWithDuplicates() throws Exception {
doDuplicatesTest();
}