From 8a276d0bf4379450c3d528a7c51dc43ae0cf28a1 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Fri, 21 Oct 2016 12:38:35 +0200 Subject: [PATCH] introduce variable: allow introduction of expression from inside for loop if independent from loop vars (IDEA-162911) --- .../IntroduceVariableBase.java | 22 +++++++++---------- ...LoopIndependantFromLoopVariable.after.java | 9 ++++++++ ...ideForLoopIndependantFromLoopVariable.java | 8 +++++++ .../refactoring/IntroduceVariableTest.java | 6 ++++- 4 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index fa92d548a366..3b67150d9a5e 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -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 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; diff --git a/java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.after.java b/java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.after.java new file mode 100644 index 000000000000..f8b362717c70 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.after.java @@ -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); + } + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.java b/java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.java new file mode 100644 index 000000000000..3d0a9a9e7523 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/InsideForLoopIndependantFromLoopVariable.java @@ -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(input.length); + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index eb7b18ed748f..f7da07c33723 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -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")); }