rewrote PseudocodeVariableDataCollector to kotlin

This commit is contained in:
Svetlana Isakova
2014-02-22 17:33:07 +04:00
parent 1f37a2120e
commit 11c953c220
3 changed files with 100 additions and 82 deletions
@@ -101,6 +101,7 @@ public class PseudocodeTraverser {
}
public interface InstructionDataMergeStrategy<D> {
@NotNull
Edges<D> execute(@NotNull Instruction instruction, @NotNull Collection<D> incomingEdgesData);
}
@@ -113,7 +114,9 @@ public class PseudocodeTraverser {
}
public static class Edges<T> {
@NotNull
public final T in;
@NotNull
public final T out;
Edges(@NotNull T in, @NotNull T out) {
@@ -121,6 +124,7 @@ public class PseudocodeTraverser {
this.out = out;
}
@NotNull
public static <T> Edges<T> create(@NotNull T in, @NotNull T out) {
return new Edges<T>(in, out);
}
@@ -14,119 +14,130 @@
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg;
package org.jetbrains.jet.lang.cfg
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.pseudocode.Instruction;
import org.jetbrains.jet.lang.cfg.pseudocode.LocalFunctionDeclarationInstruction;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.cfg.pseudocode.Instruction
import org.jetbrains.jet.lang.cfg.pseudocode.LocalFunctionDeclarationInstruction
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
import org.jetbrains.jet.lang.psi.JetElement
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.lang.cfg.PseudocodeTraverser.*
import java.util.*;
import java.util.*
public class PseudocodeVariableDataCollector extends PseudocodeTraverser {
private final BindingContext bindingContext;
public class PseudocodeVariableDataCollector(private val bindingContext: BindingContext) : PseudocodeTraverser() {
public PseudocodeVariableDataCollector(@NotNull BindingContext context) {
bindingContext = context;
suppress("UNCHECKED_CAST")
public fun <D> collectDataJ(
pseudocode: Pseudocode,
traversalOrder: TraversalOrder,
instructionDataMergeStrategy: InstructionDataMergeStrategy<MutableMap<VariableDescriptor, D>>
): MutableMap<Instruction, Edges<MutableMap<VariableDescriptor, D>>> {
//see KT-4605
return collectData(
pseudocode, traversalOrder,
instructionDataMergeStrategy as InstructionDataMergeStrategy<Map<VariableDescriptor, D>>
) as MutableMap<Instruction, Edges<MutableMap<VariableDescriptor, D>>>
}
public <D> Map<Instruction, Edges<Map<VariableDescriptor, D>>> collectData(
@NotNull Pseudocode pseudocode,
@NotNull TraversalOrder traversalOrder,
@NotNull InstructionDataMergeStrategy<Map<VariableDescriptor, D>> instructionDataMergeStrategy
) {
Map<VariableDescriptor, D> initialDataValue = Collections.emptyMap();
Map<Instruction, Edges<Map<VariableDescriptor, D>>> edgesMap = Maps.newLinkedHashMap();
initializeEdgesMap(pseudocode, edgesMap, initialDataValue);
edgesMap.put(getStartInstruction(pseudocode, traversalOrder), Edges.create(initialDataValue, initialDataValue));
public fun <D> collectData(
pseudocode: Pseudocode,
traversalOrder: TraversalOrder,
instructionDataMergeStrategy: InstructionDataMergeStrategy<Map<VariableDescriptor, D>>
): Map<Instruction, Edges<Map<VariableDescriptor, D>>> {
val initialDataValue : Map<VariableDescriptor, D> = Collections.emptyMap<VariableDescriptor, D>()
val edgesMap = LinkedHashMap<Instruction, Edges<Map<VariableDescriptor, D>>>()
initializeEdgesMap(pseudocode, edgesMap, initialDataValue)
edgesMap.put(getStartInstruction(pseudocode, traversalOrder),
Edges.create(initialDataValue, initialDataValue))
boolean[] changed = new boolean[1];
changed[0] = true;
val changed = BooleanArray(1)
changed[0] = true
while (changed[0]) {
changed[0] = false;
collectDataFromSubgraph(pseudocode, traversalOrder, LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS, edgesMap,
instructionDataMergeStrategy, Collections.<Instruction>emptyList(), changed, false);
changed[0] = false
collectDataFromSubgraph(
pseudocode, traversalOrder, LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS, edgesMap,
instructionDataMergeStrategy, Collections.emptyList<Instruction>(), changed, false)
}
return edgesMap;
return edgesMap
}
private static <M> void initializeEdgesMap(
@NotNull Pseudocode pseudocode,
@NotNull Map<Instruction, Edges<M>> edgesMap,
@NotNull M initialDataValue
private fun <M> initializeEdgesMap(
pseudocode: Pseudocode,
edgesMap: MutableMap<Instruction, Edges<M>>,
initialDataValue: M
) {
List<Instruction> instructions = pseudocode.getInstructions();
Edges<M> initialEdge = Edges.create(initialDataValue, initialDataValue);
for (Instruction instruction : instructions) {
edgesMap.put(instruction, initialEdge);
if (shouldLookInside(instruction, LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS)) {
initializeEdgesMap(((LocalFunctionDeclarationInstruction) instruction).getBody(), edgesMap, initialDataValue);
val instructions = pseudocode.getInstructions()
val initialEdge = Edges.create(initialDataValue, initialDataValue)
for (instruction in instructions) {
edgesMap.put(instruction, initialEdge)
if (PseudocodeTraverser.shouldLookInside(instruction, LookInsideStrategy.ANALYSE_LOCAL_DECLARATIONS)) {
initializeEdgesMap(((instruction as LocalFunctionDeclarationInstruction)).getBody(), edgesMap, initialDataValue)
}
}
}
private <D> void collectDataFromSubgraph(
@NotNull Pseudocode pseudocode,
@NotNull TraversalOrder traversalOrder,
@NotNull LookInsideStrategy lookInside,
@NotNull Map<Instruction, Edges<Map<VariableDescriptor, D>>> edgesMap,
@NotNull InstructionDataMergeStrategy<Map<VariableDescriptor, D>> instructionDataMergeStrategy,
@NotNull Collection<Instruction> previousSubGraphInstructions,
boolean[] changed,
boolean isLocal
private fun <D> collectDataFromSubgraph(
pseudocode: Pseudocode,
traversalOrder: TraversalOrder,
lookInside: LookInsideStrategy,
edgesMap: MutableMap<Instruction, Edges<Map<VariableDescriptor, D>>>,
instructionDataMergeStrategy: InstructionDataMergeStrategy<Map<VariableDescriptor, D>>,
previousSubGraphInstructions: Collection<Instruction>,
changed: BooleanArray,
isLocal: Boolean
) {
List<Instruction> instructions = getInstructions(pseudocode, traversalOrder);
Instruction startInstruction = getStartInstruction(pseudocode, traversalOrder);
val instructions = getInstructions(pseudocode, traversalOrder)
val startInstruction = getStartInstruction(pseudocode, traversalOrder)
for (Instruction instruction : instructions) {
boolean isStart = isStartInstruction(instruction, traversalOrder);
if (!isLocal && isStart) continue;
for (instruction in instructions) {
val isStart = isStartInstruction(instruction, traversalOrder)
if (!isLocal && isStart)
continue
Collection<Instruction> allPreviousInstructions;
Collection<Instruction> previousInstructions = getPreviousInstruction(instruction, traversalOrder);
val allPreviousInstructions: MutableCollection<Instruction>
val previousInstructions = getPreviousInstruction(instruction, traversalOrder)
if (instruction == startInstruction && !previousSubGraphInstructions.isEmpty()) {
allPreviousInstructions = Lists.newArrayList(previousInstructions);
allPreviousInstructions.addAll(previousSubGraphInstructions);
allPreviousInstructions = ArrayList(previousInstructions)
allPreviousInstructions.addAll(previousSubGraphInstructions)
}
else {
allPreviousInstructions = previousInstructions;
allPreviousInstructions = previousInstructions
}
if (shouldLookInside(instruction, lookInside)) {
LocalFunctionDeclarationInstruction functionInstruction = (LocalFunctionDeclarationInstruction) instruction;
Pseudocode subroutinePseudocode = functionInstruction.getBody();
collectDataFromSubgraph(subroutinePseudocode, traversalOrder, lookInside, edgesMap, instructionDataMergeStrategy,
previousInstructions,
changed, true);
Instruction lastInstruction = getLastInstruction(subroutinePseudocode, traversalOrder);
Edges<Map<VariableDescriptor, D>> previousValue = edgesMap.get(instruction);
Edges<Map<VariableDescriptor, D>> newValue = edgesMap.get(lastInstruction);
if (!previousValue.equals(newValue)) {
changed[0] = true;
edgesMap.put(instruction, newValue);
val functionInstruction = (instruction as LocalFunctionDeclarationInstruction)
val subroutinePseudocode = functionInstruction.getBody()
collectDataFromSubgraph(
subroutinePseudocode, traversalOrder, lookInside, edgesMap, instructionDataMergeStrategy,
previousInstructions, changed, true)
val lastInstruction = getLastInstruction(subroutinePseudocode, traversalOrder)
val previousValue = edgesMap.get(instruction)
val newValue = edgesMap.get(lastInstruction)
if (previousValue != newValue && newValue != null) {
changed[0] = true
edgesMap.put(instruction, newValue)
}
continue;
continue
}
Edges<Map<VariableDescriptor, D>> previousDataValue = edgesMap.get(instruction);
val previousDataValue = edgesMap.get(instruction)
Collection<Map<VariableDescriptor, D>> incomingEdgesData = Sets.newHashSet();
val incomingEdgesData = HashSet<Map<VariableDescriptor, D>>()
for (Instruction previousInstruction : allPreviousInstructions) {
Edges<Map<VariableDescriptor, D>> previousData = edgesMap.get(previousInstruction);
for (previousInstruction in allPreviousInstructions) {
val previousData = edgesMap.get(previousInstruction)
if (previousData != null) {
incomingEdgesData.add(previousData.out);
incomingEdgesData.add(previousData.out)
}
}
Edges<Map<VariableDescriptor, D>> mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData);
val mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData)
if (!mergedData.equals(previousDataValue)) {
changed[0] = true;
edgesMap.put(instruction, mergedData);
changed[0] = true
edgesMap.put(instruction, mergedData)
}
}
}
@@ -135,9 +135,10 @@ public class PseudocodeVariablesData {
final Set<VariableDescriptor> declaredVariables = getDeclaredVariables(pseudocode, true);
return new PseudocodeVariableDataCollector(bindingContext).collectData(
return new PseudocodeVariableDataCollector(bindingContext).collectDataJ(
pseudocode, FORWARD,
new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableInitState>>() {
@NotNull
@Override
public Edges<Map<VariableDescriptor, VariableInitState>> execute(
@NotNull Instruction instruction,
@@ -150,7 +151,8 @@ public class PseudocodeVariablesData {
addVariableInitStateFromCurrentInstructionIfAny(instruction, enterInstructionData, declaredVariables);
return Edges.create(enterInstructionData, exitInstructionData);
}
});
}
);
}
public static VariableInitState getDefaultValueForInitializers(
@@ -229,9 +231,10 @@ public class PseudocodeVariablesData {
@NotNull
public Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> getVariableUseStatusData() {
return new PseudocodeVariableDataCollector(bindingContext).collectData(
return new PseudocodeVariableDataCollector(bindingContext).collectDataJ(
pseudocode, BACKWARD,
new InstructionDataMergeStrategy<Map<VariableDescriptor, VariableUseState>>() {
@NotNull
@Override
public Edges<Map<VariableDescriptor, VariableUseState>> execute(
@NotNull Instruction instruction,