Control flow graph traversing refactoring
This commit is contained in:
+39
-19
@@ -4,6 +4,8 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -14,28 +16,35 @@ import java.util.Map;
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class JetControlFlowGraphTraverser {
|
||||
public static <D> Map<Instruction, Pair<D, D>> traverseInstructionGraphUntilFactsStabilization(
|
||||
Pseudocode pseudocode,
|
||||
public class JetControlFlowGraphTraverser<D> {
|
||||
private final Pseudocode pseudocode;
|
||||
private final Map<Instruction, Pair<D, D>> dataMap = Maps.newLinkedHashMap();
|
||||
|
||||
public static <D> JetControlFlowGraphTraverser<D> create(Pseudocode pseudocode) {
|
||||
return new JetControlFlowGraphTraverser<D>(pseudocode);
|
||||
}
|
||||
|
||||
private JetControlFlowGraphTraverser(Pseudocode pseudocode) {
|
||||
this.pseudocode = pseudocode;
|
||||
}
|
||||
|
||||
public void collectInformationFromInstructionGraph(
|
||||
InstructionsMergeStrategy<D> instructionsMergeStrategy,
|
||||
D initialDataValue,
|
||||
D initialDataValueForEnterInstruction,
|
||||
boolean straightDirection) {
|
||||
Map<Instruction, Pair<D, D>> dataMap = Maps.newLinkedHashMap();
|
||||
initializeDataMap(dataMap, pseudocode, initialDataValue);
|
||||
initializeDataMap(pseudocode, initialDataValue);
|
||||
dataMap.put(pseudocode.getEnterInstruction(), Pair.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction));
|
||||
|
||||
boolean[] changed = new boolean[1];
|
||||
changed[0] = true;
|
||||
while (changed[0]) {
|
||||
changed[0] = false;
|
||||
traverseSubGraph(pseudocode, instructionsMergeStrategy, Collections.<Instruction>emptyList(), straightDirection, dataMap, changed, false);
|
||||
traverseSubGraph(pseudocode, instructionsMergeStrategy, Collections.<Instruction>emptyList(), straightDirection, changed, false);
|
||||
}
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
private static <D> void initializeDataMap(
|
||||
Map<Instruction, Pair<D, D>> dataMap,
|
||||
private void initializeDataMap(
|
||||
Pseudocode pseudocode,
|
||||
D initialDataValue) {
|
||||
List<Instruction> instructions = pseudocode.getInstructions();
|
||||
@@ -43,17 +52,16 @@ public class JetControlFlowGraphTraverser {
|
||||
for (Instruction instruction : instructions) {
|
||||
dataMap.put(instruction, initialPair);
|
||||
if (instruction instanceof LocalDeclarationInstruction) {
|
||||
initializeDataMap(dataMap, ((LocalDeclarationInstruction) instruction).getBody(), initialDataValue);
|
||||
initializeDataMap(((LocalDeclarationInstruction) instruction).getBody(), initialDataValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <D> void traverseSubGraph(
|
||||
private void traverseSubGraph(
|
||||
Pseudocode pseudocode,
|
||||
InstructionsMergeStrategy<D> instructionsMergeStrategy,
|
||||
Collection<Instruction> previousSubGraphInstructions,
|
||||
boolean straightDirection,
|
||||
Map<Instruction, Pair<D, D>> dataMap,
|
||||
boolean[] changed,
|
||||
boolean isLocal) {
|
||||
List<Instruction> instructions = pseudocode.getInstructions();
|
||||
@@ -76,7 +84,7 @@ public class JetControlFlowGraphTraverser {
|
||||
|
||||
if (instruction instanceof LocalDeclarationInstruction) {
|
||||
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
|
||||
traverseSubGraph(subroutinePseudocode, instructionsMergeStrategy, previousInstructions, straightDirection, dataMap, changed, true);
|
||||
traverseSubGraph(subroutinePseudocode, instructionsMergeStrategy, previousInstructions, straightDirection, changed, true);
|
||||
}
|
||||
Pair<D, D> previousDataValue = dataMap.get(instruction);
|
||||
|
||||
@@ -93,24 +101,36 @@ public class JetControlFlowGraphTraverser {
|
||||
}
|
||||
}
|
||||
|
||||
public static void traverseAndAnalyzeInstructionGraph(
|
||||
public void traverseAndAnalyzeInstructionGraph(
|
||||
InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
|
||||
traverseAndAnalyzeInstructionGraph(pseudocode, instructionDataAnalyzeStrategy);
|
||||
}
|
||||
|
||||
private void traverseAndAnalyzeInstructionGraph(
|
||||
Pseudocode pseudocode,
|
||||
InstructionDataAnalyzeStrategy instructionDataAnalyzeStrategy) {
|
||||
InstructionDataAnalyzeStrategy<D> instructionDataAnalyzeStrategy) {
|
||||
List<Instruction> instructions = pseudocode.getInstructions();
|
||||
for (Instruction instruction : instructions) {
|
||||
if (((InstructionImpl)instruction).isDead()) continue;
|
||||
if (instruction instanceof LocalDeclarationInstruction) {
|
||||
traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody(), instructionDataAnalyzeStrategy);
|
||||
}
|
||||
instructionDataAnalyzeStrategy.execute(instruction);
|
||||
Pair<D, D> pair = dataMap.get(instruction);
|
||||
instructionDataAnalyzeStrategy.execute(instruction,
|
||||
pair != null ? pair.getFirst() : null,
|
||||
pair != null ? pair.getSecond() : null);
|
||||
}
|
||||
}
|
||||
|
||||
public D getResultInfo() {
|
||||
return dataMap.get(pseudocode.getExitInstruction()).getFirst();
|
||||
}
|
||||
|
||||
interface InstructionsMergeStrategy<D> {
|
||||
Pair<D, D> execute(Instruction instruction, Collection<D> incomingEdgesData);
|
||||
Pair<D, D> execute(Instruction instruction, @NotNull Collection<D> incomingEdgesData);
|
||||
}
|
||||
|
||||
interface InstructionDataAnalyzeStrategy {
|
||||
void execute(Instruction instruction);
|
||||
interface InstructionDataAnalyzeStrategy<D> {
|
||||
void execute(Instruction instruction, @Nullable D enterData, @Nullable D exitData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,14 +65,6 @@ public class JetFlowInformationProvider {
|
||||
wrappedTrace.close();
|
||||
}
|
||||
|
||||
// public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
|
||||
// Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
||||
// assert pseudocode != null;
|
||||
//
|
||||
// SubroutineExitInstruction exitInstruction = pseudocode.getExitInstruction();
|
||||
// processPreviousInstructions(exitInstruction, new HashSet<Instruction>(), returnedExpressions, elementsReturningUnit);
|
||||
// }
|
||||
|
||||
public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull final Collection<JetExpression> returnedExpressions) {
|
||||
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
||||
assert pseudocode != null;
|
||||
@@ -128,149 +120,20 @@ public class JetFlowInformationProvider {
|
||||
unreachableElements.add(((JetElementInstruction) deadInstruction).getElement());
|
||||
}
|
||||
}
|
||||
|
||||
// SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
|
||||
// Set<Instruction> visited = new HashSet<Instruction>();
|
||||
// collectReachable(enterInstruction, visited, null);
|
||||
//
|
||||
// for (Instruction instruction : pseudocode.getInstructions()) {
|
||||
// if (!visited.contains(instruction) &&
|
||||
// instruction instanceof JetElementInstruction &&
|
||||
// // TODO : do {return} while (1 > a)
|
||||
// !(instruction instanceof ReadUnitValueInstruction)) {
|
||||
// unreachableElements.add(((JetElementInstruction) instruction).getElement());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
|
||||
// Instruction dominatorInstruction = representativeInstructions.get(dominator);
|
||||
// if (dominatorInstruction == null) {
|
||||
// return;
|
||||
// }
|
||||
// SubroutineEnterInstruction enterInstruction = dominatorInstruction.getOwner().getEnterInstruction();
|
||||
//
|
||||
// Set<Instruction> reachable = new HashSet<Instruction>();
|
||||
// collectReachable(enterInstruction, reachable, null);
|
||||
//
|
||||
// Set<Instruction> reachableWithDominatorProhibited = new HashSet<Instruction>();
|
||||
// reachableWithDominatorProhibited.add(dominatorInstruction);
|
||||
// collectReachable(enterInstruction, reachableWithDominatorProhibited, null);
|
||||
//
|
||||
// for (Instruction instruction : reachable) {
|
||||
// if (instruction instanceof JetElementInstruction
|
||||
// && reachable.contains(instruction)
|
||||
// && !reachableWithDominatorProhibited.contains(instruction)) {
|
||||
// JetElementInstruction elementInstruction = (JetElementInstruction) instruction;
|
||||
// dominated.add(elementInstruction.getElement());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public boolean isBreakable(JetLoopExpression loop) {
|
||||
// LoopInfo info = loopInfo.get(loop);
|
||||
// Pseudocode.PseudocodeLabel bodyEntryPoint = (Pseudocode.PseudocodeLabel) info.getBodyEntryPoint();
|
||||
// Pseudocode.PseudocodeLabel exitPoint = (Pseudocode.PseudocodeLabel) info.getExitPoint();
|
||||
// HashSet<Instruction> visited = Sets.newHashSet();
|
||||
// Pseudocode.PseudocodeLabel conditionEntryPoint = (Pseudocode.PseudocodeLabel) info.getConditionEntryPoint();
|
||||
// visited.add(conditionEntryPoint.resolveToInstruction());
|
||||
// return collectReachable(bodyEntryPoint.resolveToInstruction(), visited, exitPoint.resolveToInstruction());
|
||||
// }
|
||||
//
|
||||
// public boolean isReachable(JetExpression from, JetExpression to) {
|
||||
// Instruction fromInstr = representativeInstructions.get(from);
|
||||
// assert fromInstr != null : "No representative instruction for " + from.getText();
|
||||
// Instruction toInstr = representativeInstructions.get(to);
|
||||
// assert toInstr != null : "No representative instruction for " + to.getText();
|
||||
//
|
||||
// return collectReachable(fromInstr, Sets.<Instruction>newHashSet(), toInstr);
|
||||
// }
|
||||
// }
|
||||
|
||||
// private boolean collectReachable(Instruction current, Set<Instruction> visited, @Nullable Instruction lookFor) {
|
||||
// if (!visited.add(current)) return false;
|
||||
// if (current == lookFor) return true;
|
||||
//
|
||||
// for (Instruction nextInstruction : current.getNextInstructions()) {
|
||||
// if (collectReachable(nextInstruction, visited, lookFor)) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// private void processPreviousInstructions(Instruction previousFor, final Set<Instruction> visited, final Collection<JetExpression> returnedExpressions, final Collection<JetElement> elementsReturningUnit) {
|
||||
// if (!visited.add(previousFor)) return;
|
||||
//
|
||||
// Collection<Instruction> previousInstructions = previousFor.getPreviousInstructions();
|
||||
// InstructionVisitor visitor = new InstructionVisitor() {
|
||||
// @Override
|
||||
// public void visitReadValue(ReadValueInstruction instruction) {
|
||||
// returnedExpressions.add((JetExpression) instruction.getElement());
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitReturnValue(ReturnValueInstruction instruction) {
|
||||
// processPreviousInstructions(instruction, visited, returnedExpressions, elementsReturningUnit);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitReturnNoValue(ReturnNoValueInstruction instruction) {
|
||||
// elementsReturningUnit.add(instruction.getElement());
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitSubroutineEnter(SubroutineEnterInstruction instruction) {
|
||||
// elementsReturningUnit.add(instruction.getSubroutine());
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
|
||||
// context.getTrace().report(UNSUPPORTED.on(instruction.getElement(), "Control-flow builder"));
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitWriteValue(WriteValueInstruction writeValueInstruction) {
|
||||
// elementsReturningUnit.add(writeValueInstruction.getElement());
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitJump(AbstractJumpInstruction instruction) {
|
||||
// processPreviousInstructions(instruction, visited, returnedExpressions, elementsReturningUnit);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitReadUnitValue(ReadUnitValueInstruction instruction) {
|
||||
// returnedExpressions.add((JetExpression) instruction.getElement());
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void visitInstruction(Instruction instruction) {
|
||||
// if (instruction instanceof JetElementInstructionImpl) {
|
||||
// JetElementInstructionImpl elementInstruction = (JetElementInstructionImpl) instruction;
|
||||
// context.getTrace().report(UNSUPPORTED.on(elementInstruction.getElement(), "Control-flow builder"));
|
||||
// }
|
||||
// else {
|
||||
// throw new UnsupportedOperationException(instruction.toString());
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// for (Instruction previousInstruction : previousInstructions) {
|
||||
// previousInstruction.accept(visitor);
|
||||
// }
|
||||
// }
|
||||
|
||||
public void markUninitializedVariables(
|
||||
@NotNull JetElement subroutine,
|
||||
final boolean inAnonymousInitializers) {
|
||||
public void markUninitializedVariables(@NotNull JetElement subroutine, final boolean inAnonymousInitializers) {
|
||||
final Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
||||
assert pseudocode != null;
|
||||
|
||||
JetControlFlowGraphTraverser<Map<VariableDescriptor, InitializationPoints>> traverser = JetControlFlowGraphTraverser.create(pseudocode);
|
||||
|
||||
JetControlFlowGraphTraverser.InstructionsMergeStrategy<Map<VariableDescriptor, InitializationPoints>> instructionsMergeStrategy =
|
||||
new JetControlFlowGraphTraverser.InstructionsMergeStrategy<Map<VariableDescriptor, InitializationPoints>>() {
|
||||
@Override
|
||||
public Pair<Map<VariableDescriptor, InitializationPoints>, Map<VariableDescriptor, InitializationPoints>> execute(
|
||||
Instruction instruction,
|
||||
Collection<Map<VariableDescriptor, InitializationPoints>> incomingEdgesData) {
|
||||
@NotNull Collection<Map<VariableDescriptor, InitializationPoints>> incomingEdgesData) {
|
||||
|
||||
Set<VariableDescriptor> variablesInScope = Sets.newHashSet();
|
||||
for (Map<VariableDescriptor, InitializationPoints> edgePointsMap : incomingEdgesData) {
|
||||
@@ -300,34 +163,17 @@ public class JetFlowInformationProvider {
|
||||
}
|
||||
};
|
||||
|
||||
Collection<VariableDescriptor> usedVariables = collectUsedVariables(pseudocode);
|
||||
Collection<VariableDescriptor> declaredVariables = collectDeclaredVariables(subroutine);
|
||||
Map<VariableDescriptor, InitializationPoints> initialMapForStartInstruction = prepareInitialMapForStartInstruction(subroutine, pseudocode);
|
||||
|
||||
traverser.collectInformationFromInstructionGraph(instructionsMergeStrategy,
|
||||
Collections.<VariableDescriptor, InitializationPoints>emptyMap(),
|
||||
initialMapForStartInstruction,
|
||||
true);
|
||||
|
||||
Map<VariableDescriptor, InitializationPoints> initialMapForStartInstruction = Maps.newHashMap();
|
||||
InitializationPoints initialPointsForDeclaredVariable = new InitializationPoints(false);
|
||||
InitializationPoints initialPointsForExternalVariable = new InitializationPoints(true);
|
||||
|
||||
for (VariableDescriptor variable : usedVariables) {
|
||||
if (declaredVariables.contains(variable)) {
|
||||
initialMapForStartInstruction.put(variable, initialPointsForDeclaredVariable);
|
||||
}
|
||||
else {
|
||||
initialMapForStartInstruction.put(variable, initialPointsForExternalVariable);
|
||||
}
|
||||
}
|
||||
final Map<Instruction, Pair<Map<VariableDescriptor, InitializationPoints>, Map<VariableDescriptor, InitializationPoints>>> dataMap =
|
||||
JetControlFlowGraphTraverser.traverseInstructionGraphUntilFactsStabilization(pseudocode,
|
||||
instructionsMergeStrategy,
|
||||
Collections.<VariableDescriptor, InitializationPoints>emptyMap(),
|
||||
initialMapForStartInstruction,
|
||||
true);
|
||||
|
||||
JetControlFlowGraphTraverser.traverseAndAnalyzeInstructionGraph(pseudocode, new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() {
|
||||
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Map<VariableDescriptor, InitializationPoints>>() {
|
||||
@Override
|
||||
public void execute(Instruction instruction) {
|
||||
Pair<Map<VariableDescriptor, InitializationPoints>, Map<VariableDescriptor, InitializationPoints>> variablesData = dataMap.get(instruction);
|
||||
Map<VariableDescriptor, InitializationPoints> enterData = variablesData.getFirst();
|
||||
Map<VariableDescriptor, InitializationPoints> exitData = variablesData.getSecond();
|
||||
public void execute(Instruction instruction, @Nullable Map<VariableDescriptor, InitializationPoints> enterData, @Nullable Map<VariableDescriptor, InitializationPoints> exitData) {
|
||||
assert enterData != null && exitData != null;
|
||||
if (instruction instanceof ReadValueInstruction) {
|
||||
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
|
||||
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
||||
@@ -380,7 +226,7 @@ public class JetFlowInformationProvider {
|
||||
});
|
||||
|
||||
if (inAnonymousInitializers) {
|
||||
Map<VariableDescriptor, InitializationPoints> lastInfo = dataMap.get(pseudocode.getExitInstruction()).getFirst();
|
||||
Map<VariableDescriptor, InitializationPoints> lastInfo = traverser.getResultInfo();
|
||||
for (Map.Entry<VariableDescriptor, InitializationPoints> entry : lastInfo.entrySet()) {
|
||||
VariableDescriptor variable = entry.getKey();
|
||||
if (variable instanceof PropertyDescriptor) {
|
||||
@@ -390,7 +236,26 @@ public class JetFlowInformationProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<VariableDescriptor, InitializationPoints> prepareInitialMapForStartInstruction(JetElement subroutine, Pseudocode pseudocode) {
|
||||
Collection<VariableDescriptor> usedVariables = collectUsedVariables(pseudocode);
|
||||
Collection<VariableDescriptor> declaredVariables = collectDeclaredVariables(subroutine);
|
||||
|
||||
Map<VariableDescriptor, InitializationPoints> initialMapForStartInstruction = Maps.newHashMap();
|
||||
InitializationPoints initialPointsForDeclaredVariable = new InitializationPoints(false);
|
||||
InitializationPoints initialPointsForExternalVariable = new InitializationPoints(true);
|
||||
|
||||
for (VariableDescriptor variable : usedVariables) {
|
||||
if (declaredVariables.contains(variable)) {
|
||||
initialMapForStartInstruction.put(variable, initialPointsForDeclaredVariable);
|
||||
}
|
||||
else {
|
||||
initialMapForStartInstruction.put(variable, initialPointsForExternalVariable);
|
||||
}
|
||||
}
|
||||
return initialMapForStartInstruction;
|
||||
}
|
||||
|
||||
public void markNotOnlyInvokedFunctionVariables(@NotNull JetElement subroutine, List<? extends VariableDescriptor> variables) {
|
||||
final List<VariableDescriptor> functionVariables = Lists.newArrayList();
|
||||
for (VariableDescriptor variable : variables) {
|
||||
@@ -402,16 +267,16 @@ public class JetFlowInformationProvider {
|
||||
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
||||
assert pseudocode != null;
|
||||
|
||||
JetControlFlowGraphTraverser.traverseAndAnalyzeInstructionGraph(pseudocode, new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() {
|
||||
JetControlFlowGraphTraverser.<Void>create(pseudocode).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
|
||||
@Override
|
||||
public void execute(Instruction instruction) {
|
||||
public void execute(Instruction instruction, Void enterData, Void exitData) {
|
||||
if (instruction instanceof ReadValueInstruction) {
|
||||
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
|
||||
if (variableDescriptor != null && functionVariables.contains(variableDescriptor)) {
|
||||
//check that we only invoke this variable
|
||||
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
||||
if (element instanceof JetSimpleNameExpression && !(element.getParent() instanceof JetCallExpression)) {
|
||||
trace.report(Errors.FUNCTION_PARAMETERS_OF_INLINE_FUNCTION.on((JetSimpleNameExpression)element, variableDescriptor));
|
||||
trace.report(Errors.FUNCTION_PARAMETERS_OF_INLINE_FUNCTION.on((JetSimpleNameExpression) element, variableDescriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,9 +314,9 @@ public class JetFlowInformationProvider {
|
||||
|
||||
private Collection<VariableDescriptor> collectUsedVariables(Pseudocode pseudocode) {
|
||||
final Set<VariableDescriptor> usedVariables = Sets.newHashSet();
|
||||
JetControlFlowGraphTraverser.traverseAndAnalyzeInstructionGraph(pseudocode, new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() {
|
||||
JetControlFlowGraphTraverser.<Void>create(pseudocode).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
|
||||
@Override
|
||||
public void execute(Instruction instruction) {
|
||||
public void execute(Instruction instruction, Void enterData, Void exitData) {
|
||||
VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
|
||||
if (variableDescriptor != null) {
|
||||
usedVariables.add(variableDescriptor);
|
||||
@@ -462,13 +327,13 @@ public class JetFlowInformationProvider {
|
||||
}
|
||||
|
||||
private Collection<VariableDescriptor> collectDeclaredVariables(JetElement element) {
|
||||
final Set<VariableDescriptor> concernedVariables = Sets.newHashSet();
|
||||
final Set<VariableDescriptor> declaredVariables = Sets.newHashSet();
|
||||
element.accept(new JetTreeVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitProperty(JetProperty property, Void data) {
|
||||
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, property);
|
||||
assert descriptor instanceof VariableDescriptor;
|
||||
concernedVariables.add((VariableDescriptor) descriptor);
|
||||
declaredVariables.add((VariableDescriptor) descriptor);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -478,12 +343,12 @@ public class JetFlowInformationProvider {
|
||||
if (loopParameter != null) {
|
||||
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, loopParameter);
|
||||
assert descriptor instanceof VariableDescriptor;
|
||||
concernedVariables.add((VariableDescriptor) descriptor);
|
||||
declaredVariables.add((VariableDescriptor) descriptor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, null);
|
||||
return concernedVariables;
|
||||
return declaredVariables;
|
||||
}
|
||||
|
||||
private static class InitializationPoints {
|
||||
|
||||
Reference in New Issue
Block a user