IDEA-240402 Dataflow to here: narrow filters during the dataflow

GitOrigin-RevId: 3fb73062b31ec664aebe8bfe167726d421752cb2
This commit is contained in:
Tagir Valeev
2020-05-15 06:47:18 +00:00
committed by intellij-monorepo-bot
parent d45584f07e
commit 7b3ce3097a
4 changed files with 57 additions and 16 deletions
@@ -42,18 +42,32 @@ public class JavaDfaSliceValueFilter implements SliceValueFilter {
return Objects.equals(value, constValue);
}
}
if (!(element instanceof PsiExpression)) return true;
DfType dfType = getElementDfType(element);
return dfType.meet(myDfType) != DfTypes.BOTTOM;
}
@Nullable JavaDfaSliceValueFilter mergeFilter(@NotNull PsiElement element) {
DfType type = getElementDfType(element);
if (type instanceof DfReferenceType) {
type = ((DfReferenceType)type).dropLocality().dropMutability();
}
DfType meet = type.meet(myDfType);
if (meet == DfTypes.TOP && myNextFilter == null) return null;
if (meet == DfTypes.BOTTOM || meet.equals(myDfType)) return this;
return new JavaDfaSliceValueFilter(myNextFilter, meet);
}
private @NotNull DfType getElementDfType(@NotNull PsiElement element) {
if (!(element instanceof PsiExpression)) return DfTypes.TOP;
PsiExpression expression = (PsiExpression)element;
DfType dfType;
PsiType expressionType = expression.getType();
if (TypeConversionUtil.isPrimitiveAndNotNull(expressionType) && myDfType instanceof DfReferenceType) {
dfType = DfTypes.typedObject(((PsiPrimitiveType)expressionType).getBoxedType(expression), Nullability.NOT_NULL);
} else if (!(expressionType instanceof PsiPrimitiveType) && myDfType instanceof DfPrimitiveType) {
dfType = DfTypes.typedObject(PsiPrimitiveType.getUnboxedType(expressionType), Nullability.NOT_NULL);
} else {
dfType = CommonDataflow.getDfType(expression);
return DfTypes.typedObject(((PsiPrimitiveType)expressionType).getBoxedType(expression), Nullability.NOT_NULL);
}
return dfType.meet(myDfType) != DfTypes.BOTTOM;
if (!(expressionType instanceof PsiPrimitiveType) && myDfType instanceof DfPrimitiveType) {
return DfTypes.typedObject(PsiPrimitiveType.getUnboxedType(expressionType), Nullability.NOT_NULL);
}
return CommonDataflow.getDfType(expression);
}
@Override
@@ -1,6 +1,7 @@
// Copyright 2000-2020 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.slicer;
import com.intellij.codeInspection.dataFlow.types.DfTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
@@ -74,8 +75,16 @@ final class JavaSliceBuilder {
final PsiElement realExpression = element.getParent() instanceof DummyHolder ? element.getParent().getContext() : element;
assert realExpression != null;
if (!(realExpression instanceof PsiCompiledElement)) {
return processor
.process(new JavaSliceUsage(realExpression, myParent, myAnalysisParams, mySubstitutor, myIndexNesting, mySyntheticField));
JavaDfaSliceValueFilter curFilter = myAnalysisParams.valueFilter instanceof JavaDfaSliceValueFilter
? (JavaDfaSliceValueFilter)myAnalysisParams.valueFilter
: new JavaDfaSliceValueFilter(DfTypes.TOP);
JavaDfaSliceValueFilter filter = curFilter.mergeFilter(realExpression);
SliceAnalysisParams params = myAnalysisParams;
if (filter != curFilter) {
params = new SliceAnalysisParams(params);
params.valueFilter = filter;
}
return processor.process(new JavaSliceUsage(realExpression, myParent, params, mySubstitutor, myIndexNesting, mySyntheticField));
}
return true;
}
@@ -87,14 +96,14 @@ final class JavaSliceBuilder {
*/
@Contract(pure = true)
@NotNull JavaSliceBuilder updateNesting(@NotNull Flow anno) {
int nestingDelta = (anno.sourceIsContainer() ? 1 : 0) - (anno.targetIsContainer() ? 1 : 0);
if (nestingDelta > 0) {
return incrementNesting();
JavaSliceBuilder result = this;
if (anno.targetIsContainer()) {
result = result.decrementNesting();
}
if (nestingDelta < 0) {
return decrementNesting();
if (anno.sourceIsContainer()) {
result = result.incrementNesting();
}
return this;
return result;
}
@Contract(pure = true)
@@ -0,0 +1,17 @@
public class NarrowFilter {
void test(int <flown11>x) {
if (x > 0) {
foo(<flown1>x);
} else {
bar(x);
}
}
void foo(int <caret>x) { }
void bar(int x) { }
void call() {
test(<flown111>1);
test(-1);
}
}
@@ -95,4 +95,5 @@ public class SliceBackwardTest extends SliceTestCase {
public void testFilterIntRange() throws Exception { doTest(">=0");}
public void testFilterIntRangeArray() throws Exception { doTest(">=0");}
public void testFilterNull() throws Exception { doTest("null");}
public void testNarrowFilter() throws Exception { doTest();}
}