introduce variable: allow introduction of expression from inside for loop if independent from loop vars (IDEA-162911)

This commit is contained in:
Anna.Kozlova
2016-10-21 14:52:31 +02:00
parent cf9d8cd25b
commit 8a276d0bf4
4 changed files with 33 additions and 12 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,8 +54,6 @@ import com.intellij.psi.impl.source.jsp.jspJava.JspCodeBlock;
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil;
import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.scope.util.PsiScopesUtil;
import com.intellij.psi.util.*;
import com.intellij.refactoring.*;
import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
@@ -755,14 +753,16 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
boolean skipForStatement = true;
final PsiForStatement forStatement = PsiTreeUtil.getParentOfType(expr, PsiForStatement.class);
if (forStatement != null) {
final VariablesProcessor variablesProcessor = new VariablesProcessor(false) {
@Override
protected boolean check(PsiVariable var, ResolveState state) {
return PsiTreeUtil.isAncestor(forStatement.getInitialization(), var, true);
}
};
PsiScopesUtil.treeWalkUp(variablesProcessor, expr, null);
skipForStatement = variablesProcessor.size() == 0;
Set<PsiVariable> vars = new HashSet<>();
SyntaxTraverser.psiTraverser().withRoot(expr)
.filter(element -> element instanceof PsiReferenceExpression)
.forEach(element -> {
final PsiElement resolve = ((PsiReferenceExpression)element).resolve();
if (resolve instanceof PsiVariable) {
vars.add((PsiVariable)resolve);
}
});
skipForStatement = vars.stream().noneMatch(variable -> PsiTreeUtil.isAncestor(forStatement.getInitialization(), variable, true));
}
PsiElement containerParent = tempContainer;
@@ -0,0 +1,9 @@
class Foo {
void foo(String[] input) {
int temp = input.length;
char[][] board = new char[temp][];
for (int i = 0; i < temp; i++) {
System.out.println(temp);
}
}
}
@@ -0,0 +1,8 @@
class Foo {
void foo(String[] input) {
char[][] board = new char[input.length][];
for (int i = 0; i < input.length; i++) {
System.out.println(<selection>input.length</selection>);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -207,6 +207,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
doTest(new MockIntroduceVariableHandler("temp", true, false, false, "int"));
}
public void testInsideForLoopIndependantFromLoopVariable() {
doTest(new MockIntroduceVariableHandler("temp", true, false, false, "int"));
}
public void testDuplicateGenericExpressions() {
doTest(new MockIntroduceVariableHandler("temp", true, false, false, "Foo2<? extends java.lang.Runnable>"));
}