mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-209947 Handle reassigned variables when fact is preserved; see through getters as variables
GitOrigin-RevId: 547cf499bdc952fc8b88af5896abffb57c628fea
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d6edd633c5
commit
17dd1432d0
+11
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection.dataFlow;
|
||||
|
||||
import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.ConditionalGotoInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.ExpressionPushingInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
|
||||
@@ -331,6 +332,7 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
|
||||
MemoryStateChange findRelation(DfaVariableValue value, @NotNull Predicate<Relation> relationPredicate, boolean startFromSelf) {
|
||||
return findChange(change -> {
|
||||
if (change.myInstruction instanceof AssignInstruction && change.myTopOfStack == value) return true;
|
||||
Change varChange = change.myChanges.get(value);
|
||||
if (varChange != null && varChange.myAddedRelations.stream().anyMatch(relationPredicate)) return true;
|
||||
Change bridgeVarChange = change.myBridgeChanges.get(value);
|
||||
@@ -346,6 +348,10 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
if (factPair != null) return factPair;
|
||||
factPair = factFromChange(type, change, change.myBridgeChanges.get(value));
|
||||
if (factPair != null) return factPair;
|
||||
if (change.myInstruction instanceof AssignInstruction && change.myTopOfStack == value && change.myPrevious != null) {
|
||||
FactDefinition<T> fact = change.myPrevious.findFact(value, type);
|
||||
return new FactDefinition<>(change, fact.myFact);
|
||||
}
|
||||
}
|
||||
return new FactDefinition<>(null, ((DfaVariableValue)value).getInherentFacts().get(type));
|
||||
}
|
||||
@@ -508,5 +514,10 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl {
|
||||
T getFact(T defaultFact) {
|
||||
return myFact == null ? defaultFact : myFact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myFact + " @ " + myChange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-8
@@ -800,14 +800,20 @@ public class TrackingRunner extends StandardDataFlowRunner {
|
||||
PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
CauseItem causeItem = fromMemberNullability(nullability, method, "method", call.getMethodExpression().getReferenceNameElement());
|
||||
if (causeItem != null) return causeItem;
|
||||
switch (nullability) {
|
||||
case NULL:
|
||||
case NULLABLE:
|
||||
return fromCallContract(factUse, call, ContractReturnValue.returnNull());
|
||||
case NOT_NULL:
|
||||
return fromCallContract(factUse, call, ContractReturnValue.returnNotNull());
|
||||
default:
|
||||
if (causeItem == null) {
|
||||
switch (nullability) {
|
||||
case NULL:
|
||||
case NULLABLE:
|
||||
causeItem = fromCallContract(factUse, call, ContractReturnValue.returnNull());
|
||||
break;
|
||||
case NOT_NULL:
|
||||
causeItem = fromCallContract(factUse, call, ContractReturnValue.returnNotNull());
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if (causeItem != null) {
|
||||
return causeItem;
|
||||
}
|
||||
}
|
||||
if (expression instanceof PsiReferenceExpression) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Value is always false (t == null; line#16)
|
||||
't' was assigned (=; line#15)
|
||||
The 'instanceof' check implies non-nullity (t.getNext() instanceof CharSequence; line#14)
|
||||
*/
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
class Test {
|
||||
@Contract(pure=true)
|
||||
native Test getNext();
|
||||
|
||||
void find(Test t) {
|
||||
while (t.getNext() instanceof CharSequence) {
|
||||
t = t.getNext();
|
||||
if (<selection>t == null</selection>) return;
|
||||
}
|
||||
System.out.println(t);
|
||||
}
|
||||
}
|
||||
+1
@@ -170,4 +170,5 @@ public class DataFlowInspectionTrackerTest extends LightCodeInsightFixtureTestCa
|
||||
public void testCollectionSizeEquality() { doTest(); }
|
||||
public void testFailingCall() { doTest(); }
|
||||
public void testInstanceOfMethodReturn() { doTest(); }
|
||||
public void testReassignAfterCheck() { doTest(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user