IDEA-231425 Extract variable from expression should be disabled if expression defines a pattern variable that is used outside

GitOrigin-RevId: c8f8ebc567da14c2bb17b4b61234f9ca80fcf664
This commit is contained in:
Tagir Valeev
2020-01-26 13:39:43 +00:00
committed by intellij-monorepo-bot
parent 4cf7c0d803
commit aeac779f23
6 changed files with 49 additions and 1 deletions
@@ -61,6 +61,7 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import com.siyeh.ipp.psiutils.ErrorUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
@@ -610,6 +611,16 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
return false;
}
for (PsiPatternVariable variable : JavaPsiPatternUtil.getExposedPatternVariables(expr)) {
if (VariableAccessUtils.getVariableReferences(variable, variable.getDeclarationScope()).stream()
.anyMatch(ref -> !PsiTreeUtil.isAncestor(expr, ref, true))) {
String message = RefactoringBundle.getCannotRefactorMessage(
RefactoringBundle.message("selected.expression.introduces.pattern.variable", variable.getName()));
showErrorMessage(project, editor, message);
return false;
}
}
final PsiElement physicalElement = expr.getUserData(ElementToWorkOn.PARENT);
@@ -0,0 +1,8 @@
class A {
void test(Object obj) {
boolean temp = obj instanceof String s && s.trim().isEmpty();
if (temp) {
System.out.println("Found");
}
}
}
@@ -0,0 +1,7 @@
class A {
void test(Object obj) {
if (<selection>obj instanceof String s && s.trim().isEmpty()</selection>) {
System.out.println("Found");
}
}
}
@@ -0,0 +1,7 @@
class A {
void test(Object obj) {
if (<selection>obj instanceof String s && s.trim().isEmpty()</selection>) {
System.out.println(s.length());
}
}
}
@@ -113,7 +113,21 @@ public class IntroduceVariableTest extends LightJavaCodeInsightTestCase {
}
fail("Should not be able to perform refactoring");
}
public void testPatternVariableUsedAfterwards() {
try {
doTest("temp", true, false, false, "");
}
catch (RuntimeException e) {
assertEquals("Error message:Cannot perform refactoring.\nSelected expression introduces pattern variable 's'", e.getMessage());
return;
}
fail("Should not be able to perform refactoring");
}
public void testPatternVariableNotUsedAfterwards() {
doTest("temp", true, false, false, "boolean");
}
public void testTernaryBothBranches() { doTest("temp", true, false, false, "int"); }
public void testIfConditionAndChain() { doTest("temp", true, false, false, CommonClassNames.JAVA_LANG_STRING); }
public void testReturnAndChain() { doTest("temp", true, false, false, CommonClassNames.JAVA_LANG_STRING); }
@@ -200,6 +200,7 @@ selected.block.should.represent.an.expression=Selected block should represent an
is.not.supported.in.the.current.context={0} is not supported in current context
type.of.the.selected.expression.cannot.be.determined=Type of selected expression cannot be determined.
selected.expression.has.void.type=Selected expression has void type.
selected.expression.introduces.pattern.variable=Selected expression introduces pattern variable ''{0}''
to.rename=to rename
to.delete.with.usage.search=to delete (with usage search)
unknown.expression.type=Unknown expression type.