introduce variable/occurrences: allow to walk up through anonymous

the current behavior is not transitive as occurrences inside anonymous when selected outside were detected (IDEA-174339)
This commit is contained in:
Anna Kozlova
2017-06-15 13:52:55 +03:00
parent 46e403bfa1
commit fb3295db37
4 changed files with 46 additions and 3 deletions
@@ -70,6 +70,7 @@ import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.occurrences.ExpressionOccurrenceManager;
import com.intellij.refactoring.util.occurrences.NotInSuperCallOccurrenceFilter;
import com.intellij.refactoring.util.occurrences.OccurrenceFilter;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
@@ -815,7 +816,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
PsiElement lastScope = tempContainer;
while (true) {
if (containerParent instanceof PsiFile) break;
if (containerParent instanceof PsiMethod) break;
if (containerParent instanceof PsiMethod) {
if (!(((PsiMethod)containerParent).getContainingClass() instanceof PsiAnonymousClass)) break;
}
if (containerParent instanceof PsiLambdaExpression) {
PsiParameter[] parameters = ((PsiLambdaExpression)containerParent).getParameterList().getParameters();
if (Arrays.stream(parameters).anyMatch(parameter -> vars.contains(parameter))) {
@@ -833,8 +836,17 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
lastScope = containerParent;
}
}
return new ExpressionOccurrenceManager(expr, lastScope, NotInSuperCallOccurrenceFilter.INSTANCE);
PsiMethod exprMethod = PsiTreeUtil.getContextOfType(expr, PsiMethod.class);
return new ExpressionOccurrenceManager(expr, lastScope, new OccurrenceFilter() {
@Override
public boolean isOK(PsiExpression occurrence) {
if (!NotInSuperCallOccurrenceFilter.INSTANCE.isOK(occurrence)) return false;
PsiMethod method = PsiTreeUtil.getContextOfType(occurrence, PsiMethod.class);
return method == null || exprMethod == null ||
PsiTreeUtil.isAncestor(exprMethod, method, false) ||
PsiTreeUtil.isAncestor(method, exprMethod, false);
}
});
}
private static boolean isInJspHolderMethod(PsiExpression expr) {
@@ -0,0 +1,14 @@
class Bug {
Bug(String s) {}
void m(String s) {
final String str = s.substring(1);
new Bug(str) {
@Override
public String toString() {
return str;
}
};
}
}
@@ -0,0 +1,13 @@
class Bug {
Bug(String s) {}
void m(String s) {
new Bug(s.substring(1)) {
@Override
public String toString() {
return <selection>s.substring(1)</selection>;
}
};
}
}
@@ -87,6 +87,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
doTest(new MockIntroduceVariableHandler("j", true, false, false, "int"));
}
public void testAnonymousClass6() {
doTest(new MockIntroduceVariableHandler("str", true, false, false, CommonClassNames.JAVA_LANG_STRING));
}
public void testLambda() {
doTest(new MockIntroduceVariableHandler("j", true, false, false, "int"));
}