ControlFlowBuilder: converted to Kotlin

This commit is contained in:
Mikhail Glukhikh
2016-01-26 18:13:42 +03:00
parent 41eed948be
commit 605da5b7b9
3 changed files with 105 additions and 128 deletions
@@ -14,151 +14,128 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.cfg; package org.jetbrains.kotlin.cfg
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue; import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode; import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*; import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.List; interface ControlFlowBuilder {
import java.util.Map;
public interface ControlFlowBuilder {
// Subroutines // Subroutines
void enterSubroutine(@NotNull KtElement subroutine); fun enterSubroutine(subroutine: KtElement)
@NotNull fun exitSubroutine(subroutine: KtElement): Pseudocode
Pseudocode exitSubroutine(@NotNull KtElement subroutine);
@NotNull val currentSubroutine: KtElement
KtElement getCurrentSubroutine(); val returnSubroutine: KtElement?
@Nullable
KtElement getReturnSubroutine();
// Lexical scopes // Lexical scopes
void enterLexicalScope(@NotNull KtElement element); fun enterLexicalScope(element: KtElement)
void exitLexicalScope(@NotNull KtElement element);
fun exitLexicalScope(element: KtElement)
// Entry/exit points // Entry/exit points
@NotNull fun getEntryPoint(labelElement: KtElement): Label
Label getEntryPoint(@NotNull KtElement labelElement);
@NotNull fun getExitPoint(labelElement: KtElement): Label
Label getExitPoint(@NotNull KtElement labelElement); fun getConditionEntryPoint(labelElement: KtElement): Label
@NotNull
Label getConditionEntryPoint(@NotNull KtElement labelElement);
// Declarations // Declarations
void declareParameter(@NotNull KtParameter parameter); fun declareParameter(parameter: KtParameter)
void declareVariable(@NotNull KtVariableDeclaration property);
void declareFunction(@NotNull KtElement subroutine, @NotNull Pseudocode pseudocode); fun declareVariable(property: KtVariableDeclaration)
fun declareFunction(subroutine: KtElement, pseudocode: Pseudocode)
// Labels // Labels
@NotNull fun createUnboundLabel(): Label
Label createUnboundLabel();
@NotNull
Label createUnboundLabel(@NotNull String name);
void bindLabel(@NotNull Label label); fun createUnboundLabel(name: String): Label
fun bindLabel(label: Label)
// Jumps // Jumps
void jump(@NotNull Label label, @NotNull KtElement element); fun jump(label: Label, element: KtElement)
void jumpOnFalse(@NotNull Label label, @NotNull KtElement element, @Nullable PseudoValue conditionValue);
void jumpOnTrue(@NotNull Label label, @NotNull KtElement element, @Nullable PseudoValue conditionValue);
void nondeterministicJump(@NotNull Label label, @NotNull KtElement element, @Nullable PseudoValue inputValue); // Maybe, jump to label
void nondeterministicJump(@NotNull List<Label> label, @NotNull KtElement element);
void jumpToError(@NotNull KtElement element);
void returnValue(@NotNull KtExpression returnExpression, @NotNull PseudoValue returnValue, @NotNull KtElement subroutine); fun jumpOnFalse(label: Label, element: KtElement, conditionValue: PseudoValue?)
void returnNoValue(@NotNull KtReturnExpression returnExpression, @NotNull KtElement subroutine); fun jumpOnTrue(label: Label, element: KtElement, conditionValue: PseudoValue?)
fun nondeterministicJump(label: Label, element: KtElement, inputValue: PseudoValue?) // Maybe, jump to label
fun nondeterministicJump(label: List<Label>, element: KtElement)
fun jumpToError(element: KtElement)
void throwException(@NotNull KtThrowExpression throwExpression, @NotNull PseudoValue thrownValue); fun returnValue(returnExpression: KtExpression, returnValue: PseudoValue, subroutine: KtElement)
fun returnNoValue(returnExpression: KtReturnExpression, subroutine: KtElement)
fun throwException(throwExpression: KtThrowExpression, thrownValue: PseudoValue)
// Loops // Loops
@NotNull fun enterLoop(expression: KtLoopExpression): LoopInfo
LoopInfo enterLoop(@NotNull KtLoopExpression expression);
void enterLoopBody(@NotNull KtLoopExpression expression); fun enterLoopBody(expression: KtLoopExpression)
void exitLoopBody(@NotNull KtLoopExpression expression); fun exitLoopBody(expression: KtLoopExpression)
@Nullable val currentLoop: KtLoopExpression?
KtLoopExpression getCurrentLoop();
// Try-Finally // Try-Finally
void enterTryFinally(@NotNull GenerationTrigger trigger); fun enterTryFinally(trigger: GenerationTrigger)
void exitTryFinally();
void repeatPseudocode(@NotNull Label startLabel, @NotNull Label finishLabel); fun exitTryFinally()
fun repeatPseudocode(startLabel: Label, finishLabel: Label)
// Reading values // Reading values
void mark(@NotNull KtElement element); fun mark(element: KtElement)
@Nullable fun getBoundValue(element: KtElement?): PseudoValue?
PseudoValue getBoundValue(@Nullable KtElement element); fun bindValue(value: PseudoValue, element: KtElement)
void bindValue(@NotNull PseudoValue value, @NotNull KtElement element); fun newValue(element: KtElement?): PseudoValue
@NotNull
PseudoValue newValue(@Nullable KtElement element);
void loadUnit(@NotNull KtExpression expression); fun loadUnit(expression: KtExpression)
@NotNull fun loadConstant(expression: KtExpression, constant: CompileTimeConstant<*>?): InstructionWithValue
InstructionWithValue loadConstant(@NotNull KtExpression expression, @Nullable CompileTimeConstant<?> constant); fun createAnonymousObject(expression: KtObjectLiteralExpression): InstructionWithValue
@NotNull fun createLambda(expression: KtFunction): InstructionWithValue
InstructionWithValue createAnonymousObject(@NotNull KtObjectLiteralExpression expression); fun loadStringTemplate(expression: KtStringTemplateExpression, inputValues: List<PseudoValue>): InstructionWithValue
@NotNull
InstructionWithValue createLambda(@NotNull KtFunction expression);
@NotNull
InstructionWithValue loadStringTemplate(@NotNull KtStringTemplateExpression expression, @NotNull List<PseudoValue> inputValues);
@NotNull fun magic(
MagicInstruction magic( instructionElement: KtElement,
@NotNull KtElement instructionElement, valueElement: KtElement?,
@Nullable KtElement valueElement, inputValues: List<PseudoValue>,
@NotNull List<PseudoValue> inputValues, kind: MagicKind): MagicInstruction
@NotNull MagicKind kind
);
@NotNull fun merge(
MergeInstruction merge( expression: KtExpression,
@NotNull KtExpression expression, inputValues: List<PseudoValue>): MergeInstruction
@NotNull List<PseudoValue> inputValues
);
@NotNull fun readVariable(
ReadValueInstruction readVariable( expression: KtExpression,
@NotNull KtExpression expression, resolvedCall: ResolvedCall<*>,
@NotNull ResolvedCall<?> resolvedCall, receiverValues: Map<PseudoValue, ReceiverValue>): ReadValueInstruction
@NotNull Map<PseudoValue, ReceiverValue> receiverValues
);
@NotNull fun call(
CallInstruction call( valueElement: KtElement,
@NotNull KtElement valueElement, resolvedCall: ResolvedCall<*>,
@NotNull ResolvedCall<?> resolvedCall, receiverValues: Map<PseudoValue, ReceiverValue>,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues, arguments: Map<PseudoValue, ValueParameterDescriptor>): CallInstruction
@NotNull Map<PseudoValue, ValueParameterDescriptor> arguments
);
enum PredefinedOperation { enum class PredefinedOperation {
AND, AND,
OR, OR,
NOT_NULL_ASSERTION NOT_NULL_ASSERTION
} }
@NotNull
OperationInstruction predefinedOperation(
@NotNull KtExpression expression,
@NotNull PredefinedOperation operation,
@NotNull List<PseudoValue> inputValues
);
void write( fun predefinedOperation(
@NotNull KtElement assignment, expression: KtExpression,
@NotNull KtElement lValue, operation: PredefinedOperation,
@NotNull PseudoValue rValue, inputValues: List<PseudoValue>): OperationInstruction
@NotNull AccessTarget target,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues); fun write(
assignment: KtElement,
lValue: KtElement,
rValue: PseudoValue,
target: AccessTarget,
receiverValues: Map<PseudoValue, ReceiverValue>)
} }
@@ -60,7 +60,7 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
@NotNull @NotNull
@Override @Override
public InstructionWithValue loadStringTemplate(@NotNull KtStringTemplateExpression expression, @NotNull List<PseudoValue> inputValues) { public InstructionWithValue loadStringTemplate(@NotNull KtStringTemplateExpression expression, @NotNull List<? extends PseudoValue> inputValues) {
return getDelegateBuilder().loadStringTemplate(expression, inputValues); return getDelegateBuilder().loadStringTemplate(expression, inputValues);
} }
@@ -69,7 +69,7 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
public MagicInstruction magic( public MagicInstruction magic(
@NotNull KtElement instructionElement, @NotNull KtElement instructionElement,
@Nullable KtElement valueElement, @Nullable KtElement valueElement,
@NotNull List<PseudoValue> inputValues, @NotNull List<? extends PseudoValue> inputValues,
@NotNull MagicKind kind @NotNull MagicKind kind
) { ) {
return getDelegateBuilder().magic(instructionElement, valueElement, inputValues, kind); return getDelegateBuilder().magic(instructionElement, valueElement, inputValues, kind);
@@ -77,7 +77,7 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
@NotNull @NotNull
@Override @Override
public MergeInstruction merge(@NotNull KtExpression expression, @NotNull List<PseudoValue> inputValues) { public MergeInstruction merge(@NotNull KtExpression expression, @NotNull List<? extends PseudoValue> inputValues) {
return getDelegateBuilder().merge(expression, inputValues); return getDelegateBuilder().merge(expression, inputValues);
} }
@@ -86,7 +86,7 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
public ReadValueInstruction readVariable( public ReadValueInstruction readVariable(
@NotNull KtExpression expression, @NotNull KtExpression expression,
@NotNull ResolvedCall<?> resolvedCall, @NotNull ResolvedCall<?> resolvedCall,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues @NotNull Map<PseudoValue, ? extends ReceiverValue> receiverValues
) { ) {
return getDelegateBuilder().readVariable(expression, resolvedCall, receiverValues); return getDelegateBuilder().readVariable(expression, resolvedCall, receiverValues);
} }
@@ -96,8 +96,8 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
public CallInstruction call( public CallInstruction call(
@NotNull KtElement valueElement, @NotNull KtElement valueElement,
@NotNull ResolvedCall<?> resolvedCall, @NotNull ResolvedCall<?> resolvedCall,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues, @NotNull Map<PseudoValue, ? extends ReceiverValue> receiverValues,
@NotNull Map<PseudoValue, ValueParameterDescriptor> arguments @NotNull Map<PseudoValue, ? extends ValueParameterDescriptor> arguments
) { ) {
return getDelegateBuilder().call(valueElement, resolvedCall, receiverValues, arguments); return getDelegateBuilder().call(valueElement, resolvedCall, receiverValues, arguments);
} }
@@ -107,7 +107,7 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
public OperationInstruction predefinedOperation( public OperationInstruction predefinedOperation(
@NotNull KtExpression expression, @NotNull KtExpression expression,
@NotNull PredefinedOperation operation, @NotNull PredefinedOperation operation,
@NotNull List<PseudoValue> inputValues @NotNull List<? extends PseudoValue> inputValues
) { ) {
return getDelegateBuilder().predefinedOperation(expression, operation, inputValues); return getDelegateBuilder().predefinedOperation(expression, operation, inputValues);
} }
@@ -150,7 +150,7 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
} }
@Override @Override
public void nondeterministicJump(@NotNull List<Label> labels, @NotNull KtElement element) { public void nondeterministicJump(@NotNull List<? extends Label> labels, @NotNull KtElement element) {
getDelegateBuilder().nondeterministicJump(labels, element); getDelegateBuilder().nondeterministicJump(labels, element);
} }
@@ -253,7 +253,7 @@ public abstract class ControlFlowBuilderAdapter implements ControlFlowBuilder {
@NotNull KtElement lValue, @NotNull KtElement lValue,
@NotNull PseudoValue rValue, @NotNull PseudoValue rValue,
@NotNull AccessTarget target, @NotNull AccessTarget target,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues) { @NotNull Map<PseudoValue, ? extends ReceiverValue> receiverValues) {
getDelegateBuilder().write(assignment, lValue, rValue, target, receiverValues); getDelegateBuilder().write(assignment, lValue, rValue, target, receiverValues);
} }
@@ -323,7 +323,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
@NotNull KtElement lValue, @NotNull KtElement lValue,
@NotNull PseudoValue rValue, @NotNull PseudoValue rValue,
@NotNull AccessTarget target, @NotNull AccessTarget target,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues) { @NotNull Map<PseudoValue, ? extends ReceiverValue> receiverValues) {
add(new WriteValueInstruction(assignment, getCurrentScope(), target, receiverValues, lValue, rValue)); add(new WriteValueInstruction(assignment, getCurrentScope(), target, receiverValues, lValue, rValue));
} }
@@ -377,7 +377,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
} }
@Override @Override
public void nondeterministicJump(@NotNull List<Label> labels, @NotNull KtElement element) { public void nondeterministicJump(@NotNull List<? extends Label> labels, @NotNull KtElement element) {
//todo //todo
//handleJumpInsideTryFinally(label); //handleJumpInsideTryFinally(label);
add(new NondeterministicJumpInstruction(element, labels, getCurrentScope(), null)); add(new NondeterministicJumpInstruction(element, labels, getCurrentScope(), null));
@@ -431,7 +431,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
@NotNull @NotNull
@Override @Override
public InstructionWithValue loadStringTemplate(@NotNull KtStringTemplateExpression expression, @NotNull List<PseudoValue> inputValues) { public InstructionWithValue loadStringTemplate(@NotNull KtStringTemplateExpression expression, @NotNull List<? extends PseudoValue> inputValues) {
return inputValues.isEmpty() ? read(expression) : magic(expression, expression, inputValues, MagicKind.STRING_TEMPLATE); return inputValues.isEmpty() ? read(expression) : magic(expression, expression, inputValues, MagicKind.STRING_TEMPLATE);
} }
@@ -440,7 +440,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
public MagicInstruction magic( public MagicInstruction magic(
@NotNull KtElement instructionElement, @NotNull KtElement instructionElement,
@Nullable KtElement valueElement, @Nullable KtElement valueElement,
@NotNull List<PseudoValue> inputValues, @NotNull List<? extends PseudoValue> inputValues,
@NotNull MagicKind kind @NotNull MagicKind kind
) { ) {
MagicInstruction instruction = new MagicInstruction( MagicInstruction instruction = new MagicInstruction(
@@ -452,7 +452,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
@NotNull @NotNull
@Override @Override
public MergeInstruction merge(@NotNull KtExpression expression, @NotNull List<PseudoValue> inputValues) { public MergeInstruction merge(@NotNull KtExpression expression, @NotNull List<? extends PseudoValue> inputValues) {
MergeInstruction instruction = new MergeInstruction(expression, getCurrentScope(), inputValues, valueFactory); MergeInstruction instruction = new MergeInstruction(expression, getCurrentScope(), inputValues, valueFactory);
add(instruction); add(instruction);
return instruction; return instruction;
@@ -463,7 +463,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
public ReadValueInstruction readVariable( public ReadValueInstruction readVariable(
@NotNull KtExpression expression, @NotNull KtExpression expression,
@NotNull ResolvedCall<?> resolvedCall, @NotNull ResolvedCall<?> resolvedCall,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues @NotNull Map<PseudoValue, ? extends ReceiverValue> receiverValues
) { ) {
return read(expression, resolvedCall, receiverValues); return read(expression, resolvedCall, receiverValues);
} }
@@ -473,8 +473,8 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
public CallInstruction call( public CallInstruction call(
@NotNull KtElement valueElement, @NotNull KtElement valueElement,
@NotNull ResolvedCall<?> resolvedCall, @NotNull ResolvedCall<?> resolvedCall,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues, @NotNull Map<PseudoValue, ? extends ReceiverValue> receiverValues,
@NotNull Map<PseudoValue, ValueParameterDescriptor> arguments @NotNull Map<PseudoValue, ? extends ValueParameterDescriptor> arguments
) { ) {
KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType(); KotlinType returnType = resolvedCall.getResultingDescriptor().getReturnType();
CallInstruction instruction = new CallInstruction( CallInstruction instruction = new CallInstruction(
@@ -494,7 +494,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
public OperationInstruction predefinedOperation( public OperationInstruction predefinedOperation(
@NotNull KtExpression expression, @NotNull KtExpression expression,
@NotNull PredefinedOperation operation, @NotNull PredefinedOperation operation,
@NotNull List<PseudoValue> inputValues @NotNull List<? extends PseudoValue> inputValues
) { ) {
return magic(expression, expression, inputValues, getMagicKind(operation)); return magic(expression, expression, inputValues, getMagicKind(operation));
} }
@@ -517,7 +517,7 @@ public class ControlFlowInstructionsGenerator extends ControlFlowBuilderAdapter
private ReadValueInstruction read( private ReadValueInstruction read(
@NotNull KtExpression expression, @NotNull KtExpression expression,
@Nullable ResolvedCall<?> resolvedCall, @Nullable ResolvedCall<?> resolvedCall,
@NotNull Map<PseudoValue, ReceiverValue> receiverValues @NotNull Map<PseudoValue, ? extends ReceiverValue> receiverValues
) { ) {
AccessTarget accessTarget = resolvedCall != null ? new AccessTarget.Call(resolvedCall) : AccessTarget.BlackBox.INSTANCE; AccessTarget accessTarget = resolvedCall != null ? new AccessTarget.Call(resolvedCall) : AccessTarget.BlackBox.INSTANCE;
ReadValueInstruction instruction = new ReadValueInstruction( ReadValueInstruction instruction = new ReadValueInstruction(