Refactoring: CFG.LexicalScope --> CFG.BlockScope #KT-11965 Fixed
This commit is contained in:
@@ -34,10 +34,10 @@ interface ControlFlowBuilder {
|
|||||||
val currentSubroutine: KtElement
|
val currentSubroutine: KtElement
|
||||||
val returnSubroutine: KtElement
|
val returnSubroutine: KtElement
|
||||||
|
|
||||||
// Lexical scopes
|
// Scopes
|
||||||
fun enterLexicalScope(block: KtElement)
|
fun enterBlockScope(block: KtElement)
|
||||||
|
|
||||||
fun exitLexicalScope(block: KtElement)
|
fun exitBlockScope(block: KtElement)
|
||||||
|
|
||||||
fun getExitPoint(labelElement: KtElement): Label?
|
fun getExitPoint(labelElement: KtElement): Label?
|
||||||
fun getConditionEntryPoint(labelElement: KtElement): Label
|
fun getConditionEntryPoint(labelElement: KtElement): Label
|
||||||
|
|||||||
@@ -217,11 +217,11 @@ abstract class ControlFlowBuilderAdapter : ControlFlowBuilder {
|
|||||||
return delegateBuilder.newValue(element)
|
return delegateBuilder.newValue(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun enterLexicalScope(block: KtElement) {
|
override fun enterBlockScope(block: KtElement) {
|
||||||
delegateBuilder.enterLexicalScope(block)
|
delegateBuilder.enterBlockScope(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitLexicalScope(block: KtElement) {
|
override fun exitBlockScope(block: KtElement) {
|
||||||
delegateBuilder.exitLexicalScope(block)
|
delegateBuilder.exitBlockScope(block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ public class ControlFlowInformationProvider {
|
|||||||
Map<Instruction, Edges<InitControlFlowInfo>> initializers =
|
Map<Instruction, Edges<InitControlFlowInfo>> initializers =
|
||||||
pseudocodeVariablesData.getVariableInitializers();
|
pseudocodeVariablesData.getVariableInitializers();
|
||||||
final Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode, true);
|
final Set<VariableDescriptor> declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode, true);
|
||||||
final LexicalScopeVariableInfo lexicalScopeVariableInfo = pseudocodeVariablesData.getLexicalScopeVariableInfo();
|
final BlockScopeVariableInfo blockScopeVariableInfo = pseudocodeVariablesData.getBlockScopeVariableInfo();
|
||||||
|
|
||||||
final Map<Instruction, DiagnosticFactory<?>> reportedDiagnosticMap = Maps.newHashMap();
|
final Map<Instruction, DiagnosticFactory<?>> reportedDiagnosticMap = Maps.newHashMap();
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ public class ControlFlowInformationProvider {
|
|||||||
) {
|
) {
|
||||||
assert in != null && out != null;
|
assert in != null && out != null;
|
||||||
VariableInitContext ctxt =
|
VariableInitContext ctxt =
|
||||||
new VariableInitContext(instruction, reportedDiagnosticMap, in, out, lexicalScopeVariableInfo);
|
new VariableInitContext(instruction, reportedDiagnosticMap, in, out, blockScopeVariableInfo);
|
||||||
if (ctxt.variableDescriptor == null) return;
|
if (ctxt.variableDescriptor == null) return;
|
||||||
if (instruction instanceof ReadValueInstruction) {
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
ReadValueInstruction readValueInstruction = (ReadValueInstruction) instruction;
|
ReadValueInstruction readValueInstruction = (ReadValueInstruction) instruction;
|
||||||
@@ -1123,22 +1123,22 @@ public class ControlFlowInformationProvider {
|
|||||||
@NotNull Map<Instruction, DiagnosticFactory<?>> map,
|
@NotNull Map<Instruction, DiagnosticFactory<?>> map,
|
||||||
@NotNull Map<VariableDescriptor, VariableControlFlowState> in,
|
@NotNull Map<VariableDescriptor, VariableControlFlowState> in,
|
||||||
@NotNull Map<VariableDescriptor, VariableControlFlowState> out,
|
@NotNull Map<VariableDescriptor, VariableControlFlowState> out,
|
||||||
@NotNull LexicalScopeVariableInfo lexicalScopeVariableInfo
|
@NotNull BlockScopeVariableInfo blockScopeVariableInfo
|
||||||
) {
|
) {
|
||||||
super(instruction, map);
|
super(instruction, map);
|
||||||
enterInitState = initialize(variableDescriptor, lexicalScopeVariableInfo, in);
|
enterInitState = initialize(variableDescriptor, blockScopeVariableInfo, in);
|
||||||
exitInitState = initialize(variableDescriptor, lexicalScopeVariableInfo, out);
|
exitInitState = initialize(variableDescriptor, blockScopeVariableInfo, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private VariableControlFlowState initialize(
|
private VariableControlFlowState initialize(
|
||||||
VariableDescriptor variableDescriptor,
|
VariableDescriptor variableDescriptor,
|
||||||
LexicalScopeVariableInfo lexicalScopeVariableInfo,
|
BlockScopeVariableInfo blockScopeVariableInfo,
|
||||||
Map<VariableDescriptor, VariableControlFlowState> map
|
Map<VariableDescriptor, VariableControlFlowState> map
|
||||||
) {
|
) {
|
||||||
if (variableDescriptor == null) return null;
|
if (variableDescriptor == null) return null;
|
||||||
VariableControlFlowState state = map.get(variableDescriptor);
|
VariableControlFlowState state = map.get(variableDescriptor);
|
||||||
if (state != null) return state;
|
if (state != null) return state;
|
||||||
return PseudocodeVariablesData.getDefaultValueForInitializers(variableDescriptor, instruction, lexicalScopeVariableInfo);
|
return PseudocodeVariablesData.getDefaultValueForInitializers(variableDescriptor, instruction, blockScopeVariableInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -661,7 +661,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
}
|
}
|
||||||
var isFirst = true
|
var isFirst = true
|
||||||
for (catchClause in catchClauses) {
|
for (catchClause in catchClauses) {
|
||||||
builder.enterLexicalScope(catchClause)
|
builder.enterBlockScope(catchClause)
|
||||||
if (!isFirst) {
|
if (!isFirst) {
|
||||||
builder.bindLabel(catchLabels.remove())
|
builder.bindLabel(catchLabels.remove())
|
||||||
}
|
}
|
||||||
@@ -675,7 +675,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
}
|
}
|
||||||
generateInstructions(catchClause.catchBody)
|
generateInstructions(catchClause.catchBody)
|
||||||
builder.jump(afterCatches, expression)
|
builder.jump(afterCatches, expression)
|
||||||
builder.exitLexicalScope(catchClause)
|
builder.exitBlockScope(catchClause)
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.bindLabel(afterCatches)
|
builder.bindLabel(afterCatches)
|
||||||
@@ -708,7 +708,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDoWhileExpression(expression: KtDoWhileExpression) {
|
override fun visitDoWhileExpression(expression: KtDoWhileExpression) {
|
||||||
builder.enterLexicalScope(expression)
|
builder.enterBlockScope(expression)
|
||||||
mark(expression)
|
mark(expression)
|
||||||
val loopInfo = builder.enterLoop(expression)
|
val loopInfo = builder.enterLoop(expression)
|
||||||
|
|
||||||
@@ -728,11 +728,11 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
}
|
}
|
||||||
builder.bindLabel(loopInfo.exitPoint)
|
builder.bindLabel(loopInfo.exitPoint)
|
||||||
builder.loadUnit(expression)
|
builder.loadUnit(expression)
|
||||||
builder.exitLexicalScope(expression)
|
builder.exitBlockScope(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitForExpression(expression: KtForExpression) {
|
override fun visitForExpression(expression: KtForExpression) {
|
||||||
builder.enterLexicalScope(expression)
|
builder.enterBlockScope(expression)
|
||||||
|
|
||||||
generateInstructions(expression.loopRange)
|
generateInstructions(expression.loopRange)
|
||||||
declareLoopParameter(expression)
|
declareLoopParameter(expression)
|
||||||
@@ -754,7 +754,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
builder.exitLoopBody(expression)
|
builder.exitLoopBody(expression)
|
||||||
builder.bindLabel(loopInfo.exitPoint)
|
builder.bindLabel(loopInfo.exitPoint)
|
||||||
builder.loadUnit(expression)
|
builder.loadUnit(expression)
|
||||||
builder.exitLexicalScope(expression)
|
builder.exitBlockScope(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun declareLoopParameter(expression: KtForExpression) {
|
private fun declareLoopParameter(expression: KtForExpression) {
|
||||||
@@ -934,9 +934,9 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBlockExpression(expression: KtBlockExpression) {
|
override fun visitBlockExpression(expression: KtBlockExpression) {
|
||||||
val declareLexicalScope = !isBlockInDoWhile(expression)
|
val declareBlockScope = !isBlockInDoWhile(expression)
|
||||||
if (declareLexicalScope) {
|
if (declareBlockScope) {
|
||||||
builder.enterLexicalScope(expression)
|
builder.enterBlockScope(expression)
|
||||||
}
|
}
|
||||||
mark(expression)
|
mark(expression)
|
||||||
val statements = expression.statements
|
val statements = expression.statements
|
||||||
@@ -956,8 +956,8 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
else {
|
else {
|
||||||
copyValue(statements.lastOrNull(), expression)
|
copyValue(statements.lastOrNull(), expression)
|
||||||
}
|
}
|
||||||
if (declareLexicalScope) {
|
if (declareBlockScope) {
|
||||||
builder.exitLexicalScope(expression)
|
builder.exitBlockScope(expression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.cfg
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.VariableDeclarationInstruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.VariableDeclarationInstruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.Edges
|
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.Edges
|
||||||
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder
|
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder
|
||||||
@@ -33,7 +33,7 @@ class PseudocodeVariableDataCollector(
|
|||||||
private val bindingContext: BindingContext,
|
private val bindingContext: BindingContext,
|
||||||
private val pseudocode: Pseudocode
|
private val pseudocode: Pseudocode
|
||||||
) {
|
) {
|
||||||
val lexicalScopeVariableInfo = computeLexicalScopeVariableInfo(pseudocode)
|
val blockScopeVariableInfo = computeBlockScopeVariableInfo(pseudocode)
|
||||||
|
|
||||||
fun <I : ControlFlowInfo<*>> collectData(
|
fun <I : ControlFlowInfo<*>> collectData(
|
||||||
traversalOrder: TraversalOrder,
|
traversalOrder: TraversalOrder,
|
||||||
@@ -54,23 +54,23 @@ class PseudocodeVariableDataCollector(
|
|||||||
to: Instruction,
|
to: Instruction,
|
||||||
info: I
|
info: I
|
||||||
): I {
|
): I {
|
||||||
// If an edge goes from deeper lexical scope to a less deep one, this means that it points outside of the deeper scope.
|
// If an edge goes from deeper scope to a less deep one, this means that it points outside of the deeper scope.
|
||||||
val toDepth = to.lexicalScope.depth
|
val toDepth = to.blockScope.depth
|
||||||
if (toDepth >= from.lexicalScope.depth) return info
|
if (toDepth >= from.blockScope.depth) return info
|
||||||
|
|
||||||
// Variables declared in an inner (deeper) scope can't be accessed from an outer scope.
|
// Variables declared in an inner (deeper) scope can't be accessed from an outer scope.
|
||||||
// Thus they can be filtered out upon leaving the inner scope.
|
// Thus they can be filtered out upon leaving the inner scope.
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return info.copy().retainAll { variable ->
|
return info.copy().retainAll { variable ->
|
||||||
val lexicalScope = lexicalScopeVariableInfo.declaredIn[variable]
|
val blockScope = blockScopeVariableInfo.declaredIn[variable]
|
||||||
// '-1' for variables declared outside this pseudocode
|
// '-1' for variables declared outside this pseudocode
|
||||||
val depth = lexicalScope?.depth ?: -1
|
val depth = blockScope?.depth ?: -1
|
||||||
depth <= toDepth
|
depth <= toDepth
|
||||||
} as I
|
} as I
|
||||||
}
|
}
|
||||||
|
|
||||||
fun computeLexicalScopeVariableInfo(pseudocode: Pseudocode): LexicalScopeVariableInfo {
|
fun computeBlockScopeVariableInfo(pseudocode: Pseudocode): BlockScopeVariableInfo {
|
||||||
val lexicalScopeVariableInfo = LexicalScopeVariableInfoImpl()
|
val blockScopeVariableInfo = BlockScopeVariableInfoImpl()
|
||||||
pseudocode.traverse(TraversalOrder.FORWARD, { instruction ->
|
pseudocode.traverse(TraversalOrder.FORWARD, { instruction ->
|
||||||
if (instruction is VariableDeclarationInstruction) {
|
if (instruction is VariableDeclarationInstruction) {
|
||||||
val variableDeclarationElement = instruction.variableDeclarationElement
|
val variableDeclarationElement = instruction.variableDeclarationElement
|
||||||
@@ -83,28 +83,28 @@ class PseudocodeVariableDataCollector(
|
|||||||
"Variable descriptor should correspond to the instruction for ${instruction.element.text}.\n" +
|
"Variable descriptor should correspond to the instruction for ${instruction.element.text}.\n" +
|
||||||
"Descriptor: $descriptor"
|
"Descriptor: $descriptor"
|
||||||
}
|
}
|
||||||
lexicalScopeVariableInfo.registerVariableDeclaredInScope(
|
blockScopeVariableInfo.registerVariableDeclaredInScope(
|
||||||
descriptor as VariableDescriptor, instruction.lexicalScope
|
descriptor as VariableDescriptor, instruction.blockScope
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return lexicalScopeVariableInfo
|
return blockScopeVariableInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LexicalScopeVariableInfo {
|
interface BlockScopeVariableInfo {
|
||||||
val declaredIn : Map<VariableDescriptor, LexicalScope>
|
val declaredIn : Map<VariableDescriptor, BlockScope>
|
||||||
val scopeVariables : Map<LexicalScope, Collection<VariableDescriptor>>
|
val scopeVariables : Map<BlockScope, Collection<VariableDescriptor>>
|
||||||
}
|
}
|
||||||
|
|
||||||
class LexicalScopeVariableInfoImpl : LexicalScopeVariableInfo {
|
class BlockScopeVariableInfoImpl : BlockScopeVariableInfo {
|
||||||
override val declaredIn = HashMap<VariableDescriptor, LexicalScope>()
|
override val declaredIn = HashMap<VariableDescriptor, BlockScope>()
|
||||||
override val scopeVariables = HashMap<LexicalScope, MutableCollection<VariableDescriptor>>()
|
override val scopeVariables = HashMap<BlockScope, MutableCollection<VariableDescriptor>>()
|
||||||
|
|
||||||
fun registerVariableDeclaredInScope(variable: VariableDescriptor, lexicalScope: LexicalScope) {
|
fun registerVariableDeclaredInScope(variable: VariableDescriptor, blockScope: BlockScope) {
|
||||||
declaredIn[variable] = lexicalScope
|
declaredIn[variable] = blockScope
|
||||||
val variablesInScope = scopeVariables.getOrPut(lexicalScope, { ArrayList<VariableDescriptor>() })
|
val variablesInScope = scopeVariables.getOrPut(blockScope, { ArrayList<VariableDescriptor>() })
|
||||||
variablesInScope.add(variable)
|
variablesInScope.add(variable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
this.pseudocodeVariableDataCollector = PseudocodeVariableDataCollector(bindingContext, pseudocode)
|
this.pseudocodeVariableDataCollector = PseudocodeVariableDataCollector(bindingContext, pseudocode)
|
||||||
}
|
}
|
||||||
|
|
||||||
val lexicalScopeVariableInfo: LexicalScopeVariableInfo
|
val blockScopeVariableInfo: BlockScopeVariableInfo
|
||||||
get() = pseudocodeVariableDataCollector.lexicalScopeVariableInfo
|
get() = pseudocodeVariableDataCollector.blockScopeVariableInfo
|
||||||
|
|
||||||
fun getDeclaredVariables(pseudocode: Pseudocode, includeInsideLocalDeclarations: Boolean): Set<VariableDescriptor> {
|
fun getDeclaredVariables(pseudocode: Pseudocode, includeInsideLocalDeclarations: Boolean): Set<VariableDescriptor> {
|
||||||
if (!includeInsideLocalDeclarations) {
|
if (!includeInsideLocalDeclarations) {
|
||||||
@@ -88,7 +88,7 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
|
|
||||||
private fun computeVariableInitializers(): Map<Instruction, Edges<InitControlFlowInfo>> {
|
private fun computeVariableInitializers(): Map<Instruction, Edges<InitControlFlowInfo>> {
|
||||||
|
|
||||||
val lexicalScopeVariableInfo = pseudocodeVariableDataCollector.lexicalScopeVariableInfo
|
val blockScopeVariableInfo = pseudocodeVariableDataCollector.blockScopeVariableInfo
|
||||||
|
|
||||||
return pseudocodeVariableDataCollector.collectData(
|
return pseudocodeVariableDataCollector.collectData(
|
||||||
TraversalOrder.FORWARD, /*mergeDataWithLocalDeclarations=*/ true, InitControlFlowInfo()
|
TraversalOrder.FORWARD, /*mergeDataWithLocalDeclarations=*/ true, InitControlFlowInfo()
|
||||||
@@ -97,7 +97,7 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
|
|
||||||
val enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData)
|
val enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData)
|
||||||
val exitInstructionData = addVariableInitStateFromCurrentInstructionIfAny(
|
val exitInstructionData = addVariableInitStateFromCurrentInstructionIfAny(
|
||||||
instruction, enterInstructionData, lexicalScopeVariableInfo)
|
instruction, enterInstructionData, blockScopeVariableInfo)
|
||||||
Edges(enterInstructionData, exitInstructionData)
|
Edges(enterInstructionData, exitInstructionData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
private fun addVariableInitStateFromCurrentInstructionIfAny(
|
private fun addVariableInitStateFromCurrentInstructionIfAny(
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
enterInstructionData: InitControlFlowInfo,
|
enterInstructionData: InitControlFlowInfo,
|
||||||
lexicalScopeVariableInfo: LexicalScopeVariableInfo): InitControlFlowInfo {
|
blockScopeVariableInfo: BlockScopeVariableInfo): InitControlFlowInfo {
|
||||||
if (instruction is MagicInstruction) {
|
if (instruction is MagicInstruction) {
|
||||||
if (instruction.kind === MagicKind.EXHAUSTIVE_WHEN_ELSE) {
|
if (instruction.kind === MagicKind.EXHAUSTIVE_WHEN_ELSE) {
|
||||||
val exitInstructionData = enterInstructionData.copy()
|
val exitInstructionData = enterInstructionData.copy()
|
||||||
@@ -137,7 +137,7 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
// instruction instanceof VariableDeclarationInstruction
|
// instruction instanceof VariableDeclarationInstruction
|
||||||
var enterInitState: VariableControlFlowState? = enterInstructionData[variable]
|
var enterInitState: VariableControlFlowState? = enterInstructionData[variable]
|
||||||
if (enterInitState == null) {
|
if (enterInitState == null) {
|
||||||
enterInitState = getDefaultValueForInitializers(variable, instruction, lexicalScopeVariableInfo)
|
enterInitState = getDefaultValueForInitializers(variable, instruction, blockScopeVariableInfo)
|
||||||
}
|
}
|
||||||
if (!enterInitState.mayBeInitialized() || !enterInitState.isDeclared) {
|
if (!enterInitState.mayBeInitialized() || !enterInitState.isDeclared) {
|
||||||
val isInitialized = enterInitState.mayBeInitialized()
|
val isInitialized = enterInitState.mayBeInitialized()
|
||||||
@@ -201,13 +201,13 @@ class PseudocodeVariablesData(val pseudocode: Pseudocode, private val bindingCon
|
|||||||
fun getDefaultValueForInitializers(
|
fun getDefaultValueForInitializers(
|
||||||
variable: VariableDescriptor,
|
variable: VariableDescriptor,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
lexicalScopeVariableInfo: LexicalScopeVariableInfo
|
blockScopeVariableInfo: BlockScopeVariableInfo
|
||||||
): VariableControlFlowState {
|
): VariableControlFlowState {
|
||||||
//todo: think of replacing it with "MapWithDefaultValue"
|
//todo: think of replacing it with "MapWithDefaultValue"
|
||||||
val declaredIn = lexicalScopeVariableInfo.declaredIn[variable]
|
val declaredIn = blockScopeVariableInfo.declaredIn[variable]
|
||||||
val declaredOutsideThisDeclaration =
|
val declaredOutsideThisDeclaration =
|
||||||
declaredIn == null //declared outside this pseudocode
|
declaredIn == null //declared outside this pseudocode
|
||||||
|| declaredIn.lexicalScopeForContainingDeclaration != instruction.lexicalScope.lexicalScopeForContainingDeclaration
|
|| declaredIn.blockScopeForContainingDeclaration != instruction.blockScope.blockScopeForContainingDeclaration
|
||||||
return VariableControlFlowState.create(/*initState=*/declaredOutsideThisDeclaration)
|
return VariableControlFlowState.create(/*initState=*/declaredOutsideThisDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -20,7 +20,7 @@ import com.intellij.util.containers.Stack
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.cfg.*
|
import org.jetbrains.kotlin.cfg.*
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.*
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.*
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.*
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.*
|
||||||
@@ -39,7 +39,7 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
|||||||
get() = builder ?: throw AssertionError("Builder stack is empty in ControlFlowInstructionsGenerator!")
|
get() = builder ?: throw AssertionError("Builder stack is empty in ControlFlowInstructionsGenerator!")
|
||||||
|
|
||||||
private val loopInfo = Stack<LoopInfo>()
|
private val loopInfo = Stack<LoopInfo>()
|
||||||
private val lexicalScopes = Stack<LexicalScope>()
|
private val blockScopes = Stack<BlockScope>()
|
||||||
private val elementToBlockInfo = HashMap<KtElement, BreakableBlockInfo>()
|
private val elementToBlockInfo = HashMap<KtElement, BreakableBlockInfo>()
|
||||||
private var labelCount = 0
|
private var labelCount = 0
|
||||||
|
|
||||||
@@ -72,13 +72,13 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
|||||||
else {
|
else {
|
||||||
pushBuilder(subroutine, subroutine)
|
pushBuilder(subroutine, subroutine)
|
||||||
}
|
}
|
||||||
delegateBuilder.enterLexicalScope(subroutine)
|
delegateBuilder.enterBlockScope(subroutine)
|
||||||
delegateBuilder.enterSubroutine(subroutine)
|
delegateBuilder.enterSubroutine(subroutine)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitSubroutine(subroutine: KtElement): Pseudocode {
|
override fun exitSubroutine(subroutine: KtElement): Pseudocode {
|
||||||
super.exitSubroutine(subroutine)
|
super.exitSubroutine(subroutine)
|
||||||
delegateBuilder.exitLexicalScope(subroutine)
|
delegateBuilder.exitBlockScope(subroutine)
|
||||||
val worker = popBuilder()
|
val worker = popBuilder()
|
||||||
if (!builders.empty()) {
|
if (!builders.empty()) {
|
||||||
val builder = builders.peek()
|
val builder = builders.peek()
|
||||||
@@ -176,23 +176,23 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() {
|
|||||||
return elementToBlockInfo[labelElement]?.exitPoint
|
return elementToBlockInfo[labelElement]?.exitPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
private val currentScope: LexicalScope
|
private val currentScope: BlockScope
|
||||||
get() = lexicalScopes.peek()
|
get() = blockScopes.peek()
|
||||||
|
|
||||||
override fun enterLexicalScope(block: KtElement) {
|
override fun enterBlockScope(block: KtElement) {
|
||||||
val current = if (lexicalScopes.isEmpty()) null else currentScope
|
val current = if (blockScopes.isEmpty()) null else currentScope
|
||||||
val scope = LexicalScope(current, block)
|
val scope = BlockScope(current, block)
|
||||||
lexicalScopes.push(scope)
|
blockScopes.push(scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exitLexicalScope(block: KtElement) {
|
override fun exitBlockScope(block: KtElement) {
|
||||||
val currentScope = currentScope
|
val currentScope = currentScope
|
||||||
assert(currentScope.block === block) {
|
assert(currentScope.block === block) {
|
||||||
"Exit from not the current lexical scope.\n" +
|
"Exit from not the current block scope.\n" +
|
||||||
"Current scope is for a block: " + currentScope.block.text + ".\n" +
|
"Current scope is for a block: " + currentScope.block.text + ".\n" +
|
||||||
"Exit from the scope for: " + block.text
|
"Exit from the scope for: " + block.text
|
||||||
}
|
}
|
||||||
lexicalScopes.pop()
|
blockScopes.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+3
-3
@@ -19,11 +19,11 @@ package org.jetbrains.kotlin.cfg.pseudocode.instructions
|
|||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
|
|
||||||
class LexicalScope(private val parentScope: LexicalScope?, val block: KtElement) {
|
class BlockScope(private val parentScope: BlockScope?, val block: KtElement) {
|
||||||
val depth: Int = (parentScope?.depth ?: 0) + 1
|
val depth: Int = (parentScope?.depth ?: 0) + 1
|
||||||
|
|
||||||
val lexicalScopeForContainingDeclaration: LexicalScope? by lazy {
|
val blockScopeForContainingDeclaration: BlockScope? by lazy {
|
||||||
var scope: LexicalScope? = this
|
var scope: BlockScope? = this
|
||||||
while (scope != null) {
|
while (scope != null) {
|
||||||
if (scope.block is KtDeclaration) {
|
if (scope.block is KtDeclaration) {
|
||||||
break
|
break
|
||||||
+1
-1
@@ -27,7 +27,7 @@ interface Instruction {
|
|||||||
|
|
||||||
val dead: Boolean
|
val dead: Boolean
|
||||||
|
|
||||||
val lexicalScope: LexicalScope
|
val blockScope: BlockScope
|
||||||
|
|
||||||
val inputValues: List<PseudoValue>
|
val inputValues: List<PseudoValue>
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ import java.util.LinkedHashSet
|
|||||||
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
|
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
|
||||||
|
|
||||||
abstract class InstructionImpl(override val lexicalScope: LexicalScope): Instruction {
|
abstract class InstructionImpl(override val blockScope: BlockScope): Instruction {
|
||||||
private var _owner: Pseudocode? = null
|
private var _owner: Pseudocode? = null
|
||||||
|
|
||||||
override var owner: Pseudocode
|
override var owner: Pseudocode
|
||||||
|
|||||||
+2
-2
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
|||||||
|
|
||||||
abstract class InstructionWithNext(
|
abstract class InstructionWithNext(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : KtElementInstructionImpl(element, lexicalScope) {
|
) : KtElementInstructionImpl(element, blockScope) {
|
||||||
var next: Instruction? = null
|
var next: Instruction? = null
|
||||||
set(value: Instruction?) {
|
set(value: Instruction?) {
|
||||||
field = outgoingEdgeTo(value)
|
field = outgoingEdgeTo(value)
|
||||||
|
|||||||
+2
-2
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.psi.KtElement
|
|||||||
|
|
||||||
abstract class KtElementInstructionImpl(
|
abstract class KtElementInstructionImpl(
|
||||||
override val element: KtElement,
|
override val element: KtElement,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : InstructionImpl(lexicalScope), KtElementInstruction {
|
) : InstructionImpl(blockScope), KtElementInstruction {
|
||||||
protected fun render(element: PsiElement): String =
|
protected fun render(element: PsiElement): String =
|
||||||
element.text?.replace("\\s+".toRegex(), " ") ?: ""
|
element.text?.replace("\\s+".toRegex(), " ") ?: ""
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -19,14 +19,14 @@ package org.jetbrains.kotlin.cfg.pseudocode.instructions.eval
|
|||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
|
|
||||||
class LoadUnitValueInstruction(
|
class LoadUnitValueInstruction(
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : InstructionWithNext(expression, lexicalScope) {
|
) : InstructionWithNext(expression, blockScope) {
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
visitor.visitLoadUnitValue(this)
|
visitor.visitLoadUnitValue(this)
|
||||||
}
|
}
|
||||||
@@ -39,5 +39,5 @@ class LoadUnitValueInstruction(
|
|||||||
"read (Unit)"
|
"read (Unit)"
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
LoadUnitValueInstruction(element as KtExpression, lexicalScope)
|
LoadUnitValueInstruction(element as KtExpression, blockScope)
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -41,25 +41,25 @@ sealed class AccessTarget {
|
|||||||
|
|
||||||
abstract class AccessValueInstruction protected constructor(
|
abstract class AccessValueInstruction protected constructor(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
val target: AccessTarget,
|
val target: AccessTarget,
|
||||||
override val receiverValues: Map<PseudoValue, ReceiverValue>
|
override val receiverValues: Map<PseudoValue, ReceiverValue>
|
||||||
) : InstructionWithNext(element, lexicalScope), InstructionWithReceivers
|
) : InstructionWithNext(element, blockScope), InstructionWithReceivers
|
||||||
|
|
||||||
class ReadValueInstruction private constructor(
|
class ReadValueInstruction private constructor(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
target: AccessTarget,
|
target: AccessTarget,
|
||||||
receiverValues: Map<PseudoValue, ReceiverValue>,
|
receiverValues: Map<PseudoValue, ReceiverValue>,
|
||||||
private var _outputValue: PseudoValue?
|
private var _outputValue: PseudoValue?
|
||||||
) : AccessValueInstruction(element, lexicalScope, target, receiverValues), InstructionWithValue {
|
) : AccessValueInstruction(element, blockScope, target, receiverValues), InstructionWithValue {
|
||||||
constructor(
|
constructor(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
target: AccessTarget,
|
target: AccessTarget,
|
||||||
receiverValues: Map<PseudoValue, ReceiverValue>,
|
receiverValues: Map<PseudoValue, ReceiverValue>,
|
||||||
factory: PseudoValueFactory
|
factory: PseudoValueFactory
|
||||||
): this(element, lexicalScope, target, receiverValues, null) {
|
): this(element, blockScope, target, receiverValues, null) {
|
||||||
_outputValue = factory.newValue(element, this)
|
_outputValue = factory.newValue(element, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,17 +91,17 @@ class ReadValueInstruction private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
ReadValueInstruction(element, lexicalScope, target, receiverValues, outputValue)
|
ReadValueInstruction(element, blockScope, target, receiverValues, outputValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
class WriteValueInstruction(
|
class WriteValueInstruction(
|
||||||
assignment: KtElement,
|
assignment: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
target: AccessTarget,
|
target: AccessTarget,
|
||||||
receiverValues: Map<PseudoValue, ReceiverValue>,
|
receiverValues: Map<PseudoValue, ReceiverValue>,
|
||||||
val lValue: KtElement,
|
val lValue: KtElement,
|
||||||
val rValue: PseudoValue
|
val rValue: PseudoValue
|
||||||
) : AccessValueInstruction(assignment, lexicalScope, target, receiverValues) {
|
) : AccessValueInstruction(assignment, blockScope, target, receiverValues) {
|
||||||
override val inputValues: List<PseudoValue>
|
override val inputValues: List<PseudoValue>
|
||||||
get() = (receiverValues.keys as Collection<PseudoValue>) + rValue
|
get() = (receiverValues.keys as Collection<PseudoValue>) + rValue
|
||||||
|
|
||||||
@@ -119,5 +119,5 @@ class WriteValueInstruction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
WriteValueInstruction(element, lexicalScope, target, receiverValues, lValue, rValue)
|
WriteValueInstruction(element, blockScope, target, receiverValues, lValue, rValue)
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.cfg.pseudocode.TypePredicate
|
|||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -30,9 +30,9 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|||||||
|
|
||||||
abstract class OperationInstruction protected constructor(
|
abstract class OperationInstruction protected constructor(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
override val inputValues: List<PseudoValue>
|
override val inputValues: List<PseudoValue>
|
||||||
) : InstructionWithNext(element, lexicalScope), InstructionWithValue {
|
) : InstructionWithNext(element, blockScope), InstructionWithValue {
|
||||||
protected var resultValue: PseudoValue? = null
|
protected var resultValue: PseudoValue? = null
|
||||||
|
|
||||||
override val outputValue: PseudoValue?
|
override val outputValue: PseudoValue?
|
||||||
@@ -55,20 +55,20 @@ abstract class OperationInstruction protected constructor(
|
|||||||
|
|
||||||
class CallInstruction private constructor(
|
class CallInstruction private constructor(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
val resolvedCall: ResolvedCall<*>,
|
val resolvedCall: ResolvedCall<*>,
|
||||||
override val receiverValues: Map<PseudoValue, ReceiverValue>,
|
override val receiverValues: Map<PseudoValue, ReceiverValue>,
|
||||||
val arguments: Map<PseudoValue, ValueParameterDescriptor>
|
val arguments: Map<PseudoValue, ValueParameterDescriptor>
|
||||||
) : OperationInstruction(element, lexicalScope, (receiverValues.keys as Collection<PseudoValue>) + arguments.keys), InstructionWithReceivers {
|
) : OperationInstruction(element, blockScope, (receiverValues.keys as Collection<PseudoValue>) + arguments.keys), InstructionWithReceivers {
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: ResolvedCall<*>,
|
||||||
receiverValues: Map<PseudoValue, ReceiverValue>,
|
receiverValues: Map<PseudoValue, ReceiverValue>,
|
||||||
arguments: Map<PseudoValue, ValueParameterDescriptor>,
|
arguments: Map<PseudoValue, ValueParameterDescriptor>,
|
||||||
factory: PseudoValueFactory?
|
factory: PseudoValueFactory?
|
||||||
): this(element, lexicalScope, resolvedCall, receiverValues, arguments) {
|
): this(element, blockScope, resolvedCall, receiverValues, arguments) {
|
||||||
setResult(factory)
|
setResult(factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ class CallInstruction private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy() =
|
override fun createCopy() =
|
||||||
CallInstruction(element, lexicalScope, resolvedCall, receiverValues, arguments).setResult(resultValue)
|
CallInstruction(element, blockScope, resolvedCall, receiverValues, arguments).setResult(resultValue)
|
||||||
|
|
||||||
override fun toString() =
|
override fun toString() =
|
||||||
renderInstruction("call", "${render(element)}, ${resolvedCall.resultingDescriptor!!.name}")
|
renderInstruction("call", "${render(element)}, ${resolvedCall.resultingDescriptor!!.name}")
|
||||||
@@ -94,18 +94,18 @@ class CallInstruction private constructor(
|
|||||||
// pass more than one value to instruction which formally requires only one (e.g. jump)
|
// pass more than one value to instruction which formally requires only one (e.g. jump)
|
||||||
class MagicInstruction(
|
class MagicInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
inputValues: List<PseudoValue>,
|
inputValues: List<PseudoValue>,
|
||||||
val kind: MagicKind
|
val kind: MagicKind
|
||||||
) : OperationInstruction(element, lexicalScope, inputValues) {
|
) : OperationInstruction(element, blockScope, inputValues) {
|
||||||
constructor (
|
constructor (
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
valueElement: KtElement?,
|
valueElement: KtElement?,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
inputValues: List<PseudoValue>,
|
inputValues: List<PseudoValue>,
|
||||||
kind: MagicKind,
|
kind: MagicKind,
|
||||||
factory: PseudoValueFactory
|
factory: PseudoValueFactory
|
||||||
): this(element, lexicalScope, inputValues, kind) {
|
): this(element, blockScope, inputValues, kind) {
|
||||||
setResult(factory, valueElement)
|
setResult(factory, valueElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ class MagicInstruction(
|
|||||||
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R = visitor.visitMagic(this)
|
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R = visitor.visitMagic(this)
|
||||||
|
|
||||||
override fun createCopy() =
|
override fun createCopy() =
|
||||||
MagicInstruction(element, lexicalScope, inputValues, kind).setResult(resultValue)
|
MagicInstruction(element, blockScope, inputValues, kind).setResult(resultValue)
|
||||||
|
|
||||||
override fun toString() = renderInstruction("magic[$kind]", render(element))
|
override fun toString() = renderInstruction("magic[$kind]", render(element))
|
||||||
}
|
}
|
||||||
@@ -149,15 +149,15 @@ enum class MagicKind(val sideEffectFree: Boolean = false) {
|
|||||||
// Merges values produced by alternative control-flow paths (such as 'if' branches)
|
// Merges values produced by alternative control-flow paths (such as 'if' branches)
|
||||||
class MergeInstruction private constructor(
|
class MergeInstruction private constructor(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
inputValues: List<PseudoValue>
|
inputValues: List<PseudoValue>
|
||||||
): OperationInstruction(element, lexicalScope, inputValues) {
|
): OperationInstruction(element, blockScope, inputValues) {
|
||||||
constructor (
|
constructor (
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
inputValues: List<PseudoValue>,
|
inputValues: List<PseudoValue>,
|
||||||
factory: PseudoValueFactory
|
factory: PseudoValueFactory
|
||||||
): this(element, lexicalScope, inputValues) {
|
): this(element, blockScope, inputValues) {
|
||||||
setResult(factory)
|
setResult(factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ class MergeInstruction private constructor(
|
|||||||
|
|
||||||
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R = visitor.visitMerge(this)
|
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R = visitor.visitMerge(this)
|
||||||
|
|
||||||
override fun createCopy() = MergeInstruction(element, lexicalScope, inputValues).setResult(resultValue)
|
override fun createCopy() = MergeInstruction(element, blockScope, inputValues).setResult(resultValue)
|
||||||
|
|
||||||
override fun toString() = renderInstruction("merge", render(element))
|
override fun toString() = renderInstruction("merge", render(element))
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.cfg.Label
|
import org.jetbrains.kotlin.cfg.Label
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstructionImpl
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstructionImpl
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
@@ -27,21 +27,21 @@ import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
|||||||
abstract class AbstractJumpInstruction(
|
abstract class AbstractJumpInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
val targetLabel: Label,
|
val targetLabel: Label,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : KtElementInstructionImpl(element, lexicalScope), JumpInstruction {
|
) : KtElementInstructionImpl(element, blockScope), JumpInstruction {
|
||||||
var resolvedTarget: Instruction? = null
|
var resolvedTarget: Instruction? = null
|
||||||
set(value: Instruction?) {
|
set(value: Instruction?) {
|
||||||
field = outgoingEdgeTo(value)
|
field = outgoingEdgeTo(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction
|
protected abstract fun createCopy(newLabel: Label, blockScope: BlockScope): AbstractJumpInstruction
|
||||||
|
|
||||||
fun copy(newLabel: Label): Instruction {
|
fun copy(newLabel: Label): Instruction {
|
||||||
return updateCopyInfo(createCopy(newLabel, lexicalScope))
|
return updateCopyInfo(createCopy(newLabel, blockScope))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl {
|
override fun createCopy(): InstructionImpl {
|
||||||
return createCopy(targetLabel, lexicalScope)
|
return createCopy(targetLabel, blockScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val nextInstructions: Collection<Instruction>
|
override val nextInstructions: Collection<Instruction>
|
||||||
|
|||||||
+5
-5
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
|
|||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.cfg.Label
|
import org.jetbrains.kotlin.cfg.Label
|
||||||
import java.util.Arrays
|
import java.util.Arrays
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
@@ -29,9 +29,9 @@ import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
|||||||
class ConditionalJumpInstruction(
|
class ConditionalJumpInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
val onTrue: Boolean,
|
val onTrue: Boolean,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
targetLabel: Label,
|
targetLabel: Label,
|
||||||
val conditionValue: PseudoValue?) : AbstractJumpInstruction(element, targetLabel, lexicalScope) {
|
val conditionValue: PseudoValue?) : AbstractJumpInstruction(element, targetLabel, blockScope) {
|
||||||
private var _nextOnTrue: Instruction? = null
|
private var _nextOnTrue: Instruction? = null
|
||||||
private var _nextOnFalse: Instruction? = null
|
private var _nextOnFalse: Instruction? = null
|
||||||
|
|
||||||
@@ -67,6 +67,6 @@ class ConditionalJumpInstruction(
|
|||||||
return "$instr(${targetLabel.name}$inValue)"
|
return "$instr(${targetLabel.name}$inValue)"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction =
|
override fun createCopy(newLabel: Label, blockScope: BlockScope): AbstractJumpInstruction =
|
||||||
ConditionalJumpInstruction(element, onTrue, lexicalScope, newLabel, conditionValue)
|
ConditionalJumpInstruction(element, onTrue, blockScope, newLabel, conditionValue)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.psi.KtElement
|
|||||||
import org.jetbrains.kotlin.cfg.Label
|
import org.jetbrains.kotlin.cfg.Label
|
||||||
import com.google.common.collect.Maps
|
import com.google.common.collect.Maps
|
||||||
import com.google.common.collect.Lists
|
import com.google.common.collect.Lists
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstructionImpl
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstructionImpl
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
@@ -32,9 +32,9 @@ import org.jetbrains.kotlin.utils.emptyOrSingletonList
|
|||||||
class NondeterministicJumpInstruction(
|
class NondeterministicJumpInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
targetLabels: List<Label>,
|
targetLabels: List<Label>,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
val inputValue: PseudoValue?
|
val inputValue: PseudoValue?
|
||||||
) : KtElementInstructionImpl(element, lexicalScope), JumpInstruction {
|
) : KtElementInstructionImpl(element, blockScope), JumpInstruction {
|
||||||
private var _next: Instruction? = null
|
private var _next: Instruction? = null
|
||||||
private val _resolvedTargets: MutableMap<Label, Instruction> = Maps.newLinkedHashMap()
|
private val _resolvedTargets: MutableMap<Label, Instruction> = Maps.newLinkedHashMap()
|
||||||
|
|
||||||
@@ -85,6 +85,6 @@ class NondeterministicJumpInstruction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createCopy(newTargetLabels: List<Label>): InstructionImpl {
|
private fun createCopy(newTargetLabels: List<Label>): InstructionImpl {
|
||||||
return NondeterministicJumpInstruction(element, newTargetLabels, lexicalScope, inputValue)
|
return NondeterministicJumpInstruction(element, newTargetLabels, blockScope, inputValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -18,15 +18,15 @@ package org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.cfg.Label
|
import org.jetbrains.kotlin.cfg.Label
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
|
|
||||||
class ReturnNoValueInstruction(
|
class ReturnNoValueInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
targetLabel: Label
|
targetLabel: Label
|
||||||
) : AbstractJumpInstruction(element, targetLabel, lexicalScope) {
|
) : AbstractJumpInstruction(element, targetLabel, blockScope) {
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
visitor.visitReturnNoValue(this)
|
visitor.visitReturnNoValue(this)
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,6 @@ class ReturnNoValueInstruction(
|
|||||||
|
|
||||||
override fun toString(): String = "ret $targetLabel"
|
override fun toString(): String = "ret $targetLabel"
|
||||||
|
|
||||||
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction =
|
override fun createCopy(newLabel: Label, blockScope: BlockScope): AbstractJumpInstruction =
|
||||||
ReturnNoValueInstruction(element, lexicalScope, newLabel)
|
ReturnNoValueInstruction(element, blockScope, newLabel)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -20,17 +20,17 @@ import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
|
|||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.cfg.Label
|
import org.jetbrains.kotlin.cfg.Label
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
import org.jetbrains.kotlin.psi.KtReturnExpression
|
import org.jetbrains.kotlin.psi.KtReturnExpression
|
||||||
|
|
||||||
class ReturnValueInstruction(
|
class ReturnValueInstruction(
|
||||||
returnExpression: KtExpression,
|
returnExpression: KtExpression,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
targetLabel: Label,
|
targetLabel: Label,
|
||||||
val returnedValue: PseudoValue
|
val returnedValue: PseudoValue
|
||||||
) : AbstractJumpInstruction(returnExpression, targetLabel, lexicalScope) {
|
) : AbstractJumpInstruction(returnExpression, targetLabel, blockScope) {
|
||||||
override val inputValues: List<PseudoValue> get() = Collections.singletonList(returnedValue)
|
override val inputValues: List<PseudoValue> get() = Collections.singletonList(returnedValue)
|
||||||
|
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
@@ -45,8 +45,8 @@ class ReturnValueInstruction(
|
|||||||
return "ret(*|$returnedValue) $targetLabel"
|
return "ret(*|$returnedValue) $targetLabel"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction {
|
override fun createCopy(newLabel: Label, blockScope: BlockScope): AbstractJumpInstruction {
|
||||||
return ReturnValueInstruction((element as KtExpression), lexicalScope, newLabel, returnedValue)
|
return ReturnValueInstruction((element as KtExpression), blockScope, newLabel, returnedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
val returnExpressionIfAny: KtReturnExpression? = element as? KtReturnExpression
|
val returnExpressionIfAny: KtReturnExpression? = element as? KtReturnExpression
|
||||||
|
|||||||
+5
-5
@@ -20,16 +20,16 @@ import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
|
|||||||
import org.jetbrains.kotlin.psi.KtThrowExpression
|
import org.jetbrains.kotlin.psi.KtThrowExpression
|
||||||
import org.jetbrains.kotlin.cfg.Label
|
import org.jetbrains.kotlin.cfg.Label
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
|
|
||||||
class ThrowExceptionInstruction(
|
class ThrowExceptionInstruction(
|
||||||
expression: KtThrowExpression,
|
expression: KtThrowExpression,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
errorLabel: Label,
|
errorLabel: Label,
|
||||||
val thrownValue: PseudoValue
|
val thrownValue: PseudoValue
|
||||||
) : AbstractJumpInstruction(expression, errorLabel, lexicalScope) {
|
) : AbstractJumpInstruction(expression, errorLabel, blockScope) {
|
||||||
override val inputValues: List<PseudoValue> get() = Collections.singletonList(thrownValue)
|
override val inputValues: List<PseudoValue> get() = Collections.singletonList(thrownValue)
|
||||||
|
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
@@ -44,7 +44,7 @@ class ThrowExceptionInstruction(
|
|||||||
return "throw (${element.text}|$thrownValue)"
|
return "throw (${element.text}|$thrownValue)"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction {
|
override fun createCopy(newLabel: Label, blockScope: BlockScope): AbstractJumpInstruction {
|
||||||
return ThrowExceptionInstruction((element as KtThrowExpression), lexicalScope, newLabel, thrownValue)
|
return ThrowExceptionInstruction((element as KtThrowExpression), blockScope, newLabel, thrownValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.cfg.Label
|
|||||||
class UnconditionalJumpInstruction(
|
class UnconditionalJumpInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
targetLabel: Label,
|
targetLabel: Label,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : AbstractJumpInstruction(element, targetLabel, lexicalScope) {
|
) : AbstractJumpInstruction(element, targetLabel, blockScope) {
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
visitor.visitUnconditionalJump(this)
|
visitor.visitUnconditionalJump(this)
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,6 @@ class UnconditionalJumpInstruction(
|
|||||||
|
|
||||||
override fun toString(): String = "jmp(${targetLabel.name})"
|
override fun toString(): String = "jmp(${targetLabel.name})"
|
||||||
|
|
||||||
override fun createCopy(newLabel: Label, lexicalScope: LexicalScope): AbstractJumpInstruction =
|
override fun createCopy(newLabel: Label, blockScope: BlockScope): AbstractJumpInstruction =
|
||||||
UnconditionalJumpInstruction(element, newLabel, lexicalScope)
|
UnconditionalJumpInstruction(element, newLabel, blockScope)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.cfg.pseudocode.instructions.special
|
|||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
||||||
import com.google.common.collect.Lists
|
import com.google.common.collect.Lists
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
|||||||
class LocalFunctionDeclarationInstruction(
|
class LocalFunctionDeclarationInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
val body: Pseudocode,
|
val body: Pseudocode,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : InstructionWithNext(element, lexicalScope) {
|
) : InstructionWithNext(element, blockScope) {
|
||||||
var sink: SubroutineSinkInstruction? = null
|
var sink: SubroutineSinkInstruction? = null
|
||||||
set(value: SubroutineSinkInstruction?) {
|
set(value: SubroutineSinkInstruction?) {
|
||||||
field = outgoingEdgeTo(value) as SubroutineSinkInstruction?
|
field = outgoingEdgeTo(value) as SubroutineSinkInstruction?
|
||||||
@@ -57,5 +57,5 @@ class LocalFunctionDeclarationInstruction(
|
|||||||
override fun toString(): String = "d(${render(element)})"
|
override fun toString(): String = "d(${render(element)})"
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
LocalFunctionDeclarationInstruction(element, body.copy(), lexicalScope)
|
LocalFunctionDeclarationInstruction(element, body.copy(), blockScope)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -17,15 +17,15 @@
|
|||||||
package org.jetbrains.kotlin.cfg.pseudocode.instructions.special
|
package org.jetbrains.kotlin.cfg.pseudocode.instructions.special
|
||||||
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
|
|
||||||
class MarkInstruction(
|
class MarkInstruction(
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : InstructionWithNext(element, lexicalScope) {
|
) : InstructionWithNext(element, blockScope) {
|
||||||
|
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
visitor.visitMarkInstruction(this)
|
visitor.visitMarkInstruction(this)
|
||||||
@@ -35,7 +35,7 @@ class MarkInstruction(
|
|||||||
return visitor.visitMarkInstruction(this)
|
return visitor.visitMarkInstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy() = MarkInstruction(element, lexicalScope)
|
override fun createCopy() = MarkInstruction(element, blockScope)
|
||||||
|
|
||||||
override fun toString() = "mark(${render(element)})"
|
override fun toString() = "mark(${render(element)})"
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.cfg.pseudocode.instructions.special
|
package org.jetbrains.kotlin.cfg.pseudocode.instructions.special
|
||||||
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
@@ -25,8 +25,8 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
|||||||
|
|
||||||
class SubroutineEnterInstruction(
|
class SubroutineEnterInstruction(
|
||||||
val subroutine: KtElement,
|
val subroutine: KtElement,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : InstructionWithNext(subroutine, lexicalScope) {
|
) : InstructionWithNext(subroutine, blockScope) {
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
visitor.visitSubroutineEnter(this)
|
visitor.visitSubroutineEnter(this)
|
||||||
}
|
}
|
||||||
@@ -38,5 +38,5 @@ class SubroutineEnterInstruction(
|
|||||||
override fun toString(): String = "<START>"
|
override fun toString(): String = "<START>"
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
SubroutineEnterInstruction(subroutine, lexicalScope)
|
SubroutineEnterInstruction(subroutine, blockScope)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -22,9 +22,9 @@ import java.util.*
|
|||||||
|
|
||||||
class SubroutineExitInstruction(
|
class SubroutineExitInstruction(
|
||||||
val subroutine: KtElement,
|
val subroutine: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
val isError: Boolean
|
val isError: Boolean
|
||||||
) : InstructionImpl(lexicalScope) {
|
) : InstructionImpl(blockScope) {
|
||||||
private var _sink: SubroutineSinkInstruction? = null
|
private var _sink: SubroutineSinkInstruction? = null
|
||||||
|
|
||||||
var sink: SubroutineSinkInstruction
|
var sink: SubroutineSinkInstruction
|
||||||
@@ -47,5 +47,5 @@ class SubroutineExitInstruction(
|
|||||||
override fun toString(): String = if (isError) "<ERROR>" else "<END>"
|
override fun toString(): String = if (isError) "<ERROR>" else "<END>"
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
SubroutineExitInstruction(subroutine, lexicalScope, isError)
|
SubroutineExitInstruction(subroutine, blockScope, isError)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.cfg.pseudocode.instructions.special
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithRe
|
|||||||
|
|
||||||
class SubroutineSinkInstruction(
|
class SubroutineSinkInstruction(
|
||||||
val subroutine: KtElement,
|
val subroutine: KtElement,
|
||||||
lexicalScope: LexicalScope,
|
blockScope: BlockScope,
|
||||||
private val debugLabel: String) : InstructionImpl(lexicalScope) {
|
private val debugLabel: String) : InstructionImpl(blockScope) {
|
||||||
override val nextInstructions: Collection<Instruction>
|
override val nextInstructions: Collection<Instruction>
|
||||||
get() = Collections.emptyList()
|
get() = Collections.emptyList()
|
||||||
|
|
||||||
@@ -42,5 +42,5 @@ class SubroutineSinkInstruction(
|
|||||||
override fun toString(): String = debugLabel
|
override fun toString(): String = debugLabel
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
SubroutineSinkInstruction(subroutine, lexicalScope, debugLabel)
|
SubroutineSinkInstruction(subroutine, blockScope, debugLabel)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -20,15 +20,15 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
|||||||
import org.jetbrains.kotlin.psi.KtVariableDeclaration
|
import org.jetbrains.kotlin.psi.KtVariableDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.LexicalScope
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl
|
||||||
|
|
||||||
class VariableDeclarationInstruction(
|
class VariableDeclarationInstruction(
|
||||||
element: KtDeclaration,
|
element: KtDeclaration,
|
||||||
lexicalScope: LexicalScope
|
blockScope: BlockScope
|
||||||
) : InstructionWithNext(element, lexicalScope) {
|
) : InstructionWithNext(element, blockScope) {
|
||||||
init {
|
init {
|
||||||
assert(element is KtVariableDeclaration || element is KtParameter) { "Invalid element: ${render(element)}}" }
|
assert(element is KtVariableDeclaration || element is KtParameter) { "Invalid element: ${render(element)}}" }
|
||||||
}
|
}
|
||||||
@@ -47,5 +47,5 @@ class VariableDeclarationInstruction(
|
|||||||
override fun toString(): String = "v(${render(element)})"
|
override fun toString(): String = "v(${render(element)})"
|
||||||
|
|
||||||
override fun createCopy(): InstructionImpl =
|
override fun createCopy(): InstructionImpl =
|
||||||
VariableDeclarationInstruction(variableDeclarationElement, lexicalScope)
|
VariableDeclarationInstruction(variableDeclarationElement, blockScope)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,8 +147,8 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String getDepthInstructionPrefix(@NotNull Instruction instruction, @Nullable Instruction previous) {
|
private static String getDepthInstructionPrefix(@NotNull Instruction instruction, @Nullable Instruction previous) {
|
||||||
Integer prevDepth = previous != null ? previous.getLexicalScope().getDepth() : null;
|
Integer prevDepth = previous != null ? previous.getBlockScope().getDepth() : null;
|
||||||
int depth = instruction.getLexicalScope().getDepth();
|
int depth = instruction.getBlockScope().getDepth();
|
||||||
if (prevDepth == null || depth != prevDepth) {
|
if (prevDepth == null || depth != prevDepth) {
|
||||||
return String.format("%2d ", depth);
|
return String.format("%2d ", depth);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user