mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
DataFlowRunner: move ignoreAssertions to the field
GitOrigin-RevId: f43cdfeda78ff6fdb381962d2a2f37a7926fe830
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1b98680aa9
commit
e90f84e72d
@@ -244,7 +244,7 @@ public class CommonDataflow {
|
||||
if (block == null) return new DataflowResult(RunnerResult.NOT_APPLICABLE);
|
||||
DataFlowRunner runner = new DataFlowRunner(block);
|
||||
CommonDataflowVisitor visitor = new CommonDataflowVisitor();
|
||||
RunnerResult result = runner.analyzeMethodRecursively(block, visitor, false);
|
||||
RunnerResult result = runner.analyzeMethodRecursively(block, visitor);
|
||||
if (result != RunnerResult.OK) return new DataflowResult(result);
|
||||
if (!(block instanceof PsiClass)) return visitor.myResult;
|
||||
DataflowResult dfr = visitor.myResult.copy();
|
||||
@@ -259,7 +259,7 @@ public class CommonDataflow {
|
||||
} else {
|
||||
initialStates = StreamEx.of(states).map(DfaMemoryState::createCopy).toList();
|
||||
}
|
||||
if(runner.analyzeBlockRecursively(body, initialStates, visitor, false) == RunnerResult.OK) {
|
||||
if(runner.analyzeBlockRecursively(body, initialStates, visitor) == RunnerResult.OK) {
|
||||
dfr = visitor.myResult.copy();
|
||||
} else {
|
||||
visitor.myResult = dfr;
|
||||
|
||||
@@ -138,7 +138,7 @@ class ContractChecker {
|
||||
}
|
||||
|
||||
ContractCheckerVisitor visitor = new ContractCheckerVisitor(method, contract, ownContract);
|
||||
runner.analyzeMethod(body, visitor, false, Collections.singletonList(initialState));
|
||||
runner.analyzeMethod(body, visitor, Collections.singletonList(initialState));
|
||||
return visitor.getErrors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec
|
||||
if (aClass instanceof PsiTypeParameter) return;
|
||||
if (PsiUtil.isLocalOrAnonymousClass(aClass) && !(aClass instanceof PsiEnumConstantInitializer)) return;
|
||||
|
||||
final DataFlowRunner runner = new DataFlowRunner(aClass, TREAT_UNKNOWN_MEMBERS_AS_NULLABLE);
|
||||
final DataFlowRunner runner = new DataFlowRunner(aClass, TREAT_UNKNOWN_MEMBERS_AS_NULLABLE, IGNORE_ASSERT_STATEMENTS);
|
||||
DataFlowInstructionVisitor visitor =
|
||||
analyzeDfaWithNestedClosures(aClass, holder, runner, Collections.singletonList(runner.createMemoryState()));
|
||||
List<DfaMemoryState> states = visitor.getEndOfInitializerStates();
|
||||
@@ -121,7 +121,7 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
if (method.isConstructor()) return;
|
||||
final DataFlowRunner runner = new DataFlowRunner(method.getBody(), TREAT_UNKNOWN_MEMBERS_AS_NULLABLE);
|
||||
final DataFlowRunner runner = new DataFlowRunner(method.getBody(), TREAT_UNKNOWN_MEMBERS_AS_NULLABLE, IGNORE_ASSERT_STATEMENTS);
|
||||
analyzeMethod(method, runner, Collections.singletonList(runner.createMemoryState()));
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec
|
||||
DataFlowRunner dfaRunner,
|
||||
Collection<? extends DfaMemoryState> initialStates) {
|
||||
final DataFlowInstructionVisitor visitor = new DataFlowInstructionVisitor();
|
||||
final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor, IGNORE_ASSERT_STATEMENTS, initialStates);
|
||||
final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor, initialStates);
|
||||
if (rc == RunnerResult.OK) {
|
||||
if (dfaRunner.wasForciblyMerged() &&
|
||||
(ApplicationManager.getApplication().isUnitTestMode() || Registry.is("ide.dfa.report.imprecise"))) {
|
||||
|
||||
@@ -42,17 +42,18 @@ import java.util.function.Consumer;
|
||||
public class DataFlowRunner {
|
||||
private static final Logger LOG = Logger.getInstance(DataFlowRunner.class);
|
||||
private static final int MERGING_BACK_BRANCHES_THRESHOLD = 50;
|
||||
static final int MAX_STATES_PER_BRANCH = 300;
|
||||
|
||||
private Instruction[] myInstructions;
|
||||
private final MultiMap<PsiElement, DfaMemoryState> myNestedClosures = new MultiMap<>();
|
||||
@NotNull
|
||||
private final DfaValueFactory myValueFactory;
|
||||
private final boolean myIgnoreAssertions;
|
||||
private boolean myInlining = true;
|
||||
private boolean myCancelled = false;
|
||||
private boolean myWasForciblyMerged = false;
|
||||
// Maximum allowed attempts to process instruction. Fail as too complex to process if certain instruction
|
||||
// is executed more than this limit times.
|
||||
static final int MAX_STATES_PER_BRANCH = 300;
|
||||
private TimeStats myStats;
|
||||
|
||||
public DataFlowRunner() {
|
||||
@@ -60,11 +61,18 @@ public class DataFlowRunner {
|
||||
}
|
||||
|
||||
public DataFlowRunner(@Nullable PsiElement context) {
|
||||
this(context, false);
|
||||
this(context, false, false);
|
||||
}
|
||||
|
||||
public DataFlowRunner(@Nullable PsiElement context, boolean unknownMembersAreNullable) {
|
||||
/**
|
||||
* @param context analysis context element (code block, class, expression, etc.); used to determine whether we can trust
|
||||
* field initializers (e.g. we usually cannot if context is a constructor)
|
||||
* @param unknownMembersAreNullable if true every parameter or method return value without nullity annotation is assumed to be nullable
|
||||
* @param ignoreAssertions if true, assertion statements will be ignored, as if JVM is started with -da.
|
||||
*/
|
||||
public DataFlowRunner(@Nullable PsiElement context, boolean unknownMembersAreNullable, boolean ignoreAssertions) {
|
||||
myValueFactory = new DfaValueFactory(context, unknownMembersAreNullable);
|
||||
myIgnoreAssertions = ignoreAssertions;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -121,7 +129,7 @@ public class DataFlowRunner {
|
||||
@NotNull
|
||||
public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor) {
|
||||
Collection<DfaMemoryState> initialStates = createInitialStates(psiBlock, visitor, false);
|
||||
return initialStates == null ? RunnerResult.NOT_APPLICABLE : analyzeMethod(psiBlock, visitor, false, initialStates);
|
||||
return initialStates == null ? RunnerResult.NOT_APPLICABLE : analyzeMethod(psiBlock, visitor, initialStates);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,7 +149,7 @@ public class DataFlowRunner {
|
||||
if (initialStates.isEmpty()) {
|
||||
return RunnerResult.OK;
|
||||
}
|
||||
return analyzeMethod(psiBlock, visitor, false, initialStates);
|
||||
return analyzeMethod(psiBlock, visitor, initialStates);
|
||||
}
|
||||
|
||||
public final RunnerResult analyzeCodeBlock(@NotNull PsiCodeBlock block,
|
||||
@@ -149,18 +157,17 @@ public class DataFlowRunner {
|
||||
Consumer<? super DfaMemoryState> initialStateAdjuster) {
|
||||
final DfaMemoryState state = createMemoryState();
|
||||
initialStateAdjuster.accept(state);
|
||||
return analyzeMethod(block, visitor, false, Collections.singleton(state));
|
||||
return analyzeMethod(block, visitor, Collections.singleton(state));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock,
|
||||
@NotNull InstructionVisitor visitor,
|
||||
boolean ignoreAssertions,
|
||||
@NotNull Collection<? extends DfaMemoryState> initialStates) {
|
||||
ControlFlow flow = null;
|
||||
try {
|
||||
myStats = new TimeStats();
|
||||
flow = new ControlFlowAnalyzer(myValueFactory, psiBlock, ignoreAssertions, myInlining).buildControlFlow();
|
||||
flow = new ControlFlowAnalyzer(myValueFactory, psiBlock, myIgnoreAssertions, myInlining).buildControlFlow();
|
||||
myStats.endFlow();
|
||||
if (flow == null) return RunnerResult.NOT_APPLICABLE;
|
||||
|
||||
@@ -395,22 +402,23 @@ public class DataFlowRunner {
|
||||
LOG.error(new RuntimeExceptionWithAttachments(e, attachments));
|
||||
}
|
||||
|
||||
public RunnerResult analyzeMethodRecursively(@NotNull PsiElement block, StandardInstructionVisitor visitor, boolean ignoreAssertions) {
|
||||
@NotNull
|
||||
public RunnerResult analyzeMethodRecursively(@NotNull PsiElement block, @NotNull StandardInstructionVisitor visitor) {
|
||||
Collection<DfaMemoryState> states = createInitialStates(block, visitor, false);
|
||||
if (states == null) return RunnerResult.NOT_APPLICABLE;
|
||||
return analyzeBlockRecursively(block, states, visitor, ignoreAssertions);
|
||||
return analyzeBlockRecursively(block, states, visitor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RunnerResult analyzeBlockRecursively(@NotNull PsiElement block,
|
||||
Collection<? extends DfaMemoryState> states,
|
||||
StandardInstructionVisitor visitor,
|
||||
boolean ignoreAssertions) {
|
||||
RunnerResult result = analyzeMethod(block, visitor, ignoreAssertions, states);
|
||||
@NotNull Collection<? extends DfaMemoryState> states,
|
||||
@NotNull StandardInstructionVisitor visitor) {
|
||||
RunnerResult result = analyzeMethod(block, visitor, states);
|
||||
if (result != RunnerResult.OK) return result;
|
||||
|
||||
Ref<RunnerResult> ref = Ref.create(RunnerResult.OK);
|
||||
forNestedClosures((closure, nestedStates) -> {
|
||||
RunnerResult res = analyzeBlockRecursively(closure, nestedStates, visitor, ignoreAssertions);
|
||||
RunnerResult res = analyzeBlockRecursively(closure, nestedStates, visitor);
|
||||
if (res != RunnerResult.OK) {
|
||||
ref.set(res);
|
||||
}
|
||||
@@ -420,7 +428,7 @@ public class DataFlowRunner {
|
||||
|
||||
private void initializeVariables(@NotNull PsiElement psiBlock,
|
||||
@NotNull Collection<? extends DfaMemoryState> initialStates,
|
||||
ControlFlow flow) {
|
||||
@NotNull ControlFlow flow) {
|
||||
if (psiBlock instanceof PsiClass) {
|
||||
DfaVariableValue thisValue = getFactory().getVarFactory().createThisValue((PsiClass)psiBlock);
|
||||
// In class initializer this variable is local until escaped
|
||||
|
||||
@@ -305,7 +305,7 @@ public class DfaUtil {
|
||||
|
||||
/**
|
||||
* Returns a surrounding PSI element which should be analyzed via DFA
|
||||
* (e.g. passed to {@link DataFlowRunner#analyzeMethodRecursively(PsiElement, StandardInstructionVisitor, boolean)}) to cover
|
||||
* (e.g. passed to {@link #analyzeMethodRecursively(PsiElement, StandardInstructionVisitor)}) to cover
|
||||
* given expression.
|
||||
*
|
||||
* @param expression expression to cover
|
||||
|
||||
@@ -50,8 +50,11 @@ public class TrackingRunner extends DataFlowRunner {
|
||||
private final List<DfaInstructionState> afterStates = new ArrayList<>();
|
||||
private final List<TrackingDfaMemoryState> killedStates = new ArrayList<>();
|
||||
|
||||
private TrackingRunner(boolean unknownMembersAreNullable, @Nullable PsiElement context, PsiExpression expression) {
|
||||
super(context, unknownMembersAreNullable);
|
||||
private TrackingRunner(@Nullable PsiElement context,
|
||||
PsiExpression expression,
|
||||
boolean unknownMembersAreNullable,
|
||||
boolean ignoreAssertions) {
|
||||
super(context, unknownMembersAreNullable, ignoreAssertions);
|
||||
myExpression = expression;
|
||||
}
|
||||
|
||||
@@ -117,12 +120,12 @@ public class TrackingRunner extends DataFlowRunner {
|
||||
DfaProblemType type) {
|
||||
PsiElement body = DfaUtil.getDataflowContext(expression);
|
||||
if (body == null) return null;
|
||||
TrackingRunner runner = new TrackingRunner(unknownAreNullables, body, expression);
|
||||
if (!runner.analyze(ignoreAssertions, expression, body)) return null;
|
||||
TrackingRunner runner = new TrackingRunner(body, expression, unknownAreNullables, ignoreAssertions);
|
||||
if (!runner.analyze(expression, body)) return null;
|
||||
return runner.findProblemCause(expression, type);
|
||||
}
|
||||
|
||||
private boolean analyze(boolean ignoreAssertions, PsiExpression expression, PsiElement body) {
|
||||
private boolean analyze(PsiExpression expression, PsiElement body) {
|
||||
List<DfaMemoryState> endOfInitializerStates = new ArrayList<>();
|
||||
StandardInstructionVisitor visitor = new StandardInstructionVisitor(true) {
|
||||
@Override
|
||||
@@ -135,7 +138,7 @@ public class TrackingRunner extends DataFlowRunner {
|
||||
return super.visitEndOfInitializer(instruction, runner, state);
|
||||
}
|
||||
};
|
||||
RunnerResult result = analyzeMethodRecursively(body, visitor, ignoreAssertions);
|
||||
RunnerResult result = analyzeMethodRecursively(body, visitor);
|
||||
if (result != RunnerResult.OK) return false;
|
||||
if (body instanceof PsiClass) {
|
||||
PsiMethod ctor = PsiTreeUtil.getParentOfType(expression, PsiMethod.class, true, PsiClass.class, PsiLambdaExpression.class);
|
||||
@@ -151,7 +154,7 @@ public class TrackingRunner extends DataFlowRunner {
|
||||
else {
|
||||
initialStates = StreamEx.of(endOfInitializerStates).map(DfaMemoryState::createCopy).toList();
|
||||
}
|
||||
return analyzeBlockRecursively(ctorBody, initialStates, visitor, false) == RunnerResult.OK;
|
||||
return analyzeBlockRecursively(ctorBody, initialStates, visitor) == RunnerResult.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user