mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
TryWithResources: fixed unbalanced stack
This commit is contained in:
@@ -93,11 +93,6 @@ public class ControlFlow {
|
||||
public int getInstructionOffset() {
|
||||
return myElementToStartOffsetMap.get(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(myElementToStartOffsetMap.get(element));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -107,11 +102,6 @@ public class ControlFlow {
|
||||
public int getInstructionOffset() {
|
||||
return myElementToEndOffsetMap.get(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(myElementToEndOffsetMap.get(element));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -127,8 +117,13 @@ public class ControlFlow {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public interface ControlFlowOffset {
|
||||
int getInstructionOffset();
|
||||
public abstract static class ControlFlowOffset {
|
||||
public abstract int getInstructionOffset();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(getInstructionOffset());
|
||||
}
|
||||
}
|
||||
|
||||
static ControlFlowOffset deltaOffset(final ControlFlowOffset delegate, final int delta) {
|
||||
|
||||
+32
-26
@@ -922,32 +922,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
myTrapStack = myTrapStack.prepend(new Trap.TryCatch(statement, clauses));
|
||||
}
|
||||
|
||||
Set<PsiClassType> closerExceptions = Collections.emptySet();
|
||||
Trap.TwrFinally twrFinallyDescriptor = null;
|
||||
if (resourceList != null) {
|
||||
resourceList.accept(this);
|
||||
|
||||
closerExceptions = StreamEx.of(resourceList.iterator()).flatCollection(ExceptionUtil::getCloserExceptions).toSet();
|
||||
if (!closerExceptions.isEmpty()) {
|
||||
twrFinallyDescriptor = new Trap.TwrFinally(resourceList, getStartOffset(resourceList));
|
||||
myTrapStack = myTrapStack.prepend(twrFinallyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (tryBlock != null) {
|
||||
tryBlock.accept(this);
|
||||
}
|
||||
|
||||
if (twrFinallyDescriptor != null) {
|
||||
assert myTrapStack.getHead() instanceof Trap.TwrFinally;
|
||||
InstructionTransfer gotoEnd = new InstructionTransfer(getEndOffset(resourceList), getVariablesInside(tryBlock));
|
||||
controlTransfer(gotoEnd, FList.createFromReversed(ContainerUtil.createMaybeSingletonList(twrFinallyDescriptor)));
|
||||
myTrapStack = myTrapStack.getTail();
|
||||
startElement(resourceList);
|
||||
addThrows(null, closerExceptions.toArray(PsiClassType.EMPTY_ARRAY));
|
||||
addInstruction(new ControlTransferInstruction(null)); // DfaControlTransferValue is on stack
|
||||
finishElement(resourceList);
|
||||
}
|
||||
processTryWithResources(resourceList, tryBlock);
|
||||
|
||||
InstructionTransfer gotoEnd = new InstructionTransfer(getEndOffset(statement), getVariablesInside(tryBlock));
|
||||
FList<Trap> singleFinally = FList.createFromReversed(ContainerUtil.createMaybeSingletonList(finallyDescriptor));
|
||||
@@ -980,6 +955,37 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
finishElement(statement);
|
||||
}
|
||||
|
||||
private void processTryWithResources(@Nullable PsiResourceList resourceList, @Nullable PsiCodeBlock tryBlock) {
|
||||
Set<PsiClassType> closerExceptions = Collections.emptySet();
|
||||
Trap.TwrFinally twrFinallyDescriptor = null;
|
||||
if (resourceList != null) {
|
||||
resourceList.accept(this);
|
||||
|
||||
closerExceptions = StreamEx.of(resourceList.iterator()).flatCollection(ExceptionUtil::getCloserExceptions).toSet();
|
||||
if (!closerExceptions.isEmpty()) {
|
||||
twrFinallyDescriptor = new Trap.TwrFinally(resourceList, getStartOffset(resourceList));
|
||||
myTrapStack = myTrapStack.prepend(twrFinallyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (tryBlock != null) {
|
||||
tryBlock.accept(this);
|
||||
}
|
||||
|
||||
if (twrFinallyDescriptor != null) {
|
||||
assert myTrapStack.getHead() instanceof Trap.TwrFinally;
|
||||
InstructionTransfer gotoEnd = new InstructionTransfer(getEndOffset(resourceList), getVariablesInside(tryBlock));
|
||||
controlTransfer(gotoEnd, FList.createFromReversed(ContainerUtil.createMaybeSingletonList(twrFinallyDescriptor)));
|
||||
myTrapStack = myTrapStack.getTail().prepend(new Trap.InsideFinally(resourceList));
|
||||
startElement(resourceList);
|
||||
addThrows(null, closerExceptions.toArray(PsiClassType.EMPTY_ARRAY));
|
||||
addInstruction(new ControlTransferInstruction(null)); // DfaControlTransferValue is on stack
|
||||
finishElement(resourceList);
|
||||
assert myTrapStack.getHead() instanceof Trap.InsideFinally;
|
||||
myTrapStack = myTrapStack.getTail();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitResourceList(PsiResourceList resourceList) {
|
||||
for (PsiResourceListElement resource : resourceList) {
|
||||
|
||||
+14
-5
@@ -59,14 +59,23 @@ open class ControlTransferInstruction(val transfer: DfaControlTransferValue?) :
|
||||
|
||||
fun getPossibleTargetInstructions(allInstructions: Array<Instruction>) = getPossibleTargetIndices().map { allInstructions[it] }
|
||||
|
||||
override fun toString() = transfer.toString()
|
||||
override fun toString() = if (transfer == null) "RET" else "TRANSFER " + transfer.toString()
|
||||
}
|
||||
|
||||
sealed class Trap(val anchor: PsiElement) {
|
||||
class TryCatch(tryStatement : PsiTryStatement, val clauses: LinkedHashMap<PsiCatchSection, ControlFlow.ControlFlowOffset>): Trap(tryStatement)
|
||||
class TryFinally(val finallyBlock: PsiCodeBlock, val jumpOffset: ControlFlow.ControlFlowOffset): Trap(finallyBlock)
|
||||
class TwrFinally(resourceList: PsiResourceList, val jumpOffset: ControlFlow.ControlFlowOffset): Trap(resourceList)
|
||||
class InsideFinally(val finallyBlock: PsiCodeBlock): Trap(finallyBlock)
|
||||
class TryCatch(tryStatement: PsiTryStatement, val clauses: LinkedHashMap<PsiCatchSection, ControlFlow.ControlFlowOffset>)
|
||||
: Trap(tryStatement) {
|
||||
override fun toString(): String = "TryCatch -> " + clauses.values
|
||||
}
|
||||
class TryFinally(finallyBlock: PsiCodeBlock, val jumpOffset: ControlFlow.ControlFlowOffset): Trap(finallyBlock) {
|
||||
override fun toString(): String = "TryFinally -> " + jumpOffset
|
||||
}
|
||||
class TwrFinally(resourceList: PsiResourceList, val jumpOffset: ControlFlow.ControlFlowOffset): Trap(resourceList) {
|
||||
override fun toString(): String = "TwrFinally -> " + jumpOffset
|
||||
}
|
||||
class InsideFinally(finallyBlock: PsiElement): Trap(finallyBlock) {
|
||||
override fun toString(): String = "InsideFinally"
|
||||
}
|
||||
|
||||
internal fun getPossibleTargets(): Collection<Int> {
|
||||
return when (this) {
|
||||
|
||||
+17
@@ -1,4 +1,5 @@
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
// IDEA-181860
|
||||
class bugcheck {
|
||||
@@ -48,4 +49,20 @@ class bugcheck {
|
||||
// s is never null here
|
||||
return s.trim();
|
||||
}
|
||||
|
||||
static List<String> inLoop(String[] paths) {
|
||||
List<String> strings = new ArrayList<>();
|
||||
for (String path : paths) {
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
|
||||
String s = br.readLine();
|
||||
if (s != null) {
|
||||
strings.add(s);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user