From d6d7d4b3ab092e988a75faf27c9e10e71c4208dc Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Mon, 20 Nov 2017 15:14:12 +0700 Subject: [PATCH] DataFlowRunner: forNestedClosures; merging nested state is encapsulated within the runner --- .../dataFlow/DataFlowInspectionBase.java | 21 +----------------- .../dataFlow/DataFlowRunner.java | 22 ++++++++++++++++--- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 9c54f35c914b..b82857cd0a08 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -18,7 +18,6 @@ import com.intellij.codeInspection.dataFlow.instructions.*; import com.intellij.codeInspection.dataFlow.value.DfaConstValue; import com.intellij.codeInspection.dataFlow.value.DfaUnknownValue; import com.intellij.codeInspection.dataFlow.value.DfaValue; -import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; import com.intellij.codeInspection.nullable.NullableStuffInspectionBase; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -31,7 +30,6 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.MultiMap; import com.siyeh.ig.psiutils.*; import one.util.streamex.StreamEx; import org.jdom.Element; @@ -184,24 +182,7 @@ public class DataFlowInspectionBase extends AbstractBaseJavaLocalInspectionTool final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor, IGNORE_ASSERT_STATEMENTS, initialStates); if (rc == RunnerResult.OK) { createDescription(dfaRunner, holder, visitor, scope); - - MultiMap nestedClosures = dfaRunner.getNestedClosures(); - for (PsiElement closure : nestedClosures.keySet()) { - List unusedVars = StreamEx.of(dfaRunner.getFactory().getValues()) - .select(DfaVariableValue.class) - .filter(var -> var.getQualifier() == null) - .filter(var -> var.getPsiVariable() instanceof PsiVariable && - !VariableAccessUtils.variableIsUsed((PsiVariable)var.getPsiVariable(), closure)) - .toList(); - Collection states = nestedClosures.get(closure); - if (!unusedVars.isEmpty()) { - List stateList = StreamEx.of(states) - .peek(state -> unusedVars.forEach(state::flushVariable)) - .map(state -> (DfaMemoryStateImpl)state).distinct().toList(); - states = StateQueue.mergeGroup(stateList); - } - analyzeDfaWithNestedClosures(closure, holder, dfaRunner, states); - } + dfaRunner.forNestedClosures((closure, states) -> analyzeDfaWithNestedClosures(closure, holder, dfaRunner, states)); } else if (rc == RunnerResult.TOO_COMPLEX) { PsiIdentifier name = null; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java index 13efd844170e..effa2f4551ce 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java @@ -30,12 +30,14 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import com.siyeh.ig.psiutils.VariableAccessUtils; import gnu.trove.THashSet; import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.BiConsumer; import java.util.function.Consumer; public class DataFlowRunner { @@ -372,9 +374,23 @@ public class DataFlowRunner { return myInstructions[index]; } - @NotNull - MultiMap getNestedClosures() { - return new MultiMap<>(myNestedClosures); + public void forNestedClosures(BiConsumer> consumer) { + for (PsiElement closure : myNestedClosures.keySet()) { + List unusedVars = StreamEx.of(getFactory().getValues()) + .select(DfaVariableValue.class) + .filter(var -> var.getQualifier() == null) + .filter(var -> var.getPsiVariable() instanceof PsiVariable && + !VariableAccessUtils.variableIsUsed((PsiVariable)var.getPsiVariable(), closure)) + .toList(); + Collection states = myNestedClosures.get(closure); + if (!unusedVars.isEmpty()) { + List stateList = StreamEx.of(states) + .peek(state -> unusedVars.forEach(state::flushVariable)) + .map(state -> (DfaMemoryStateImpl)state).distinct().toList(); + states = StateQueue.mergeGroup(stateList); + } + consumer.accept(closure, states); + } } @NotNull