mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: Detect which output variables are used after the method call when extracting a method object (IDEA-152688)
This commit is contained in:
@@ -147,6 +147,10 @@ public class ControlFlowWrapper {
|
||||
return myExitStatements;
|
||||
}
|
||||
|
||||
public List<PsiVariable> filterUsedVariables(PsiVariable[] outputVariables) {
|
||||
return ControlFlowUtil.filterUsedVariables(myControlFlow, myFlowEnd, outputVariables);
|
||||
}
|
||||
|
||||
public static class ExitStatementsNotSameException extends Exception {}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -874,7 +874,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
|
||||
setMethodCall((PsiMethodCallExpression)((PsiLocalVariable)replace.getDeclaredElements()[0]).getInitializer());
|
||||
}
|
||||
|
||||
final List<PsiVariable> usedVariables = myControlFlowWrapper.getUsedVariables();
|
||||
final List<PsiVariable> usedVariables = myControlFlowWrapper.filterUsedVariables(myOutputVariables);
|
||||
Collection<ControlFlowUtil.VariableInfo> reassigned = myControlFlowWrapper.getInitializedTwice();
|
||||
for (PsiVariable variable : usedVariables) {
|
||||
String name = variable.getName();
|
||||
|
||||
@@ -361,6 +361,19 @@ public class ControlFlowUtil {
|
||||
return outputVariables;
|
||||
}
|
||||
|
||||
public static List<PsiVariable> filterUsedVariables(ControlFlow flow, int offset, PsiVariable[] variables) {
|
||||
if (offset >= flow.getSize()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<PsiVariable> result = new ArrayList<>();
|
||||
for (PsiVariable variable : variables) {
|
||||
if (needVariableValueAt(variable, flow, offset)) {
|
||||
result.add(variable);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Collection<PsiStatement> findExitPointsAndStatements(final ControlFlow flow, final int start, final int end, final IntArrayList exitPoints,
|
||||
final Class... classesFilter) {
|
||||
if (end == start) {
|
||||
|
||||
+6
-6
@@ -13,15 +13,15 @@ public class ABug {
|
||||
|
||||
Inner inner = new Inner(bottles).invoke();
|
||||
if (inner.is()) return null;
|
||||
List<String> errors = inner.getErrors();
|
||||
int money = inner.getMoney();
|
||||
int nCount = inner.getnCount();
|
||||
int rCount = inner.getrCount();
|
||||
int wCount = inner.getwCount();
|
||||
char[] tripel = inner.getTripel();
|
||||
boolean no33pr = inner.isNo33pr();
|
||||
int first = inner.getFirst();
|
||||
int last = inner.getLast();
|
||||
char[] tripel = inner.getTripel();
|
||||
int rCount = inner.getrCount();
|
||||
int wCount = inner.getwCount();
|
||||
int nCount = inner.getnCount();
|
||||
int money = inner.getMoney();
|
||||
List<String> errors = inner.getErrors();
|
||||
|
||||
boolean unhappy = no33pr && first || no33pr && last;
|
||||
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
class Test {
|
||||
|
||||
public static class Node {
|
||||
public int x;
|
||||
public boolean condition;
|
||||
public Node next;
|
||||
}
|
||||
|
||||
public static int test(Node cur) {
|
||||
Node prev = null;
|
||||
int total = 0;
|
||||
while (cur != null) {
|
||||
if (cur.condition) {
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;
|
||||
} else {<selection>
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;</selection>
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
class Test {
|
||||
|
||||
public static class Node {
|
||||
public int x;
|
||||
public boolean condition;
|
||||
public Node next;
|
||||
}
|
||||
|
||||
public static int test(Node cur) {
|
||||
Node prev = null;
|
||||
int total = 0;
|
||||
while (cur != null) {
|
||||
if (cur.condition) {
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;
|
||||
} else {
|
||||
Inner inner = new Inner(cur, prev, total).invoke();
|
||||
cur = inner.getCur();
|
||||
prev = inner.getPrev();
|
||||
total = inner.getTotal();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private static class Inner {
|
||||
private Node cur;
|
||||
private Node prev;
|
||||
private int total;
|
||||
|
||||
public Inner(Node cur, Node prev, int total) {
|
||||
this.cur = cur;
|
||||
this.prev = prev;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public Node getCur() {
|
||||
return cur;
|
||||
}
|
||||
|
||||
public Node getPrev() {
|
||||
return prev;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public Inner invoke() {
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
class Test {
|
||||
|
||||
public static class Node {
|
||||
public int x;
|
||||
public boolean condition;
|
||||
public Node next;
|
||||
}
|
||||
|
||||
public static int test(Node cur) {
|
||||
Node prev = null;
|
||||
int total = 0;
|
||||
while (cur != null) {
|
||||
if (cur.condition) {
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;
|
||||
} else {<selection>
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;</selection>
|
||||
return cur != null ? total + cur.x : total;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
class Test {
|
||||
|
||||
public static class Node {
|
||||
public int x;
|
||||
public boolean condition;
|
||||
public Node next;
|
||||
}
|
||||
|
||||
public static int test(Node cur) {
|
||||
Node prev = null;
|
||||
int total = 0;
|
||||
while (cur != null) {
|
||||
if (cur.condition) {
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;
|
||||
} else {
|
||||
Inner inner = new Inner(cur, prev, total).invoke();
|
||||
cur = inner.getCur();
|
||||
total = inner.getTotal();
|
||||
return cur != null ? total + cur.x : total;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private static class Inner {
|
||||
private Node cur;
|
||||
private Node prev;
|
||||
private int total;
|
||||
|
||||
public Inner(Node cur, Node prev, int total) {
|
||||
this.cur = cur;
|
||||
this.prev = prev;
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public Node getCur() {
|
||||
return cur;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public Inner invoke() {
|
||||
if (prev != null) {
|
||||
total += prev.x;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur.next;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,8 +3,8 @@ class Test {
|
||||
int i = 0;
|
||||
|
||||
Inner inner = new Inner(i).invoke();
|
||||
int k = inner.getK();
|
||||
int j = inner.getJ();
|
||||
int k = inner.getK();
|
||||
|
||||
int m = k + j;
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,8 +4,8 @@ class A {
|
||||
int y = 46;
|
||||
int inner = 47;
|
||||
Inner inner1 = new Inner(y).invoke();
|
||||
y = inner1.getY();
|
||||
x = inner1.getX();
|
||||
y = inner1.getY();
|
||||
x = y + x + 45;
|
||||
boolean z = true;
|
||||
if (z) {
|
||||
|
||||
+8
@@ -156,6 +156,14 @@ public class ExtractMethodObjectWithMultipleExitPointsTest extends LightRefactor
|
||||
doTestWithIdeaCodeStyleSettings();
|
||||
}
|
||||
|
||||
public void testOutputVariablesUsedInLoop1() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testOutputVariablesUsedInLoop2() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTestWithIdeaCodeStyleSettings() throws Exception {
|
||||
final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
|
||||
String oldPrefix = settings.FIELD_NAME_PREFIX;
|
||||
|
||||
Reference in New Issue
Block a user