merge DfaNotNullValue into DfaTypeValue

This commit is contained in:
peter
2013-09-10 18:28:46 +02:00
parent 650794d9c2
commit 2ee4c955da
8 changed files with 52 additions and 158 deletions
@@ -73,8 +73,8 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
myIgnoreAssertions = ignoreAssertions;
PsiManager manager = codeFragment.getManager();
GlobalSearchScope scope = codeFragment.getResolveScope();
myRuntimeException = myFactory.getNotNullFactory().create(PsiType.getJavaLangRuntimeException(manager, scope));
myError = myFactory.getNotNullFactory().create(PsiType.getJavaLangError(manager, scope));
myRuntimeException = myFactory.createTypeValue(PsiType.getJavaLangRuntimeException(manager, scope), Nullness.NOT_NULL);
myError = myFactory.createTypeValue(PsiType.getJavaLangError(manager, scope), Nullness.NOT_NULL);
myNpe = JavaPsiFacade.getElementFactory(manager.getProject()).createTypeByFQClassName(JAVA_LANG_NULL_POINTER_EXCEPTION, scope);
myFields = new HashSet<DfaVariableValue>();
myCatchStack = new Stack<CatchDescriptor>();
@@ -1259,7 +1259,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
ConditionalGotoInstruction cond = new ConditionalGotoInstruction(null, false, null);
addInstruction(cond);
addInstruction(new EmptyStackInstruction());
addInstruction(new PushInstruction(myFactory.getNotNullFactory().create(ref), null));
addInstruction(new PushInstruction(myFactory.createTypeValue(ref, Nullness.NOT_NULL), null));
addThrowCode(ref);
cond.setOffset(myCurrentFlow.getInstructionCount());
}
@@ -1390,7 +1390,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
break;
case NOT_NULL_VALUE:
PsiType type = expression.getType();
addInstruction(new PushInstruction(myFactory.createTypeValueWithNullability(type, Nullness.NOT_NULL), null));
addInstruction(new PushInstruction(myFactory.createTypeValue(type, Nullness.NOT_NULL), null));
addInstruction(new GotoInstruction(exitPoint));
break;
case TRUE_VALUE:
@@ -1731,7 +1731,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
}
if (dfaValue == null) {
PsiType type = expression.getType();
return myFactory.createTypeValueWithNullability(type, DfaPsiUtil.getElementNullability(type, field));
return myFactory.createTypeValue(type, DfaPsiUtil.getElementNullability(type, field));
}
return dfaValue;
}
@@ -1794,13 +1794,13 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
@Override public void visitSuperExpression(PsiSuperExpression expression) {
startElement(expression);
addInstruction(new PushInstruction(myFactory.getNotNullFactory().create(expression.getType()), null));
addInstruction(new PushInstruction(myFactory.createTypeValue(expression.getType(), Nullness.NOT_NULL), null));
finishElement(expression);
}
@Override public void visitThisExpression(PsiThisExpression expression) {
startElement(expression);
addInstruction(new PushInstruction(myFactory.getNotNullFactory().create(expression.getType()), null));
addInstruction(new PushInstruction(myFactory.createTypeValue(expression.getType(), Nullness.NOT_NULL), null));
finishElement(expression);
}
@@ -277,16 +277,14 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
}
getVariableState(var).setValue(value);
if (value instanceof DfaNotNullValue) {
DfaTypeValue dfaType = myFactory.getTypeFactory().createTypeValue(((DfaNotNullValue)value).getType());
DfaRelationValue dfaInstanceof = myFactory.getRelationFactory().createRelation(var, dfaType, JavaTokenType.INSTANCEOF_KEYWORD, false);
applyCondition(dfaInstanceof);
applyCondition(compareToNull(var, true));
}
else if (value instanceof DfaTypeValue) {
if (value instanceof DfaTypeValue) {
getVariableState(var).setNullable(((DfaTypeValue)value).isNullable());
DfaRelationValue dfaInstanceof = myFactory.getRelationFactory().createRelation(var, value, JavaTokenType.INSTANCEOF_KEYWORD, false);
applyInstanceofOrNull(dfaInstanceof);
if (((DfaTypeValue)value).isNotNull()) {
applyCondition(dfaInstanceof);
} else {
applyInstanceofOrNull(dfaInstanceof);
}
}
else {
DfaRelationValue dfaEqual = myFactory.getRelationFactory().createRelation(var, value, JavaTokenType.EQEQ, false);
@@ -511,7 +509,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
@Override
public boolean isNull(DfaValue dfaValue) {
if (dfaValue instanceof DfaNotNullValue) return false;
if (dfaValue instanceof DfaTypeValue && ((DfaTypeValue)dfaValue).isNotNull()) return false;
if (dfaValue instanceof DfaVariableValue || dfaValue instanceof DfaConstValue) {
DfaConstValue dfaNull = myFactory.getConstFactory().getNull();
@@ -613,7 +611,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
if (dfaLeft instanceof DfaUnknownValue || dfaRight instanceof DfaUnknownValue) return true;
boolean isNegated = dfaRelation.isNegated();
if (dfaLeft instanceof DfaNotNullValue && dfaRight == myFactory.getConstFactory().getNull()) {
if (dfaLeft instanceof DfaTypeValue && ((DfaTypeValue)dfaLeft).isNotNull() && dfaRight == myFactory.getConstFactory().getNull()) {
return isNegated;
}
@@ -629,10 +627,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
return true;
}
if (dfaRight instanceof DfaNotNullValue) {
return true;
}
if (isNull(dfaRight) && compareVariableWithNull(dfaLeft) || isNull(dfaLeft) && compareVariableWithNull(dfaRight)) {
return isNegated;
}
@@ -124,7 +124,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
if (!(psiVariable instanceof PsiField) || !psiVariable.hasModifierProperty(PsiModifier.VOLATILE)) {
memState.setVarValue(var, dfaSource);
}
} else if (dfaDest instanceof DfaNotNullValue && !memState.checkNotNullable(dfaSource)) {
} else if (dfaDest instanceof DfaTypeValue && ((DfaTypeValue)dfaDest).isNotNull() && !memState.checkNotNullable(dfaSource)) {
onAssigningToNotNullableVariable(instruction);
}
@@ -155,8 +155,8 @@ public class StandardInstructionVisitor extends InstructionVisitor {
onInstructionProducesNPE(instruction);
if (qualifier instanceof DfaVariableValue) {
final DfaNotNullValue.Factory factory = runner.getFactory().getNotNullFactory();
memState.setVarValue((DfaVariableValue)qualifier, factory.create(((DfaVariableValue)qualifier).getVariableType()));
memState.setVarValue((DfaVariableValue)qualifier, runner.getFactory()
.createTypeValue(((DfaVariableValue)qualifier).getVariableType(), Nullness.NOT_NULL));
}
}
@@ -214,7 +214,6 @@ public class StandardInstructionVisitor extends InstructionVisitor {
public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
final PsiExpression[] args = instruction.getArgs();
Map<PsiExpression, Nullness> map = myParametersNullability.get(instruction);
final DfaNotNullValue.Factory factory = runner.getFactory().getNotNullFactory();
for (int i = 0; i < args.length; i++) {
final DfaValue arg = memState.pop();
PsiExpression expr = args[(args.length - i - 1)];
@@ -222,7 +221,8 @@ public class StandardInstructionVisitor extends InstructionVisitor {
if (!memState.checkNotNullable(arg)) {
onPassingNullParameter(expr);
if (arg instanceof DfaVariableValue) {
memState.setVarValue((DfaVariableValue)arg, factory.create(((DfaVariableValue)arg).getVariableType()));
memState.setVarValue((DfaVariableValue)arg, runner.getFactory()
.createTypeValue(((DfaVariableValue)arg).getVariableType(), Nullness.NOT_NULL));
}
}
}
@@ -236,7 +236,8 @@ public class StandardInstructionVisitor extends InstructionVisitor {
if (!memState.checkNotNullable(qualifier)) {
onInstructionProducesNPE(instruction);
if (qualifier instanceof DfaVariableValue) {
memState.setVarValue((DfaVariableValue)qualifier, factory.create(((DfaVariableValue)qualifier).getVariableType()));
memState.setVarValue((DfaVariableValue)qualifier, runner.getFactory().createTypeValue(
((DfaVariableValue)qualifier).getVariableType(), Nullness.NOT_NULL));
}
}
@@ -266,7 +267,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
if (methodType == MethodCallInstruction.MethodType.BOXING) {
DfaValue boxed = factory.getBoxedFactory().createBoxed(qualifierValue);
return boxed == null ? factory.getNotNullFactory().create(type) : boxed;
return boxed == null ? factory.createTypeValue(type, Nullness.NOT_NULL) : boxed;
}
if (methodType == MethodCallInstruction.MethodType.CAST) {
@@ -277,7 +278,7 @@ public class StandardInstructionVisitor extends InstructionVisitor {
}
if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) {
return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction));
return factory.createTypeValue(type, myReturnTypeNullability.get(instruction));
}
return DfaUnknownValue.getInstance();
}
@@ -393,17 +394,12 @@ public class StandardInstructionVisitor extends InstructionVisitor {
}
private void handleInstanceof(InstanceofInstruction instruction, DfaValue dfaRight, DfaValue dfaLeft) {
if ((dfaLeft instanceof DfaTypeValue || dfaLeft instanceof DfaNotNullValue) && dfaRight instanceof DfaTypeValue) {
final PsiType leftType;
if (dfaLeft instanceof DfaNotNullValue) {
leftType = ((DfaNotNullValue)dfaLeft).getType();
}
else {
leftType = ((DfaTypeValue)dfaLeft).getType();
if (dfaLeft instanceof DfaTypeValue && dfaRight instanceof DfaTypeValue) {
if (!((DfaTypeValue)dfaLeft).isNotNull()) {
myCanBeNullInInstanceof.add(instruction);
}
if (((DfaTypeValue)dfaRight).getType().isAssignableFrom(leftType)) {
if (((DfaTypeValue)dfaRight).getType().isAssignableFrom(((DfaTypeValue)dfaLeft).getType())) {
return;
}
}
@@ -24,10 +24,7 @@
*/
package com.intellij.codeInspection.dataFlow.instructions;
import com.intellij.codeInspection.dataFlow.DataFlowRunner;
import com.intellij.codeInspection.dataFlow.DfaInstructionState;
import com.intellij.codeInspection.dataFlow.DfaMemoryState;
import com.intellij.codeInspection.dataFlow.InstructionVisitor;
import com.intellij.codeInspection.dataFlow.*;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.openapi.project.Project;
@@ -60,7 +57,7 @@ public class BinopInstruction extends BranchingInstruction {
PsiElement anchor = getPsiAnchor();
Project project = myProject;
PsiClassType string = PsiType.getJavaLangString(PsiManager.getInstance(project), anchor == null ? GlobalSearchScope.allScope(project) : anchor.getResolveScope());
return factory.getNotNullFactory().create(string);
return factory.createTypeValue(string, Nullness.NOT_NULL);
}
public String toString() {
@@ -1,92 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Created by IntelliJ IDEA.
* User: max
* Date: Jan 28, 2002
* Time: 6:45:14 PM
* To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.codeInspection.dataFlow.value;
import com.intellij.psi.PsiType;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
public class DfaNotNullValue extends DfaValue {
public static class Factory {
private final DfaNotNullValue mySharedInstance;
private final HashMap<String,ArrayList<DfaNotNullValue>> myStringToObject;
private final DfaValueFactory myFactory;
Factory(DfaValueFactory factory) {
myFactory = factory;
mySharedInstance = new DfaNotNullValue(factory);
myStringToObject = new HashMap<String, ArrayList<DfaNotNullValue>>();
}
@NotNull
public DfaValue create(@Nullable PsiType type) {
if (type == null) return DfaUnknownValue.getInstance();
mySharedInstance.myType = type;
String id = mySharedInstance.toString();
ArrayList<DfaNotNullValue> conditions = myStringToObject.get(id);
if (conditions == null) {
conditions = new ArrayList<DfaNotNullValue>();
myStringToObject.put(id, conditions);
}
else {
for (DfaNotNullValue value : conditions) {
if (value.hardEquals(mySharedInstance)) return value;
}
}
DfaNotNullValue result = new DfaNotNullValue(type, myFactory);
conditions.add(result);
return result;
}
}
private PsiType myType;
private DfaNotNullValue(PsiType myType, DfaValueFactory factory) {
super(factory);
this.myType = myType;
}
private DfaNotNullValue(DfaValueFactory factory) {
super(factory);
}
@SuppressWarnings({"HardCodedStringLiteral"})
public String toString() {
return "@notnull " + myType.getCanonicalText();
}
public PsiType getType() {
return myType;
}
private boolean hardEquals(DfaNotNullValue aNotNull) {
return aNotNull.myType == myType;
}
}
@@ -63,10 +63,10 @@ public class DfaRelationValue extends DfaValue {
return createCanonicalRelation(relation, negated, dfaLeft, dfaRight);
}
if (dfaLeft instanceof DfaNotNullValue && dfaRight instanceof DfaConstValue) {
if (dfaLeft instanceof DfaTypeValue && ((DfaTypeValue)dfaLeft).isNotNull() && dfaRight instanceof DfaConstValue) {
return createCanonicalRelation(relation, negated, dfaLeft, dfaRight);
}
else if (dfaRight instanceof DfaNotNullValue && dfaLeft instanceof DfaConstValue) {
else if (dfaRight instanceof DfaTypeValue && ((DfaTypeValue)dfaRight).isNotNull() && dfaLeft instanceof DfaConstValue) {
return createCanonicalRelation(relation, negated, dfaRight, dfaLeft);
}
else {
@@ -24,6 +24,7 @@
*/
package com.intellij.codeInspection.dataFlow.value;
import com.intellij.codeInspection.dataFlow.Nullness;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiKeyword;
@@ -48,11 +49,11 @@ public class DfaTypeValue extends DfaValue {
}
@NotNull
public DfaTypeValue createTypeValue(@NotNull PsiType type, boolean nullable) {
public DfaTypeValue createTypeValue(@NotNull PsiType type, Nullness nullable) {
type = TypeConversionUtil.erasure(type);
mySharedInstance.myType = type;
mySharedInstance.myCanonicalText = StringUtil.notNullize(type.getCanonicalText(), PsiKeyword.NULL);
mySharedInstance.myIsNullable = nullable;
mySharedInstance.myNullness = nullable;
String id = mySharedInstance.toString();
ArrayList<DfaTypeValue> conditions = myStringToObject.get(id);
@@ -71,22 +72,22 @@ public class DfaTypeValue extends DfaValue {
}
public DfaTypeValue createTypeValue(@NotNull PsiType type) {
return createTypeValue(type, false);
return createTypeValue(type, Nullness.UNKNOWN);
}
}
private PsiType myType;
private String myCanonicalText;
private boolean myIsNullable;
private Nullness myNullness;
private DfaTypeValue(DfaValueFactory factory) {
super(factory);
}
private DfaTypeValue(PsiType type, boolean isNullable, DfaValueFactory factory, String canonicalText) {
private DfaTypeValue(PsiType type, Nullness nullness, DfaValueFactory factory, String canonicalText) {
super(factory);
myType = type;
myIsNullable = isNullable;
myNullness = nullness;
myCanonicalText = canonicalText;
}
@@ -95,16 +96,20 @@ public class DfaTypeValue extends DfaValue {
}
public boolean isNullable() {
return myIsNullable;
return myNullness == Nullness.NULLABLE;
}
public boolean isNotNull() {
return myNullness == Nullness.NOT_NULL;
}
@NonNls
public String toString() {
return myCanonicalText + ", nullable=" + myIsNullable;
return myCanonicalText + ", nullable=" + myNullness;
}
private boolean hardEquals(DfaTypeValue aType) {
return Comparing.equal(myCanonicalText, aType.myCanonicalText) && myIsNullable == aType.myIsNullable;
return Comparing.equal(myCanonicalText, aType.myCanonicalText) && myNullness == aType.myNullness;
}
public boolean isAssignableFrom(DfaTypeValue dfaType) {
@@ -46,13 +46,13 @@ public class DfaValueFactory {
myVarFactory = new DfaVariableValue.Factory(this);
myConstFactory = new DfaConstValue.Factory(this);
myBoxedFactory = new DfaBoxedValue.Factory(this);
myNotNullFactory = new DfaNotNullValue.Factory(this);
myTypeFactory = new DfaTypeValue.Factory(this);
myRelationFactory = new DfaRelationValue.Factory(this);
}
public DfaValue createTypeValueWithNullability(@Nullable PsiType type, Nullness nullability) {
return nullability == Nullness.NOT_NULL ? getNotNullFactory().create(type) : getTypeFactory().createTypeValue(type, nullability == Nullness.NULLABLE);
public DfaValue createTypeValue(@Nullable PsiType type, Nullness nullability) {
if (type == null) return DfaUnknownValue.getInstance();
return getTypeFactory().createTypeValue(type, nullability);
}
int createID() {
@@ -80,14 +80,14 @@ public class DfaValueFactory {
}
if (psiExpression instanceof PsiNewExpression) {
return getNotNullFactory().create(psiExpression.getType());
return createTypeValue(psiExpression.getType(), Nullness.NOT_NULL);
}
final Object value = JavaConstantExpressionEvaluator.computeConstantExpression(psiExpression, false);
PsiType type = psiExpression.getType();
if (value != null && type != null) {
if (value instanceof String) {
return getNotNullFactory().create(type); // Non-null string literal.
return createTypeValue(type, Nullness.NOT_NULL); // Non-null string literal.
}
return getConstFactory().createFromValue(value, type, null);
}
@@ -98,7 +98,7 @@ public class DfaValueFactory {
@Nullable
public DfaValue createLiteralValue(PsiLiteralExpression literal) {
if (literal.getValue() instanceof String) {
return getNotNullFactory().create(literal.getType()); // Non-null string literal.
return createTypeValue(literal.getType(), Nullness.NOT_NULL); // Non-null string literal.
}
return getConstFactory().create(literal);
}
@@ -131,7 +131,7 @@ public class DfaValueFactory {
PsiExpression initializer = variable.getInitializer();
PsiType type = initializer == null ? null : initializer.getType();
if (initializer != null && type != null && isNotNullExpression(initializer, type)) {
return getNotNullFactory().create(type);
return createTypeValue(type, Nullness.NOT_NULL);
}
}
@@ -173,7 +173,6 @@ public class DfaValueFactory {
private final DfaVariableValue.Factory myVarFactory;
private final DfaConstValue.Factory myConstFactory;
private final DfaBoxedValue.Factory myBoxedFactory;
private final DfaNotNullValue.Factory myNotNullFactory;
private final DfaTypeValue.Factory myTypeFactory;
private final DfaRelationValue.Factory myRelationFactory;
@@ -191,11 +190,6 @@ public class DfaValueFactory {
return myBoxedFactory;
}
@NotNull
public DfaNotNullValue.Factory getNotNullFactory() {
return myNotNullFactory;
}
@NotNull
public DfaTypeValue.Factory getTypeFactory() {
return myTypeFactory;