mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DefUseUtil: make the traversal non-recursive to avoid possible SOE for huge methods (EA-144050)
GitOrigin-RevId: 02df88e041af9be7a4259a734bbfe3b7b0e3cd93
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f433a0c263
commit
10c3276674
@@ -13,6 +13,7 @@ import com.intellij.util.containers.Queue;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -391,7 +392,8 @@ public class DefUseUtil {
|
||||
|
||||
final boolean [] visited = new boolean[instructions.size() + 1];
|
||||
visited [visited.length-1] = true; // stop on the code end
|
||||
int elem = defs() ? flow.getStartOffset(refOrDef) : flow.getEndOffset(refOrDef);
|
||||
final boolean defs = defs();
|
||||
int elem = defs ? flow.getStartOffset(refOrDef) : flow.getEndOffset(refOrDef);
|
||||
|
||||
// hack: ControlFlow doesn't contains parameters initialization
|
||||
if (elem == -1 && def instanceof PsiParameter) {
|
||||
@@ -399,62 +401,65 @@ public class DefUseUtil {
|
||||
}
|
||||
|
||||
if (elem != -1) {
|
||||
if (!defs () && instructions.get(elem) instanceof ReadVariableInstruction) {
|
||||
if (!defs && instructions.get(elem) instanceof ReadVariableInstruction) {
|
||||
LOG.assertTrue(nNext(elem) == 1);
|
||||
LOG.assertTrue(getNext(elem,0) == elem+1);
|
||||
elem += 1;
|
||||
}
|
||||
|
||||
final Set<@NotNull PsiElement> res = new THashSet<>();
|
||||
class Inner {
|
||||
private void traverse(int index) {
|
||||
if (visited[index]) {
|
||||
return;
|
||||
}
|
||||
visited [index] = true;
|
||||
// hack: ControlFlow doesn't contains parameters initialization
|
||||
int startIndex = elem;
|
||||
|
||||
if (defs ()) {
|
||||
final Instruction instruction = instructions.get(index);
|
||||
processInstruction(res, instruction, index);
|
||||
if (instruction instanceof WriteVariableInstruction) {
|
||||
WriteVariableInstruction instructionW = (WriteVariableInstruction)instruction;
|
||||
if (instructionW.variable == def) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
TIntArrayList workQueue = new TIntArrayList();
|
||||
workQueue.add(startIndex);
|
||||
|
||||
// hack: ControlFlow doesn't contains parameters initialization
|
||||
if (index == 0 && def instanceof PsiParameter) {
|
||||
PsiIdentifier identifier = def.getNameIdentifier();
|
||||
if (identifier != null) {
|
||||
res.add(identifier);
|
||||
}
|
||||
while (!workQueue.isEmpty()) {
|
||||
int index = workQueue.remove(workQueue.size() - 1);
|
||||
if (visited[index]) {
|
||||
continue;
|
||||
}
|
||||
visited [index] = true;
|
||||
|
||||
if (defs) {
|
||||
final Instruction instruction = instructions.get(index);
|
||||
processInstruction(res, instruction, index);
|
||||
if (instruction instanceof WriteVariableInstruction) {
|
||||
WriteVariableInstruction instructionW = (WriteVariableInstruction)instruction;
|
||||
if (instructionW.variable == def) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final int nNext = nNext (index);
|
||||
for (int i = 0; i < nNext; i++) {
|
||||
final int prev = getNext(index, i);
|
||||
if (!visited [prev]) {
|
||||
if (!defs ()) {
|
||||
final Instruction instruction = instructions.get(prev);
|
||||
if (instruction instanceof WriteVariableInstruction) {
|
||||
WriteVariableInstruction instructionW = (WriteVariableInstruction)instruction;
|
||||
if (instructionW.variable == def) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
processInstruction(res, instruction, prev);
|
||||
}
|
||||
}
|
||||
traverse (prev);
|
||||
|
||||
// hack: ControlFlow doesn't contains parameters initialization
|
||||
if (index == 0 && def instanceof PsiParameter) {
|
||||
PsiIdentifier identifier = def.getNameIdentifier();
|
||||
if (identifier != null) {
|
||||
res.add(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int nNext = nNext (index);
|
||||
for (int i = 0; i < nNext; i++) {
|
||||
final int prev = getNext(index, i);
|
||||
if (!visited [prev]) {
|
||||
if (!defs) {
|
||||
final Instruction instruction = instructions.get(prev);
|
||||
if (instruction instanceof WriteVariableInstruction) {
|
||||
WriteVariableInstruction instructionW = (WriteVariableInstruction)instruction;
|
||||
if (instructionW.variable == def) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
processInstruction(res, instruction, prev);
|
||||
}
|
||||
}
|
||||
workQueue.add(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
new Inner ().traverse(elem);
|
||||
return PsiUtilCore.toPsiElementArray(res);
|
||||
}
|
||||
return PsiElement.EMPTY_ARRAY;
|
||||
|
||||
Reference in New Issue
Block a user