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:
committed by
Mikhail Glukhikh
parent
41ff51ca8c
commit
08f8a2b75c
@@ -16,6 +16,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cfg
|
package org.jetbrains.kotlin.cfg
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
|
|
||||||
interface Label {
|
interface Label {
|
||||||
|
val pseudocode: Pseudocode
|
||||||
|
|
||||||
val name: String
|
val name: String
|
||||||
|
|
||||||
|
val targetInstructionIndex: Int
|
||||||
|
|
||||||
|
fun resolveToInstruction(): Instruction
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -302,7 +302,7 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun bindLabel(label: Label) {
|
override fun bindLabel(label: Label) {
|
||||||
pseudocode.bindLabel(label)
|
pseudocode.bindLabel(label as PseudocodeLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun nondeterministicJump(label: Label, element: KtElement, inputValue: PseudoValue?) {
|
override fun nondeterministicJump(label: Label, element: KtElement, inputValue: PseudoValue?) {
|
||||||
|
|||||||
@@ -38,40 +38,8 @@ import org.jetbrains.kotlin.psi.KtElement
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode {
|
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 {
|
internal val mutableInstructionList = ArrayList<Instruction>()
|
||||||
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>()
|
|
||||||
override val instructions = ArrayList<Instruction>()
|
override val instructions = ArrayList<Instruction>()
|
||||||
|
|
||||||
private val elementsToValues = BidirectionalMap<KtElement, PseudoValue>()
|
private val elementsToValues = BidirectionalMap<KtElement, PseudoValue>()
|
||||||
@@ -130,7 +98,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createLabel(name: String, comment: String?): PseudocodeLabel {
|
fun createLabel(name: String, comment: String?): PseudocodeLabel {
|
||||||
val label = PseudocodeLabel(name, comment)
|
val label = PseudocodeLabel(this, name, comment)
|
||||||
labels.add(label)
|
labels.add(label)
|
||||||
return label
|
return label
|
||||||
}
|
}
|
||||||
@@ -223,8 +191,8 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
|
|||||||
elementsToValues.put(element, value)
|
elementsToValues.put(element, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bindLabel(label: Label) {
|
fun bindLabel(label: PseudocodeLabel) {
|
||||||
(label as PseudocodeLabel).setTargetInstructionIndex(mutableInstructionList.size)
|
label.targetInstructionIndex = mutableInstructionList.size
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMergedValues(value: PseudoValue) = mergedValues[value] ?: emptySet()
|
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 {
|
private fun getJumpTarget(targetLabel: Label): Instruction {
|
||||||
return (targetLabel as PseudocodeLabel).resolveToInstruction()
|
return targetLabel.resolveToInstruction()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNextPosition(currentPosition: Int): Instruction {
|
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 {
|
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(
|
private fun repeatInternal(
|
||||||
@@ -396,17 +364,19 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
|
|||||||
startLabel: Label?, finishLabel: Label?,
|
startLabel: Label?, finishLabel: Label?,
|
||||||
labelCountArg: Int): Int {
|
labelCountArg: Int): Int {
|
||||||
var labelCount = labelCountArg
|
var labelCount = labelCountArg
|
||||||
val startIndex = (if (startLabel != null) (startLabel as PseudocodeLabel).targetInstructionIndex else Integer.valueOf(0))!!
|
val startIndex = if (startLabel != null) startLabel.targetInstructionIndex else 0
|
||||||
val finishIndex = (if (finishLabel != null)
|
val finishIndex = if (finishLabel != null)
|
||||||
(finishLabel as PseudocodeLabel).targetInstructionIndex
|
finishLabel.targetInstructionIndex
|
||||||
else
|
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>()
|
val originalLabelsForInstruction = HashMultimap.create<Instruction, Label>()
|
||||||
for (label in originalPseudocode.labels) {
|
for (label in originalPseudocode.labels) {
|
||||||
val index = label.targetInstructionIndex ?: continue
|
val index = label.targetInstructionIndex
|
||||||
//label is not bounded yet
|
//label is not bounded yet
|
||||||
|
if (index < 0) continue
|
||||||
|
|
||||||
if (label === startLabel || label === finishLabel) continue
|
if (label === startLabel || label === finishLabel) continue
|
||||||
|
|
||||||
if (startIndex <= index && index <= finishIndex) {
|
if (startIndex <= index && index <= finishIndex) {
|
||||||
@@ -415,7 +385,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (label in originalToCopy.values) {
|
for (label in originalToCopy.values) {
|
||||||
labels.add(label as PseudocodeLabel)
|
labels.add(label)
|
||||||
}
|
}
|
||||||
for (index in startIndex..finishIndex - 1) {
|
for (index in startIndex..finishIndex - 1) {
|
||||||
val originalInstruction = originalPseudocode.mutableInstructionList[index]
|
val originalInstruction = originalPseudocode.mutableInstructionList[index]
|
||||||
@@ -442,14 +412,14 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
|
|||||||
|
|
||||||
private fun repeatLabelsBindingForInstruction(
|
private fun repeatLabelsBindingForInstruction(
|
||||||
originalInstruction: Instruction,
|
originalInstruction: Instruction,
|
||||||
originalToCopy: Map<Label, Label>,
|
originalToCopy: Map<Label, PseudocodeLabel>,
|
||||||
originalLabelsForInstruction: Multimap<Instruction, Label>) {
|
originalLabelsForInstruction: Multimap<Instruction, Label>) {
|
||||||
for (originalLabel in originalLabelsForInstruction.get(originalInstruction)) {
|
for (originalLabel in originalLabelsForInstruction.get(originalInstruction)) {
|
||||||
bindLabel(originalToCopy[originalLabel]!!)
|
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) {
|
if (instruction is AbstractJumpInstruction) {
|
||||||
val originalTarget = instruction.targetLabel
|
val originalTarget = instruction.targetLabel
|
||||||
if (originalToCopy.containsKey(originalTarget)) {
|
if (originalToCopy.containsKey(originalTarget)) {
|
||||||
@@ -464,7 +434,7 @@ class PseudocodeImpl(override val correspondingElement: KtElement) : Pseudocode
|
|||||||
return (instruction as InstructionImpl).copy()
|
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>()
|
val newLabels = Lists.newArrayList<Label>()
|
||||||
for (label in labels) {
|
for (label in labels) {
|
||||||
val newLabel = originalToCopy[label]
|
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.analyzer.AnalysisResult;
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode;
|
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode;
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeImpl;
|
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.PseudocodeUtil;
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction;
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction;
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl;
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl;
|
||||||
@@ -183,12 +184,12 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment {
|
|||||||
) {
|
) {
|
||||||
List<Instruction> instructions = pseudocode.getInstructionsIncludingDeadCode();
|
List<Instruction> instructions = pseudocode.getInstructionsIncludingDeadCode();
|
||||||
Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions());
|
Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions());
|
||||||
List<PseudocodeImpl.PseudocodeLabel> labels = pseudocode.getLabels();
|
List<PseudocodeLabel> labels = pseudocode.getLabels();
|
||||||
int instructionColumnWidth = countInstructionColumnWidth(instructions);
|
int instructionColumnWidth = countInstructionColumnWidth(instructions);
|
||||||
|
|
||||||
for (int i = 0; i < instructions.size(); i++) {
|
for (int i = 0; i < instructions.size(); i++) {
|
||||||
Instruction instruction = instructions.get(i);
|
Instruction instruction = instructions.get(i);
|
||||||
for (PseudocodeImpl.PseudocodeLabel label: labels) {
|
for (PseudocodeLabel label: labels) {
|
||||||
if (label.getTargetInstructionIndex() == i) {
|
if (label.getTargetInstructionIndex() == i) {
|
||||||
out.append(label).append(":\n");
|
out.append(label).append(":\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user