mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DataFlowRunner: forNestedClosures; merging nested state is encapsulated within the runner
This commit is contained in:
+1
-20
@@ -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<PsiElement,DfaMemoryState> nestedClosures = dfaRunner.getNestedClosures();
|
||||
for (PsiElement closure : nestedClosures.keySet()) {
|
||||
List<DfaVariableValue> 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<? extends DfaMemoryState> states = nestedClosures.get(closure);
|
||||
if (!unusedVars.isEmpty()) {
|
||||
List<DfaMemoryStateImpl> 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;
|
||||
|
||||
+19
-3
@@ -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<PsiElement, DfaMemoryState> getNestedClosures() {
|
||||
return new MultiMap<>(myNestedClosures);
|
||||
public void forNestedClosures(BiConsumer<PsiElement, Collection<? extends DfaMemoryState>> consumer) {
|
||||
for (PsiElement closure : myNestedClosures.keySet()) {
|
||||
List<DfaVariableValue> 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<? extends DfaMemoryState> states = myNestedClosures.get(closure);
|
||||
if (!unusedVars.isEmpty()) {
|
||||
List<DfaMemoryStateImpl> 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
|
||||
|
||||
Reference in New Issue
Block a user