summaryrefslogtreecommitdiff
path: root/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow
diff options
context:
space:
mode:
Diffstat (limited to 'java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow')
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ContractInference.java21
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java14
-rw-r--r--java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java10
3 files changed, 34 insertions, 11 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 a1c908837ad0..bd207e58a0fe 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
@@ -71,7 +71,23 @@ class ContractInferenceInterpreter {
if (statements.length == 1) {
if (statements[0] instanceof PsiReturnStatement) {
List<MethodContract> result = handleDelegation(((PsiReturnStatement)statements[0]).getReturnValue(), false);
- if (result != null) return result;
+ if (result != null) {
+ PsiTypeElement typeElement = myMethod.getReturnTypeElement();
+ final boolean returningObject = typeElement == null || !(typeElement.getType() instanceof PsiClassType);
+ return ContainerUtil.findAll(result, new Condition<MethodContract>() {
+ @Override
+ public boolean value(MethodContract contract) {
+ if ((contract.returnValue == NULL_VALUE || contract.returnValue == NOT_NULL_VALUE) && returningObject) {
+ return false;
+ }
+ if ((contract.returnValue == TRUE_VALUE || contract.returnValue == FALSE_VALUE) && !returningObject) {
+ return false;
+ }
+
+ return true;
+ }
+ });
+ }
}
else if (statements[0] instanceof PsiExpressionStatement && ((PsiExpressionStatement)statements[0]).getExpression() instanceof PsiMethodCallExpression) {
List<MethodContract> result = handleDelegation(((PsiExpressionStatement)statements[0]).getExpression(), false);
@@ -132,6 +148,9 @@ class ContractInferenceInterpreter {
}
else {
answer = withConstraint(answer, paramIndex, argConstraint);
+ if (answer == null) {
+ return null;
+ }
}
}
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java
index 691c2f00d985..1167210f917e 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/MethodContract.java
@@ -89,10 +89,16 @@ public class MethodContract {
throw new ParseException("A contract clause must be in form arg1, ..., argN -> return-value");
}
- String[] argStrings = clause.substring(0, arrowIndex).split(",");
- ValueConstraint[] args = new ValueConstraint[argStrings.length];
- for (int i = 0; i < args.length; i++) {
- args[i] = parseConstraint(argStrings[i]);
+ String beforeArrow = clause.substring(0, arrowIndex);
+ ValueConstraint[] args;
+ if (StringUtil.isNotEmpty(beforeArrow)) {
+ String[] argStrings = beforeArrow.split(",");
+ args = new ValueConstraint[argStrings.length];
+ for (int i = 0; i < args.length; i++) {
+ args[i] = parseConstraint(argStrings[i]);
+ }
+ } else {
+ args = new ValueConstraint[0];
}
result.add(new MethodContract(args, parseConstraint(clause.substring(arrowIndex + arrow.length()))));
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 013e24cbe07a..36449128b494 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -500,21 +500,19 @@ public class StandardInstructionVisitor extends InstructionVisitor {
PsiType varType = var.getVariableType();
if (!(varType instanceof PsiPrimitiveType)) return null;
+
+ if (varType == PsiType.FLOAT || varType == PsiType.DOUBLE) return null;
double minValue = varType == PsiType.BYTE ? Byte.MIN_VALUE :
varType == PsiType.SHORT ? Short.MIN_VALUE :
varType == PsiType.INT ? Integer.MIN_VALUE :
varType == PsiType.CHAR ? Character.MIN_VALUE :
- varType == PsiType.LONG ? Long.MIN_VALUE :
- varType == PsiType.FLOAT ? Float.MIN_VALUE :
- Double.MIN_VALUE;
+ Long.MIN_VALUE;
double maxValue = varType == PsiType.BYTE ? Byte.MAX_VALUE :
varType == PsiType.SHORT ? Short.MAX_VALUE :
varType == PsiType.INT ? Integer.MAX_VALUE :
varType == PsiType.CHAR ? Character.MAX_VALUE :
- varType == PsiType.LONG ? Long.MAX_VALUE :
- varType == PsiType.FLOAT ? Float.MAX_VALUE :
- Double.MAX_VALUE;
+ Long.MAX_VALUE;
return checkComparisonWithKnownRange(instruction, runner, memState, opSign, comparedWith, minValue, maxValue);
}