From d279e798c9d18395ecc441e780c3edde4b20167b Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 2 Oct 2014 18:14:05 +0200 Subject: [PATCH] ContractInference: prevent SOE in a more obvious way --- .../dataFlow/ContractInference.java | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java index 4ef9a1dbc08b..63df26ff3e17 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java @@ -55,7 +55,14 @@ public class ContractInference { @Nullable @Override public Result> compute() { - return Result.create(new ContractInferenceInterpreter(method).inferContracts(), method); + List result = RecursionManager.doPreventingRecursion(method, true, new Computable>() { + @Override + public List compute() { + return new ContractInferenceInterpreter(method).inferContracts(); + } + }); + if (result == null) result = Collections.emptyList(); + return Result.create(result, method); } }); } @@ -134,47 +141,42 @@ class ContractInferenceInterpreter { if (targetMethod == null) return Collections.emptyList(); final PsiExpression[] arguments = expression.getArgumentList().getExpressions(); - return RecursionManager.doPreventingRecursion(myMethod, true, new Computable>() { + final boolean notNull = NullableNotNullManager.isNotNull(targetMethod); + List fromDelegate = ContainerUtil.mapNotNull(ControlFlowAnalyzer.getMethodContracts(targetMethod), new NullableFunction() { + @Nullable @Override - public List compute() { - final boolean notNull = NullableNotNullManager.isNotNull(targetMethod); - List fromDelegate = ContainerUtil.mapNotNull(ControlFlowAnalyzer.getMethodContracts(targetMethod), new NullableFunction() { - @Nullable - @Override - public MethodContract fun(MethodContract delegateContract) { - ValueConstraint[] answer = myEmptyConstraints; - for (int i = 0; i < delegateContract.arguments.length; i++) { - if (i >= arguments.length) return null; + public MethodContract fun(MethodContract delegateContract) { + ValueConstraint[] answer = myEmptyConstraints; + for (int i = 0; i < delegateContract.arguments.length; i++) { + if (i >= arguments.length) return null; - ValueConstraint argConstraint = delegateContract.arguments[i]; - if (argConstraint != ANY_VALUE) { - int paramIndex = resolveParameter(arguments[i]); - if (paramIndex < 0) { - if (argConstraint != getLiteralConstraint(arguments[i])) { - return null; - } - } - else { - answer = withConstraint(answer, paramIndex, argConstraint); - if (answer == null) { - return null; - } - } + ValueConstraint argConstraint = delegateContract.arguments[i]; + if (argConstraint != ANY_VALUE) { + int paramIndex = resolveParameter(arguments[i]); + if (paramIndex < 0) { + if (argConstraint != getLiteralConstraint(arguments[i])) { + return null; } } - ValueConstraint returnValue = negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue; - if (notNull && returnValue != THROW_EXCEPTION) { - returnValue = NOT_NULL_VALUE; + else { + answer = withConstraint(answer, paramIndex, argConstraint); + if (answer == null) { + return null; + } } - return answer == null ? null : new MethodContract(answer, returnValue); } - }); - if (notNull) { - return ContainerUtil.concat(fromDelegate, Arrays.asList(new MethodContract(myEmptyConstraints, NOT_NULL_VALUE))); } - return fromDelegate; + ValueConstraint returnValue = negated ? negateConstraint(delegateContract.returnValue) : delegateContract.returnValue; + if (notNull && returnValue != THROW_EXCEPTION) { + returnValue = NOT_NULL_VALUE; + } + return answer == null ? null : new MethodContract(answer, returnValue); } }); + if (notNull) { + return ContainerUtil.concat(fromDelegate, Arrays.asList(new MethodContract(myEmptyConstraints, NOT_NULL_VALUE))); + } + return fromDelegate; } @NotNull