mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java inspection: Check if the returned variable is read in the 'finally' block of an enclosing 'try' statement in "Move return to computation" inspection (IDEA-121153)
This commit is contained in:
+11
-13
@@ -186,22 +186,20 @@ public class ReturnSeparatedFromComputationInspection extends BaseJavaBatchLocal
|
||||
}
|
||||
|
||||
private static boolean isApplicable(@NotNull ControlFlow flow, @NotNull ReturnContext context) {
|
||||
final int flowStart = flow.getStartOffset(context.returnScope);
|
||||
final int flowEnd = flow.getEndOffset(context.returnScope);
|
||||
if (flowStart < 0 || flowEnd < 0) return false;
|
||||
|
||||
final int returnStartOffset = flow.getStartOffset(context.returnStatement);
|
||||
final int returnEndOffset = flow.getEndOffset(context.returnStatement);
|
||||
if (returnStartOffset < 0 || returnEndOffset < 0) return false;
|
||||
|
||||
if (hasChainedAssignmentsInScope(flow, context.returnedVariable, context.returnStatement)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (context.returnScope != context.variableScope &&
|
||||
ControlFlowUtil.hasObservableThrowExitPoints(flow, flowStart, flowEnd,
|
||||
new PsiElement[]{context.refactoredStatement}, context.variableScope)) {
|
||||
return false;
|
||||
if (context.returnScope != context.variableScope) {
|
||||
if (ControlFlowUtil.isVariableReadInFinally(flow, context.returnScope, context.variableScope, context.returnedVariable)) {
|
||||
return false;
|
||||
}
|
||||
final int flowStart = flow.getStartOffset(context.returnScope);
|
||||
final int flowEnd = flow.getEndOffset(context.returnScope);
|
||||
if (flowStart < 0 || flowEnd < 0) return false;
|
||||
if (ControlFlowUtil.hasObservableThrowExitPoints(flow, flowStart, flowEnd,
|
||||
new PsiElement[]{context.refactoredStatement}, context.variableScope)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Mover mover = new Mover(flow, context.refactoredStatement, context.returnedVariable, context.returnType, true);
|
||||
|
||||
@@ -258,6 +258,37 @@ public class ControlFlowUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isVariableReadInFinally(@NotNull ControlFlow flow,
|
||||
@Nullable PsiElement startElement,
|
||||
@NotNull PsiElement enclosingCodeFragment,
|
||||
@NotNull PsiVariable variable) {
|
||||
for (PsiElement element = startElement; element != null && element != enclosingCodeFragment; element = element.getParent()) {
|
||||
if (element instanceof PsiCodeBlock) {
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiTryStatement) {
|
||||
final PsiTryStatement tryStatement = (PsiTryStatement)parent;
|
||||
if (tryStatement.getTryBlock() == element) {
|
||||
final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
|
||||
if (finallyBlock != null) {
|
||||
final List<Instruction> instructions = flow.getInstructions();
|
||||
final int startOffset = flow.getStartOffset(finallyBlock);
|
||||
final int endOffset = flow.getEndOffset(finallyBlock);
|
||||
LOG.assertTrue(startOffset >= 0, "flow start");
|
||||
LOG.assertTrue(endOffset <= instructions.size(), "flow end");
|
||||
for (int i = startOffset; i < endOffset; i++) {
|
||||
final Instruction instruction = instructions.get(i);
|
||||
if (instruction instanceof ReadVariableInstruction && ((ReadVariableInstruction)instruction).variable == variable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<PsiVariable> getInputVariables(ControlFlow flow, int start, int end) {
|
||||
List<PsiVariable> usedVariables = getUsedVariables(flow, start, end);
|
||||
ArrayList<PsiVariable> array = new ArrayList<PsiVariable>(usedVariables.size());
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Move 'return' closer to computation of the value of 'n'" "false"
|
||||
class T {
|
||||
int f(boolean b) {
|
||||
int n = -1;
|
||||
try {
|
||||
if (b) throw new RuntimeException();
|
||||
n = 1;
|
||||
re<caret>turn n;
|
||||
}
|
||||
finally {
|
||||
System.out.println(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user