mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
LiveVariablesAnalyzer: use EscapeInstruction instead of visiting the closure
GitOrigin-RevId: 0856d5b5e4c15d9ce6fd83eefab92fb4a5373aac
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e3704df1e9
commit
f88bb8439b
@@ -748,15 +748,15 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
|
||||
private void handleClosure(PsiElement closure) {
|
||||
Set<PsiLocalVariable> variables = new HashSet<>();
|
||||
Set<PsiVariable> variables = new HashSet<>();
|
||||
Set<DfaVariableValue> escapedVars = new HashSet<>();
|
||||
closure.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiElement target = expression.resolve();
|
||||
if (target instanceof PsiLocalVariable) {
|
||||
variables.add((PsiLocalVariable)target);
|
||||
if (target instanceof PsiLocalVariable || target instanceof PsiParameter) {
|
||||
variables.add((PsiVariable)target);
|
||||
}
|
||||
if (target instanceof PsiMember && !((PsiMember)target).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
DfaVariableValue qualifier = getFactory().getExpressionFactory().getQualifierOrThisVariable(expression);
|
||||
@@ -778,7 +778,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
for (DfaValue value : getFactory().getValues()) {
|
||||
if(value instanceof DfaVariableValue) {
|
||||
PsiModifierListOwner var = ((DfaVariableValue)value).getPsiVariable();
|
||||
if (var instanceof PsiLocalVariable && variables.contains(var)) {
|
||||
if (var instanceof PsiVariable && variables.contains(var)) {
|
||||
escapedVars.add((DfaVariableValue)value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,17 @@ import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import com.intellij.util.PairFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FilteringIterator;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.Queue;
|
||||
import com.intellij.util.containers.*;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import one.util.streamex.IntStreamEx;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -31,23 +29,6 @@ public class LiveVariablesAnalyzer {
|
||||
private final Instruction[] myInstructions;
|
||||
private final MultiMap<Instruction, Instruction> myForwardMap;
|
||||
private final MultiMap<Instruction, Instruction> myBackwardMap;
|
||||
private final Map<PsiElement, List<DfaVariableValue>> myClosureReads =
|
||||
FactoryMap.create(closure -> {
|
||||
final Set<DfaVariableValue> result = new LinkedHashSet<>();
|
||||
closure.accept(new PsiRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
DfaValue value = myFactory.createValue((PsiReferenceExpression)element);
|
||||
if (value instanceof DfaVariableValue) {
|
||||
result.add((DfaVariableValue)value);
|
||||
}
|
||||
}
|
||||
super.visitElement(element);
|
||||
}
|
||||
});
|
||||
return new ArrayList<>(result);
|
||||
});
|
||||
|
||||
public LiveVariablesAnalyzer(ControlFlow flow, DfaValueFactory factory) {
|
||||
myFactory = factory;
|
||||
@@ -102,15 +83,17 @@ public class LiveVariablesAnalyzer {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<DfaVariableValue> getReadVariables(Instruction instruction) {
|
||||
private static List<DfaVariableValue> getReadVariables(Instruction instruction) {
|
||||
if (instruction instanceof PushInstruction && !((PushInstruction)instruction).isReferenceWrite()) {
|
||||
DfaValue value = ((PushInstruction)instruction).getValue();
|
||||
if (value instanceof DfaVariableValue) {
|
||||
return Collections.singletonList((DfaVariableValue)value);
|
||||
}
|
||||
}
|
||||
else if (instruction instanceof ClosureInstruction) {
|
||||
return myClosureReads.get(((ClosureInstruction)instruction).getClosureElement());
|
||||
else if (instruction instanceof EscapeInstruction) {
|
||||
return StreamEx.of(((EscapeInstruction)instruction).getEscapedVars())
|
||||
.flatMap(v -> StreamEx.of(v.getDependentVariables()).prepend(v))
|
||||
.distinct().toList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user