diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index c643fe1a65b..71ddd8e3e44 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -38,6 +38,7 @@ import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.JetMainDetector; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -62,7 +63,7 @@ public class JetFlowInformationProvider { subroutine = declaration; this.trace = trace; pseudocode = new JetControlFlowProcessor(trace).generatePseudocode(declaration); - pseudocodeData = new PseudocodeData(pseudocode, trace); + pseudocodeData = new PseudocodeData(pseudocode, trace.getBindingContext()); } private void collectReturnExpressions(@NotNull final Collection returnedExpressions) { @@ -195,7 +196,7 @@ public class JetFlowInformationProvider { VariableDescriptor variableDescriptor = pseudocodeData.extractVariableDescriptorIfAny(instruction, true); if (variableDescriptor == null) return; if (!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction)) return; - InstructionData.EdgesData variableInitializers = instructionData.getInitializersMap().get( + Edges variableInitializers = instructionData.getInitializersMap().get( variableDescriptor); if (variableInitializers == null) return; if (instruction instanceof ReadValueInstruction) { @@ -394,7 +395,7 @@ public class JetFlowInformationProvider { private void recordInitializedVariables(DeclarationData declarationData, InstructionData instructionData) { for (VariableDescriptor variable : declarationData.usedVariables) { if (variable instanceof PropertyDescriptor && declarationData.declaredVariables.contains(variable)) { - InstructionData.EdgesData variableInitializers = instructionData.getInitializersMap().get(variable); + Edges variableInitializers = instructionData.getInitializersMap().get(variable); if (variableInitializers == null) return; trace.record(BindingContext.IS_INITIALIZED, (PropertyDescriptor) variable, variableInitializers.getIn().isInitialized()); } @@ -411,7 +412,7 @@ public class JetFlowInformationProvider { VariableDescriptor variableDescriptor = pseudocodeData.extractVariableDescriptorIfAny(instruction, false); if (variableDescriptor == null || !declarationData.declaredVariables.contains(variableDescriptor) || !DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), variableDescriptor)) return; - InstructionData.EdgesData statusEdgesData = instructionData.getUseStatusMap().get(variableDescriptor); + Edges statusEdgesData = instructionData.getUseStatusMap().get(variableDescriptor); VariableUseStatus variableUseStatus = statusEdgesData != null ? statusEdgesData.getIn() : null; if (instruction instanceof WriteValueInstruction) { if (trace.get(CAPTURED_IN_CLOSURE, variableDescriptor)) return; @@ -487,10 +488,9 @@ public class JetFlowInformationProvider { public void markUnusedLiteralsInBlock() { assert pseudocode != null; - JetControlFlowGraphTraverser traverser = JetControlFlowGraphTraverser.create(pseudocode, true, true); - traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() { + PseudocodeTraverser.traverseAndAnalyzeInstructionGraph(pseudocode, true, new PseudocodeTraverser.SimpleInstructionDataAnalyzeStrategy() { @Override - public void execute(@NotNull Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) { + public void execute(@NotNull Instruction instruction) { if (!(instruction instanceof ReadValueInstruction)) return; JetElement element = ((ReadValueInstruction) instruction).getElement(); if (!(element instanceof JetFunctionLiteralExpression diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowGraphTraverser.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeTraverser.java similarity index 57% rename from compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowGraphTraverser.java rename to compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeTraverser.java index 874f163e514..54ce272fa1f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowGraphTraverser.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeTraverser.java @@ -19,79 +19,71 @@ 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 com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.cfg.data.Edges; import org.jetbrains.jet.lang.cfg.pseudocode.*; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; /** * @author svtk */ -public class JetControlFlowGraphTraverser { - private final Pseudocode pseudocode; - private final boolean lookInside; - private final boolean directOrder; - private final Map> dataMap = Maps.newLinkedHashMap(); - - public static JetControlFlowGraphTraverser create(@NotNull Pseudocode pseudocode, boolean lookInside, boolean straightDirection) { - return new JetControlFlowGraphTraverser(pseudocode, lookInside, straightDirection); - } - - private JetControlFlowGraphTraverser(@NotNull Pseudocode pseudocode, boolean lookInside, boolean directOrder) { - this.pseudocode = pseudocode; - this.lookInside = lookInside; - this.directOrder = directOrder; - } - +public class PseudocodeTraverser { @NotNull - private Instruction getStartInstruction(@NotNull Pseudocode pseudocode) { + private static Instruction getStartInstruction(@NotNull Pseudocode pseudocode, boolean directOrder) { return directOrder ? pseudocode.getEnterInstruction() : pseudocode.getSinkInstruction(); } - @NotNull - public Map> getDataMap() { - return dataMap; - } - - public void collectInformationFromInstructionGraph( + public static Map> collectInformationFromInstructionGraph( + boolean lookInside, + boolean directOrder, + @NotNull Pseudocode pseudocode, @NotNull D initialDataValue, @NotNull D initialDataValueForEnterInstruction, @NotNull InstructionDataMergeStrategy instructionDataMergeStrategy) { - initializeDataMap(pseudocode, initialDataValue); - dataMap.put(getStartInstruction(pseudocode), - Pair.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction)); + Map> dataMap = Maps.newLinkedHashMap(); + initializeDataMap(lookInside, dataMap, pseudocode, initialDataValue); + dataMap.put(getStartInstruction(pseudocode, directOrder), + Edges.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction)); boolean[] changed = new boolean[1]; changed[0] = true; while (changed[0]) { changed[0] = false; - traverseSubGraph(pseudocode, instructionDataMergeStrategy, Collections.emptyList(), changed, false); + traverseSubGraph(lookInside, pseudocode, dataMap, instructionDataMergeStrategy, Collections.emptyList(), directOrder, changed, false); } + return dataMap; } - private void initializeDataMap( - @NotNull Pseudocode pseudocode, + private static void initializeDataMap( + boolean lookInside, + @NotNull Map> dataMap, @NotNull Pseudocode pseudocode, @NotNull D initialDataValue) { List instructions = pseudocode.getInstructions(); - Pair initialPair = Pair.create(initialDataValue, initialDataValue); + Edges initialEdge = Edges.create(initialDataValue, initialDataValue); for (Instruction instruction : instructions) { - dataMap.put(instruction, initialPair); + dataMap.put(instruction, initialEdge); if (lookInside && instruction instanceof LocalDeclarationInstruction) { - initializeDataMap(((LocalDeclarationInstruction) instruction).getBody(), initialDataValue); + initializeDataMap(lookInside, dataMap, ((LocalDeclarationInstruction) instruction).getBody(), initialDataValue); } } } - private void traverseSubGraph( + private static void traverseSubGraph( + boolean lookInside, @NotNull Pseudocode pseudocode, + @NotNull Map> dataMap, @NotNull InstructionDataMergeStrategy instructionDataMergeStrategy, @NotNull Collection previousSubGraphInstructions, + boolean directOrder, boolean[] changed, boolean isLocal) { List instructions = directOrder ? pseudocode.getInstructions() : pseudocode.getReversedInstructions(); - Instruction startInstruction = getStartInstruction(pseudocode); + Instruction startInstruction = getStartInstruction(pseudocode, directOrder); for (Instruction instruction : instructions) { boolean isStart = directOrder ? instruction instanceof SubroutineEnterInstruction : instruction instanceof SubroutineSinkInstruction; @@ -110,27 +102,27 @@ public class JetControlFlowGraphTraverser { if (lookInside && instruction instanceof LocalDeclarationInstruction) { Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody(); - traverseSubGraph(subroutinePseudocode, instructionDataMergeStrategy, previousInstructions, changed, true); + traverseSubGraph(lookInside, subroutinePseudocode, dataMap ,instructionDataMergeStrategy, previousInstructions, directOrder, changed, true); Instruction lastInstruction = directOrder ? subroutinePseudocode.getSinkInstruction() : subroutinePseudocode.getEnterInstruction(); - Pair previousValue = dataMap.get(instruction); - Pair newValue = dataMap.get(lastInstruction); + Edges previousValue = dataMap.get(instruction); + Edges newValue = dataMap.get(lastInstruction); if (!previousValue.equals(newValue)) { changed[0] = true; dataMap.put(instruction, newValue); } continue; } - Pair previousDataValue = dataMap.get(instruction); + Edges previousDataValue = dataMap.get(instruction); Collection incomingEdgesData = Sets.newHashSet(); for (Instruction previousInstruction : allPreviousInstructions) { - Pair previousData = dataMap.get(previousInstruction); + Edges previousData = dataMap.get(previousInstruction); if (previousData != null) { - incomingEdgesData.add(previousData.getSecond()); + incomingEdgesData.add(previousData.out); } } - Pair mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData); + Edges mergedData = instructionDataMergeStrategy.execute(instruction, incomingEdgesData); if (!mergedData.equals(previousDataValue)) { changed[0] = true; dataMap.put(instruction, mergedData); @@ -138,13 +130,28 @@ public class JetControlFlowGraphTraverser { } } - public void traverseAndAnalyzeInstructionGraph( - @NotNull InstructionDataAnalyzeStrategy instructionDataAnalyzeStrategy) { - traverseAndAnalyzeInstructionGraph(pseudocode, instructionDataAnalyzeStrategy); - } - - private void traverseAndAnalyzeInstructionGraph( + public static void traverseAndAnalyzeInstructionGraph( @NotNull Pseudocode pseudocode, + boolean directOrder, + SimpleInstructionDataAnalyzeStrategy instructionDataAnalyzeStrategy) { + List instructions = pseudocode.getInstructions(); + if (!directOrder) { + instructions = Lists.newArrayList(instructions); + Collections.reverse(instructions); + } + for (Instruction instruction : instructions) { + if (instruction instanceof LocalDeclarationInstruction) { + traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody(), directOrder, instructionDataAnalyzeStrategy); + } + instructionDataAnalyzeStrategy.execute(instruction); + } + } + + public static void traverseAndAnalyzeInstructionGraph( + boolean lookInside, + @NotNull Pseudocode pseudocode, + @NotNull Map> dataMap, + boolean directOrder, @NotNull InstructionDataAnalyzeStrategy instructionDataAnalyzeStrategy) { List instructions = pseudocode.getInstructions(); if (!directOrder) { @@ -153,24 +160,22 @@ public class JetControlFlowGraphTraverser { } for (Instruction instruction : instructions) { if (lookInside && instruction instanceof LocalDeclarationInstruction) { - traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody(), instructionDataAnalyzeStrategy); + traverseAndAnalyzeInstructionGraph(lookInside, ((LocalDeclarationInstruction) instruction).getBody(), dataMap, directOrder, instructionDataAnalyzeStrategy); } - Pair pair = dataMap.get(instruction); - instructionDataAnalyzeStrategy.execute(instruction, - pair != null ? pair.getFirst() : null, - pair != null ? pair.getSecond() : null); + Edges edges = dataMap.get(instruction); + instructionDataAnalyzeStrategy.execute(instruction, edges != null ? edges.in : null, edges != null ? edges.out : null); } } - public D getResultInfo() { - return dataMap.get(pseudocode.getExitInstruction()).getFirst(); - } - public interface InstructionDataMergeStrategy { - Pair execute(@NotNull Instruction instruction, @NotNull Collection incomingEdgesData); + Edges execute(@NotNull Instruction instruction, @NotNull Collection incomingEdgesData); } public interface InstructionDataAnalyzeStrategy { void execute(@NotNull Instruction instruction, @Nullable D enterData, @Nullable D exitData); } + + public interface SimpleInstructionDataAnalyzeStrategy { + void execute(@NotNull Instruction instruction); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/Edges.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/Edges.java new file mode 100644 index 00000000000..519a491743e --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/Edges.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.cfg.data; + +import org.jetbrains.annotations.NotNull; + +/** +* @author svtk +*/ +public class Edges { + public final T in; + public final T out; + + Edges(@NotNull T in, @NotNull T out) { + this.in = in; + this.out = out; + } + + public static Edges create(@NotNull T in, @NotNull T out) { + return new Edges(in, out); + } + + @NotNull + public T getIn() { + return in; + } + + @NotNull + public T getOut() { + return out; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Edges)) return false; + + Edges edges = (Edges) o; + + if (in != null ? !in.equals(edges.in) : edges.in != null) return false; + if (out != null ? !out.equals(edges.out) : edges.out != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = in != null ? in.hashCode() : 0; + result = 31 * result + (out != null ? out.hashCode() : 0); + return result; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/InstructionData.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/InstructionData.java index ec77df1997d..2a0df4cd178 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/InstructionData.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/InstructionData.java @@ -31,62 +31,38 @@ public class InstructionData { public final Instruction instruction; public final PseudocodeData pseudocodeData; - private final Map> initializersMap = Maps.newHashMap(); - private final Map> useStatusMap = Maps.newHashMap(); + private final Map> initializersMap = Maps.newHashMap(); + private final Map> useStatusMap = Maps.newHashMap(); public InstructionData(@NotNull PseudocodeData data, @NotNull Instruction instruction, - @NotNull Pair, Map> pairOfVariableInitializersMap, - @NotNull Pair, Map> pairOfVariableStatusMap) { + @NotNull Edges> pairOfVariableInitializersMap, + @NotNull Edges> pairOfVariableStatusMap) { pseudocodeData = data; this.instruction = instruction; - for (Map.Entry entry : pairOfVariableInitializersMap.second.entrySet()) { + for (Map.Entry entry : pairOfVariableInitializersMap.out.entrySet()) { VariableDescriptor variableDescriptor = entry.getKey(); - VariableInitializers in = pairOfVariableInitializersMap.first.get(variableDescriptor); + VariableInitializers in = pairOfVariableInitializersMap.in.get(variableDescriptor); VariableInitializers out = entry.getValue(); - initializersMap.put(variableDescriptor, EdgesData.create(in, out)); + initializersMap.put(variableDescriptor, Edges.create(in, out)); } - for (Map.Entry entry : pairOfVariableStatusMap.second.entrySet()) { + for (Map.Entry entry : pairOfVariableStatusMap.out.entrySet()) { VariableDescriptor variableDescriptor = entry.getKey(); - VariableUseStatus in = pairOfVariableStatusMap.first.get(variableDescriptor); + VariableUseStatus in = pairOfVariableStatusMap.in.get(variableDescriptor); VariableUseStatus out = entry.getValue(); if (in == null || out == null) continue; - useStatusMap.put(variableDescriptor, EdgesData.create(in, out)); + useStatusMap.put(variableDescriptor, Edges.create(in, out)); } } @NotNull - public Map> getInitializersMap() { + public Map> getInitializersMap() { return initializersMap; } @NotNull - public Map> getUseStatusMap() { + public Map> getUseStatusMap() { return useStatusMap; } - - public static class EdgesData { - private final T in; - private final T out; - - private EdgesData(@NotNull T in, @NotNull T out) { - this.in = in; - this.out = out; - } - - private static EdgesData create(@NotNull T in, @NotNull T out) { - return new EdgesData(in, out); - } - - @NotNull - public T getIn() { - return in; - } - - @NotNull - public T getOut() { - return out; - } - } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/PseudocodeData.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/PseudocodeData.java index ccb6173d932..38d7a54a0d0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/PseudocodeData.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/data/PseudocodeData.java @@ -19,10 +19,9 @@ package org.jetbrains.jet.lang.cfg.data; 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.JetControlFlowGraphTraverser; +import org.jetbrains.jet.lang.cfg.PseudocodeTraverser; import org.jetbrains.jet.lang.cfg.pseudocode.*; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; @@ -31,7 +30,6 @@ import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; -import org.jetbrains.jet.lang.resolve.BindingTrace; import java.util.*; @@ -42,29 +40,38 @@ public class PseudocodeData { private final Pseudocode pseudocode; private final Map instructionDataMap = Maps.newLinkedHashMap(); private final Map declarationDataMap = Maps.newLinkedHashMap(); - private final BindingTrace trace; - public PseudocodeData(@NotNull Pseudocode pseudocode, @NotNull BindingTrace trace) { + //private final Map> declaredVariablesInEachDeclaration; + //private final Map> usedVariablesInEachDeclaration; + + private final BindingContext bindingContext; + + public PseudocodeData(@NotNull Pseudocode pseudocode, @NotNull BindingContext bindingContext) { this.pseudocode = pseudocode; - this.trace = trace; + this.bindingContext = bindingContext; collectDeclarationData(pseudocode); DeclarationData declarationData = declarationDataMap.get(pseudocode); - final Map, Map>> variableInitializersMap = + final Map>> variableInitializersMap = collectVariableInitializers(pseudocode, declarationData); - final Map, Map>> variableStatusMap = + final Map>> variableStatusMap = collectVariableStatusData(); - JetControlFlowGraphTraverser.create(pseudocode, true, true).traverseAndAnalyzeInstructionGraph( - new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() { - @Override - public void execute(@NotNull Instruction instruction, Void enterData, Void exitData) { - instructionDataMap.put(instruction, - new InstructionData(PseudocodeData.this, instruction, variableInitializersMap.get(instruction), - variableStatusMap.get(instruction))); - } - }); + + PseudocodeTraverser.traverseAndAnalyzeInstructionGraph(pseudocode, true, + new PseudocodeTraverser.SimpleInstructionDataAnalyzeStrategy() { + @Override + public void execute(@NotNull Instruction instruction) { + instructionDataMap.put(instruction, + new InstructionData(PseudocodeData.this, + instruction, + variableInitializersMap + .get(instruction), + variableStatusMap + .get(instruction))); + } + }); } @NotNull @@ -126,64 +133,59 @@ public class PseudocodeData { private Set collectUsedVariables(@NotNull Pseudocode pseudocode) { final Set usedVariables = Sets.newHashSet(); - JetControlFlowGraphTraverser.create(pseudocode, true, true).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() { - @Override - public void execute(@NotNull Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) { - VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, false); - if (variableDescriptor != null) { - usedVariables.add(variableDescriptor); - } - } - }); + PseudocodeTraverser.traverseAndAnalyzeInstructionGraph(pseudocode, true, + new PseudocodeTraverser.SimpleInstructionDataAnalyzeStrategy() { + @Override + public void execute(@NotNull Instruction instruction) { + VariableDescriptor variableDescriptor = + extractVariableDescriptorIfAny(instruction, false); + if (variableDescriptor != null) { + usedVariables.add(variableDescriptor); + } + } + }); return usedVariables; } private Set collectDeclaredVariables(@NotNull Pseudocode pseudocode) { final Set declaredVariables = Sets.newHashSet(); - JetControlFlowGraphTraverser.create(pseudocode, false, true).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() { - @Override - public void execute(@NotNull Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) { - if (instruction instanceof VariableDeclarationInstruction) { - JetDeclaration variableDeclarationElement = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement(); - DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement); - if (descriptor != null) { - assert descriptor instanceof VariableDescriptor; - declaredVariables.add((VariableDescriptor) descriptor); - } + for (Instruction instruction : pseudocode.getInstructions()) { + if (instruction instanceof VariableDeclarationInstruction) { + JetDeclaration variableDeclarationElement = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement(); + DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement); + if (descriptor != null) { + assert descriptor instanceof VariableDescriptor; + declaredVariables.add((VariableDescriptor) descriptor); } } - }); + } return declaredVariables; } // variable initializers - private Map, Map>> collectVariableInitializers( + private Map>> collectVariableInitializers( Pseudocode pseudocode, DeclarationData data) { - - JetControlFlowGraphTraverser> traverser = JetControlFlowGraphTraverser.create(pseudocode, false, true); - final Map initialMapForStartInstruction = prepareInitialMapForStartInstruction(data.usedVariables, data.declaredVariables); - traverser.collectInformationFromInstructionGraph(Collections.emptyMap(), initialMapForStartInstruction, - new JetControlFlowGraphTraverser.InstructionDataMergeStrategy>() { + Map>> result = + PseudocodeTraverser.collectInformationFromInstructionGraph(false, true, pseudocode, Collections.emptyMap(), initialMapForStartInstruction, + new PseudocodeTraverser.InstructionDataMergeStrategy>() { @Override - public Pair, Map> execute( + public Edges> execute( @NotNull Instruction instruction, @NotNull Collection> incomingEdgesData) { Map enterInstructionData = mergeIncomingEdgesData(incomingEdgesData); Map exitInstructionData = addVariableInitializerFromCurrentInstructionIfAny(instruction, enterInstructionData); - return Pair.create(enterInstructionData, exitInstructionData); + return Edges.create(enterInstructionData, exitInstructionData); } }); - Map, Map>> result = - traverser.getDataMap(); for (LocalDeclarationInstruction localDeclarationInstruction : pseudocode.getLocalDeclarations()) { Pseudocode localPseudocode = localDeclarationInstruction.getBody(); - Map, Map>> initializersForLocalDeclaration = + Map>> initializersForLocalDeclaration = collectVariableInitializers(localPseudocode, declarationDataMap.get(localPseudocode)); for (Instruction instruction : initializersForLocalDeclaration.keySet()) { @@ -267,17 +269,15 @@ public class PseudocodeData { // variable use - private Map, Map>> collectVariableStatusData() { - JetControlFlowGraphTraverser> traverser = - JetControlFlowGraphTraverser.create(pseudocode, true, false); + private Map>> collectVariableStatusData() { Map sinkInstructionData = Maps.newHashMap(); for (VariableDescriptor usedVariable : declarationDataMap.get(pseudocode).usedVariables) { sinkInstructionData.put(usedVariable, VariableUseStatus.UNUSED); } - traverser.collectInformationFromInstructionGraph(Collections.emptyMap(), sinkInstructionData, - new JetControlFlowGraphTraverser.InstructionDataMergeStrategy>() { + return PseudocodeTraverser.collectInformationFromInstructionGraph(true, false, pseudocode, Collections.emptyMap(), sinkInstructionData, + new PseudocodeTraverser.InstructionDataMergeStrategy>() { @Override - public Pair, Map> execute(@NotNull Instruction instruction, @NotNull Collection> incomingEdgesData) { + public Edges> execute(@NotNull Instruction instruction, @NotNull Collection> incomingEdgesData) { Map enterResult = Maps.newHashMap(); for (Map edgeData : incomingEdgesData) { for (Map.Entry entry : edgeData.entrySet()) { @@ -288,7 +288,7 @@ public class PseudocodeData { } VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, true); if (variableDescriptor == null || (!(instruction instanceof ReadValueInstruction) && !(instruction instanceof WriteValueInstruction))) { - return Pair.create(enterResult, enterResult); + return Edges.create(enterResult, enterResult); } Map exitResult = Maps.newHashMap(enterResult); if (instruction instanceof ReadValueInstruction) { @@ -307,10 +307,9 @@ public class PseudocodeData { exitResult.put(variableDescriptor, VariableUseStatus.LAST_WRITTEN); } } - return Pair.create(enterResult, exitResult); + return Edges.create(enterResult, exitResult); } }); - return traverser.getDataMap(); } // Util methods @@ -327,7 +326,7 @@ public class PseudocodeData { else if (instruction instanceof VariableDeclarationInstruction) { element = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement(); } - return BindingContextUtils.extractVariableDescriptorIfAny(trace.getBindingContext(), element, onlyReference); + return BindingContextUtils.extractVariableDescriptorIfAny(bindingContext, element, onlyReference); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java index 3612cc1a997..f82ce6c46d6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java @@ -65,5 +65,4 @@ public class PseudocodeUtil { return new JetControlFlowProcessor(mockTrace).generatePseudocode(declaration); } - }