mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
fixed wrong dfa for integer comparisons (IDEA-91380)
This commit is contained in:
@@ -952,9 +952,6 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
if (JavaTokenType.PLUS == op && (type == null || !type.equalsToText(CommonClassNames.JAVA_LANG_STRING))) {
|
||||
return null;
|
||||
}
|
||||
else if (op == JavaTokenType.LT || op == JavaTokenType.GT) {
|
||||
return JavaTokenType.NE;
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
@@ -553,7 +553,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
if (dfaCond instanceof DfaUnboxedValue) {
|
||||
DfaVariableValue dfaVar = ((DfaUnboxedValue)dfaCond).getVariable();
|
||||
boolean isNegated = dfaVar.isNegated();
|
||||
DfaVariableValue dfaNormalVar = isNegated ? (DfaVariableValue)dfaVar.createNegated() : dfaVar;
|
||||
DfaVariableValue dfaNormalVar = isNegated ? dfaVar.createNegated() : dfaVar;
|
||||
DfaConstValue dfaTrue = myFactory.getConstFactory().getTrue();
|
||||
final DfaValue boxedTrue = myFactory.getBoxedFactory().createBoxed(dfaTrue);
|
||||
DfaRelationValue dfaEqualsTrue = myFactory.getRelationFactory().createRelation(dfaNormalVar, boxedTrue, JavaTokenType.EQEQ, isNegated);
|
||||
@@ -563,7 +563,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
if (dfaCond instanceof DfaVariableValue) {
|
||||
DfaVariableValue dfaVar = (DfaVariableValue)dfaCond;
|
||||
boolean isNegated = dfaVar.isNegated();
|
||||
DfaVariableValue dfaNormalVar = isNegated ? (DfaVariableValue)dfaVar.createNegated() : dfaVar;
|
||||
DfaVariableValue dfaNormalVar = isNegated ? dfaVar.createNegated() : dfaVar;
|
||||
DfaConstValue dfaTrue = myFactory.getConstFactory().getTrue();
|
||||
DfaRelationValue dfaEqualsTrue = myFactory.getRelationFactory().createRelation(dfaNormalVar, dfaTrue, JavaTokenType.EQEQ, isNegated);
|
||||
|
||||
@@ -576,7 +576,10 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
|
||||
if (!(dfaCond instanceof DfaRelationValue)) return true;
|
||||
|
||||
DfaRelationValue dfaRelation = (DfaRelationValue)dfaCond;
|
||||
return applyRelationCondition((DfaRelationValue)dfaCond);
|
||||
}
|
||||
|
||||
private boolean applyRelationCondition(DfaRelationValue dfaRelation) {
|
||||
DfaValue dfaLeft = dfaRelation.getLeftOperand();
|
||||
DfaValue dfaRight = dfaRelation.getRightOperand();
|
||||
if (dfaRight == null || dfaLeft == null) return false;
|
||||
@@ -610,6 +613,14 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
|
||||
if (dfaLeft instanceof DfaUnknownValue || dfaRight instanceof DfaUnknownValue) return true;
|
||||
|
||||
return applyEquivalenceRelation(dfaRelation, dfaLeft, dfaRight);
|
||||
}
|
||||
|
||||
private boolean applyEquivalenceRelation(DfaRelationValue dfaRelation, DfaValue dfaLeft, DfaValue dfaRight) {
|
||||
boolean isNegated = dfaRelation.isNonEquality();
|
||||
if (!isNegated && !dfaRelation.isEquality()) {
|
||||
return true;
|
||||
}
|
||||
boolean result = applyRelation(dfaLeft, dfaRight, isNegated);
|
||||
if (dfaRight instanceof DfaConstValue) {
|
||||
Object constVal = ((DfaConstValue)dfaRight).getValue();
|
||||
|
||||
+5
-6
@@ -34,20 +34,19 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.psi.JavaTokenType.*;
|
||||
|
||||
public class BinopInstruction extends BranchingInstruction {
|
||||
private static final TokenSet ourSignificantOperations = TokenSet.create(EQEQ, NE, LT, GT, LE, GE, INSTANCEOF_KEYWORD, PLUS);
|
||||
private final IElementType myOperationSign;
|
||||
private final Project myProject;
|
||||
|
||||
public BinopInstruction(IElementType opSign, PsiElement psiAnchor, @NotNull Project project) {
|
||||
myProject = project;
|
||||
if (JavaTokenType.EQEQ == opSign || JavaTokenType.NE == opSign || JavaTokenType.INSTANCEOF_KEYWORD == opSign || JavaTokenType.PLUS == opSign) {
|
||||
myOperationSign = opSign;
|
||||
}
|
||||
else {
|
||||
myOperationSign = null;
|
||||
}
|
||||
myOperationSign = ourSignificantOperations.contains(opSign) ? opSign : null;
|
||||
|
||||
setPsiAnchor(psiAnchor);
|
||||
}
|
||||
|
||||
+3
-3
@@ -70,8 +70,8 @@ public abstract class BranchingInstruction extends Instruction {
|
||||
return "true".equals(text) || "false".equals(text);
|
||||
}
|
||||
|
||||
protected void setPsiAnchor(PsiElement psiAcnchor) {
|
||||
myExpression = psiAcnchor;
|
||||
isConstTrue = psiAcnchor != null && isBoolConst(psiAcnchor);
|
||||
protected void setPsiAnchor(PsiElement psiAnchor) {
|
||||
myExpression = psiAnchor;
|
||||
isConstTrue = psiAnchor != null && isBoolConst(psiAnchor);
|
||||
}
|
||||
}
|
||||
|
||||
+22
-22
@@ -25,7 +25,6 @@
|
||||
package com.intellij.codeInspection.dataFlow.value;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -33,6 +32,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static com.intellij.psi.JavaTokenType.*;
|
||||
|
||||
public class DfaRelationValue extends DfaValue {
|
||||
private DfaValue myLeftOperand;
|
||||
private DfaValue myRightOperand;
|
||||
@@ -52,8 +53,8 @@ public class DfaRelationValue extends DfaValue {
|
||||
|
||||
@Nullable
|
||||
public DfaRelationValue createRelation(DfaValue dfaLeft, DfaValue dfaRight, IElementType relation, boolean negated) {
|
||||
if (dfaRight instanceof DfaTypeValue && JavaTokenType.INSTANCEOF_KEYWORD != relation) return null;
|
||||
if (JavaTokenType.PLUS == relation) return null;
|
||||
if (dfaRight instanceof DfaTypeValue && INSTANCEOF_KEYWORD != relation) return null;
|
||||
if (PLUS == relation) return null;
|
||||
|
||||
if (dfaLeft instanceof DfaVariableValue || dfaLeft instanceof DfaBoxedValue || dfaLeft instanceof DfaUnboxedValue
|
||||
|| dfaRight instanceof DfaVariableValue || dfaRight instanceof DfaBoxedValue || dfaRight instanceof DfaUnboxedValue) {
|
||||
@@ -79,16 +80,16 @@ public class DfaRelationValue extends DfaValue {
|
||||
final DfaValue dfaLeft,
|
||||
final DfaValue dfaRight) {
|
||||
// To canonical form.
|
||||
if (JavaTokenType.NE == relation) {
|
||||
relation = JavaTokenType.EQEQ;
|
||||
if (NE == relation) {
|
||||
relation = EQEQ;
|
||||
negated = !negated;
|
||||
}
|
||||
else if (JavaTokenType.LT == relation) {
|
||||
relation = JavaTokenType.GE;
|
||||
else if (LT == relation) {
|
||||
relation = GE;
|
||||
negated = !negated;
|
||||
}
|
||||
else if (JavaTokenType.LE == relation) {
|
||||
relation = JavaTokenType.GT;
|
||||
else if (LE == relation) {
|
||||
relation = GT;
|
||||
negated = !negated;
|
||||
}
|
||||
|
||||
@@ -115,19 +116,10 @@ public class DfaRelationValue extends DfaValue {
|
||||
}
|
||||
|
||||
private static IElementType getSymmetricOperation(IElementType sign) {
|
||||
if (JavaTokenType.LT == sign) {
|
||||
return JavaTokenType.GT;
|
||||
}
|
||||
else if (JavaTokenType.GE == sign) {
|
||||
return JavaTokenType.LE;
|
||||
}
|
||||
else if (JavaTokenType.GT == sign) {
|
||||
return JavaTokenType.LT;
|
||||
}
|
||||
else if (JavaTokenType.LE == sign) {
|
||||
return JavaTokenType.GE;
|
||||
}
|
||||
|
||||
if (LT == sign) return GT;
|
||||
if (GE == sign) return LE;
|
||||
if (GT == sign) return LT;
|
||||
if (LE == sign) return GE;
|
||||
return sign;
|
||||
}
|
||||
}
|
||||
@@ -168,6 +160,14 @@ public class DfaRelationValue extends DfaValue {
|
||||
rel.myIsNegated == myIsNegated;
|
||||
}
|
||||
|
||||
public boolean isEquality() {
|
||||
return myRelation == EQEQ && !myIsNegated;
|
||||
}
|
||||
|
||||
public boolean isNonEquality() {
|
||||
return myRelation == EQEQ && myIsNegated || myRelation == GT && !myIsNegated || myRelation == GE && myIsNegated;
|
||||
}
|
||||
|
||||
@NonNls public String toString() {
|
||||
return (isNegated() ? "not " : "") + myLeftOperand + " " + myRelation + " " + myRightOperand;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
class Zoo2 {
|
||||
public static boolean startsWith(@NotNull String path, @NotNull String start, final boolean caseSensitive) {
|
||||
final int length1 = path.length();
|
||||
final int length2 = start.length();
|
||||
if (length2 == 0) return true;
|
||||
if (length2 > length1) return false;
|
||||
if (!path.regionMatches(!caseSensitive, 0, start, 0, length2)) return false;
|
||||
if (length1 == length2) return true;
|
||||
char last2 = start.charAt(length2 - 1);
|
||||
char next1;
|
||||
if (last2 == '/' || last2 == File.separatorChar) {
|
||||
next1 = path.charAt(length2 - 1);
|
||||
}
|
||||
else {
|
||||
next1 = path.charAt(length2);
|
||||
}
|
||||
return next1 == '/' || next1 == File.separatorChar;
|
||||
}
|
||||
void foo(Some me, Some other) {
|
||||
if (me.depth < other.depth) {
|
||||
System.out.println("less");
|
||||
} else if (other.depth > me.depth) {
|
||||
System.out.println("more");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Some {
|
||||
final int depth;
|
||||
|
||||
Some(int depth) {
|
||||
this.depth = depth;
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,7 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
|
||||
public void testEqualsConstant() throws Throwable { doTest(); }
|
||||
public void testFinalLoopVariableInstanceof() throws Throwable { doTest(); }
|
||||
public void testGreaterIsNotEquals() throws Throwable { doTest(); }
|
||||
public void testNotGreaterIsNotEquals() throws Throwable { doTest(); }
|
||||
|
||||
public void testChainedFinalFieldsDfa() throws Throwable { doTest(); }
|
||||
public void testChainedFinalFieldAccessorsDfa() throws Throwable { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user