PseudocodeLabel is extracted from PseudocodeImpl (now not an inner class), some its properties / functions are supported now by base Label

(cherry picked from commit 30dd52e)
This commit is contained in:
Mikhail Glukhikh
2016-08-24 14:49:36 +03:00
committed by Mikhail Glukhikh
parent 41ff51ca8c
commit 08f8a2b75c
5 changed files with 80 additions and 51 deletions
@@ -16,6 +16,15 @@
package org.jetbrains.kotlin.cfg
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
interface Label {
val pseudocode: Pseudocode
val name: String
val targetInstructionIndex: Int
fun resolveToInstruction(): Instruction
}
@@ -302,7 +302,7 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
}
override fun bindLabel(label: Label) {
pseudocode.bindLabel(label)
pseudocode.bindLabel(label as PseudocodeLabel)
}
override fun nondeterministicJump(label: Label, element: KtElement, inputValue: PseudoValue?) {
@@ -38,40 +38,8 @@ import org.jetbrains.kotlin.psi.KtElement
import java.util.*
class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode {
inner class PseudocodeLabel internal constructor(private val name: String, private val comment: String?) : Label {
var targetInstructionIndex: Int? = null
private set
override fun getName(): String {
return name
}
override fun toString(): String {
return if (comment == null) name else "$name [$comment]"
}
fun setTargetInstructionIndex(targetInstructionIndex: Int) {
this.targetInstructionIndex = targetInstructionIndex
}
fun resolveToInstruction(): Instruction {
val index = targetInstructionIndex
if (index == null || index >= mutableInstructionList.size) {
error("resolveToInstruction: incorrect index $index for label $name " +
"in subroutine ${correspondingElement.text} with instructions $mutableInstructionList")
}
return mutableInstructionList[index]
}
fun copy(newLabelIndex: Int): PseudocodeLabel {
return PseudocodeLabel("L" + newLabelIndex, "copy of $name, $comment")
}
val pseudocode: PseudocodeImpl
get() = this@PseudocodeImpl
}
private val mutableInstructionList = ArrayList<Instruction>()
internal val mutableInstructionList = ArrayList<Instruction>()
override val instructions = ArrayList<Instruction>()
private val elementsToValues = BidirectionalMap<KtElement, PseudoValue>()
@@ -130,7 +98,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
}
fun createLabel(name: String, comment: String?): PseudocodeLabel {
val label = PseudocodeLabel(name, comment)
val label = PseudocodeLabel(this, name, comment)
labels.add(label)
return label
}
@@ -223,8 +191,8 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
elementsToValues.put(element, value)
}
fun bindLabel(label: Label) {
(label as PseudocodeLabel).setTargetInstructionIndex(mutableInstructionList.size)
fun bindLabel(label: PseudocodeLabel) {
label.targetInstructionIndex = mutableInstructionList.size
}
private fun getMergedValues(value: PseudoValue) = mergedValues[value] ?: emptySet()
@@ -363,7 +331,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
}
private fun getJumpTarget(targetLabel: Label): Instruction {
return (targetLabel as PseudocodeLabel).resolveToInstruction()
return targetLabel.resolveToInstruction()
}
private fun getNextPosition(currentPosition: Int): Instruction {
@@ -388,7 +356,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
}
fun repeatPart(startLabel: Label, finishLabel: Label, labelCount: Int): Int {
return repeatInternal((startLabel as PseudocodeLabel).pseudocode, startLabel, finishLabel, labelCount)
return repeatInternal(startLabel.pseudocode as PseudocodeImpl, startLabel, finishLabel, labelCount)
}
private fun repeatInternal(
@@ -396,17 +364,19 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
startLabel: Label?, finishLabel: Label?,
labelCountArg: Int): Int {
var labelCount = labelCountArg
val startIndex = (if (startLabel != null) (startLabel as PseudocodeLabel).targetInstructionIndex else Integer.valueOf(0))!!
val finishIndex = (if (finishLabel != null)
(finishLabel as PseudocodeLabel).targetInstructionIndex
val startIndex = if (startLabel != null) startLabel.targetInstructionIndex else 0
val finishIndex = if (finishLabel != null)
finishLabel.targetInstructionIndex
else
Integer.valueOf(originalPseudocode.mutableInstructionList.size))!!
originalPseudocode.mutableInstructionList.size
val originalToCopy = Maps.newLinkedHashMap<Label, Label>()
val originalToCopy = Maps.newLinkedHashMap<Label, PseudocodeLabel>()
val originalLabelsForInstruction = HashMultimap.create<Instruction, Label>()
for (label in originalPseudocode.labels) {
val index = label.targetInstructionIndex ?: continue
val index = label.targetInstructionIndex
//label is not bounded yet
if (index < 0) continue
if (label === startLabel || label === finishLabel) continue
if (startIndex <= index && index <= finishIndex) {
@@ -415,7 +385,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
}
}
for (label in originalToCopy.values) {
labels.add(label as PseudocodeLabel)
labels.add(label)
}
for (index in startIndex..finishIndex - 1) {
val originalInstruction = originalPseudocode.mutableInstructionList[index]
@@ -442,14 +412,14 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
private fun repeatLabelsBindingForInstruction(
originalInstruction: Instruction,
originalToCopy: Map<Label, Label>,
originalToCopy: Map<Label, PseudocodeLabel>,
originalLabelsForInstruction: Multimap<Instruction, Label>) {
for (originalLabel in originalLabelsForInstruction.get(originalInstruction)) {
bindLabel(originalToCopy[originalLabel]!!)
}
}
private fun copyInstruction(instruction: Instruction, originalToCopy: Map<Label, Label>): Instruction {
private fun copyInstruction(instruction: Instruction, originalToCopy: Map<Label, PseudocodeLabel>): Instruction {
if (instruction is AbstractJumpInstruction) {
val originalTarget = instruction.targetLabel
if (originalToCopy.containsKey(originalTarget)) {
@@ -464,7 +434,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
return (instruction as InstructionImpl).copy()
}
private fun copyLabels(labels: Collection<Label>, originalToCopy: Map<Label, Label>): MutableList<Label> {
private fun copyLabels(labels: Collection<Label>, originalToCopy: Map<Label, PseudocodeLabel>): MutableList<Label> {
val newLabels = Lists.newArrayList<Label>()
for (label in labels) {
val newLabel = originalToCopy[label]
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2016 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.kotlin.cfg.pseudocode
import org.jetbrains.kotlin.cfg.Label
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
import org.jetbrains.kotlin.psi.KtElement
class PseudocodeLabel internal constructor(
override val pseudocode: PseudocodeImpl, override val name: String, private val comment: String?
) : Label {
private val instructionList: List<Instruction> get() = pseudocode.mutableInstructionList
private val correspondingElement: KtElement get() = pseudocode.correspondingElement
override var targetInstructionIndex = -1
override fun toString(): String {
return if (comment == null) name else "$name [$comment]"
}
override fun resolveToInstruction(): Instruction {
val index = targetInstructionIndex
if (index < 0 || index >= instructionList.size) {
error("resolveToInstruction: incorrect index $index for label $name " +
"in subroutine ${correspondingElement.text} with instructions $instructionList")
}
return instructionList[index]
}
fun copy(newLabelIndex: Int): PseudocodeLabel {
return PseudocodeLabel(pseudocode, "L" + newLabelIndex, "copy of $name, $comment")
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.analyzer.AnalysisResult;
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode;
import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeImpl;
import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeLabel;
import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeUtil;
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction;
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl;
@@ -183,12 +184,12 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment {
) {
List<Instruction> instructions = pseudocode.getInstructionsIncludingDeadCode();
Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions());
List<PseudocodeImpl.PseudocodeLabel> labels = pseudocode.getLabels();
List<PseudocodeLabel> labels = pseudocode.getLabels();
int instructionColumnWidth = countInstructionColumnWidth(instructions);
for (int i = 0; i < instructions.size(); i++) {
Instruction instruction = instructions.get(i);
for (PseudocodeImpl.PseudocodeLabel label: labels) {
for (PseudocodeLabel label: labels) {
if (label.getTargetInstructionIndex() == i) {
out.append(label).append(":\n");
}