Added local declaration instruction to pseudocode
This commit is contained in:
-34
@@ -1,34 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class FunctionLiteralValueInstruction extends ReadValueInstruction {
|
|
||||||
|
|
||||||
private Pseudocode body;
|
|
||||||
|
|
||||||
public FunctionLiteralValueInstruction(@NotNull JetFunctionLiteralExpression expression) {
|
|
||||||
super(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pseudocode getBody() {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBody(Pseudocode body) {
|
|
||||||
this.body = body;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(InstructionVisitor visitor) {
|
|
||||||
visitor.visitFunctionLiteralValue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "rf(" + element.getText() + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ public class InstructionVisitor {
|
|||||||
visitInstructionWithNext(instruction);
|
visitInstructionWithNext(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
public void visitFunctionLiteralValue(LocalDeclarationInstruction instruction) {
|
||||||
visitReadValue(instruction);
|
visitReadValue(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ public class InstructionVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||||
visitJump(instruction);
|
visitInstruction(instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
|
public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
|
||||||
|
|||||||
+21
-15
@@ -2,10 +2,7 @@ package org.jetbrains.jet.lang.cfg.pseudocode;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.cfg.*;
|
import org.jetbrains.jet.lang.cfg.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetThrowExpression;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -25,7 +22,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
private final JetPseudocodeTrace trace;
|
private final JetPseudocodeTrace trace;
|
||||||
|
|
||||||
public JetControlFlowInstructionsGenerator(JetPseudocodeTrace trace) {
|
public JetControlFlowInstructionsGenerator(JetPseudocodeTrace trace) {
|
||||||
super(null);
|
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,28 +37,31 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
if (!builders.isEmpty()) {
|
if (!builders.isEmpty()) {
|
||||||
builder = builders.peek();
|
builder = builders.peek();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
builder = null;
|
||||||
|
}
|
||||||
return worker;
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
public void enterSubroutine(@NotNull JetDeclaration subroutine) {
|
||||||
if (isFunctionLiteral) {
|
if (builder != null) {
|
||||||
pushBuilder(subroutine, builder.getCurrentSubroutine());
|
pushBuilder(subroutine, builder.getCurrentSubroutine());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pushBuilder(subroutine, subroutine);
|
pushBuilder(subroutine, subroutine);
|
||||||
}
|
}
|
||||||
builder.enterSubroutine(subroutine, false);
|
assert builder != null;
|
||||||
|
builder.enterSubroutine(subroutine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
|
||||||
super.exitSubroutine(subroutine, functionLiteral);
|
super.exitSubroutine(subroutine);
|
||||||
JetControlFlowInstructionsGeneratorWorker worker = popBuilder(subroutine);
|
JetControlFlowInstructionsGeneratorWorker worker = popBuilder(subroutine);
|
||||||
if (functionLiteral) {
|
if (!builders.empty()) {
|
||||||
JetControlFlowInstructionsGeneratorWorker builder = builders.peek();
|
JetControlFlowInstructionsGeneratorWorker builder = builders.peek();
|
||||||
FunctionLiteralValueInstruction instruction = new FunctionLiteralValueInstruction((JetFunctionLiteralExpression) subroutine);
|
LocalDeclarationInstruction instruction = new LocalDeclarationInstruction(subroutine, worker.getPseudocode());
|
||||||
instruction.setBody(worker.getPseudocode());
|
|
||||||
builder.add(instruction);
|
builder.add(instruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +127,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enterSubroutine(@NotNull JetElement subroutine, boolean isFunctionLiteral) {
|
public void enterSubroutine(@NotNull JetDeclaration subroutine) {
|
||||||
Label entryPoint = createUnboundLabel();
|
Label entryPoint = createUnboundLabel();
|
||||||
BreakableBlockInfo blockInfo = new BreakableBlockInfo(subroutine, entryPoint, createUnboundLabel());
|
BreakableBlockInfo blockInfo = new BreakableBlockInfo(subroutine, entryPoint, createUnboundLabel());
|
||||||
// subroutineInfo.push(blockInfo);
|
// subroutineInfo.push(blockInfo);
|
||||||
@@ -179,7 +178,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exitSubroutine(@NotNull JetElement subroutine, boolean functionLiteral) {
|
public void exitSubroutine(@NotNull JetDeclaration subroutine) {
|
||||||
bindLabel(getExitPoint(subroutine));
|
bindLabel(getExitPoint(subroutine));
|
||||||
pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>"));
|
pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>"));
|
||||||
bindLabel(error);
|
bindLabel(error);
|
||||||
@@ -246,6 +245,13 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
add(new NondeterministicJumpInstruction(label));
|
add(new NondeterministicJumpInstruction(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nondeterministicJump(List<Label> labels) {
|
||||||
|
//todo
|
||||||
|
//handleJumpInsideTryFinally(label);
|
||||||
|
add(new NondeterministicJumpInstruction(labels));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void jumpToError(JetThrowExpression expression) {
|
public void jumpToError(JetThrowExpression expression) {
|
||||||
add(new UnconditionalJumpInstruction(error));
|
add(new UnconditionalJumpInstruction(error));
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFunction;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class LocalDeclarationInstruction extends ReadValueInstruction {
|
||||||
|
|
||||||
|
private Pseudocode body;
|
||||||
|
|
||||||
|
public LocalDeclarationInstruction(@NotNull JetDeclaration element, Pseudocode body) {
|
||||||
|
super(element);
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pseudocode getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(InstructionVisitor visitor) {
|
||||||
|
visitor.visitFunctionLiteralValue(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String kind = "!";
|
||||||
|
if (element instanceof JetFunction) {
|
||||||
|
kind = "f";
|
||||||
|
}
|
||||||
|
else if (element instanceof JetClass) {
|
||||||
|
kind = "c";
|
||||||
|
}
|
||||||
|
else if (element instanceof JetObjectDeclaration) {
|
||||||
|
kind = "o";
|
||||||
|
}
|
||||||
|
return "r" + kind + "(" + element.getText() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,10 +11,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.JetTestCaseBase;
|
import org.jetbrains.jet.JetTestCaseBase;
|
||||||
import org.jetbrains.jet.lang.cfg.LoopInfo;
|
import org.jetbrains.jet.lang.cfg.LoopInfo;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
|
|
||||||
import org.jetbrains.jet.plugin.AnalyzerFacade;
|
import org.jetbrains.jet.plugin.AnalyzerFacade;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -91,12 +88,13 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
for (Pseudocode pseudocode : pseudocodes) {
|
for (Pseudocode pseudocode : pseudocodes) {
|
||||||
JetElement correspondingElement = pseudocode.getCorrespondingElement();
|
JetElement correspondingElement = pseudocode.getCorrespondingElement();
|
||||||
String label;
|
String label;
|
||||||
if (correspondingElement instanceof JetNamedDeclaration) {
|
assert correspondingElement instanceof JetNamedDeclaration;
|
||||||
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) correspondingElement;
|
if (correspondingElement instanceof JetFunctionLiteral) {
|
||||||
label = namedDeclaration.getName();
|
label = "anonymous_" + i++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
label = "anonymous_" + i++;
|
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) correspondingElement;
|
||||||
|
label = namedDeclaration.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
instructionDump.append("== ").append(label).append(" ==\n");
|
instructionDump.append("== ").append(label).append(" ==\n");
|
||||||
@@ -222,9 +220,9 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
}
|
}
|
||||||
for (int i = 0, instructionsSize = instructions.size(); i < instructionsSize; i++) {
|
for (int i = 0, instructionsSize = instructions.size(); i < instructionsSize; i++) {
|
||||||
Instruction instruction = instructions.get(i);
|
Instruction instruction = instructions.get(i);
|
||||||
if (instruction instanceof FunctionLiteralValueInstruction) {
|
if (instruction instanceof LocalDeclarationInstruction) {
|
||||||
FunctionLiteralValueInstruction functionLiteralValueInstruction = (FunctionLiteralValueInstruction) instruction;
|
LocalDeclarationInstruction localDeclarationInstruction = (LocalDeclarationInstruction) instruction;
|
||||||
locals.add(functionLiteralValueInstruction.getBody());
|
locals.add(localDeclarationInstruction.getBody());
|
||||||
}
|
}
|
||||||
for (Pseudocode.PseudocodeLabel label: labels) {
|
for (Pseudocode.PseudocodeLabel label: labels) {
|
||||||
if (label.getTargetInstructionIndex() == i) {
|
if (label.getTargetInstructionIndex() == i) {
|
||||||
@@ -245,7 +243,7 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
for (final Instruction fromInst : instructions) {
|
for (final Instruction fromInst : instructions) {
|
||||||
fromInst.accept(new InstructionVisitor() {
|
fromInst.accept(new InstructionVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void visitFunctionLiteralValue(FunctionLiteralValueInstruction instruction) {
|
public void visitFunctionLiteralValue(LocalDeclarationInstruction instruction) {
|
||||||
int index = count[0];
|
int index = count[0];
|
||||||
// instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName);
|
// instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName);
|
||||||
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getBody().getInstructions().get(0)), null);
|
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getBody().getInstructions().get(0)), null);
|
||||||
@@ -264,7 +262,8 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
public void visitNondeterministicJump(NondeterministicJumpInstruction instruction) {
|
||||||
visitJump(instruction);
|
//todo print edges
|
||||||
|
visitInstruction(instruction);
|
||||||
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getNext()), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +324,7 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
else if (node instanceof UnsupportedElementInstruction) {
|
else if (node instanceof UnsupportedElementInstruction) {
|
||||||
shape = "box, fillcolor=red, style=filled";
|
shape = "box, fillcolor=red, style=filled";
|
||||||
}
|
}
|
||||||
else if (node instanceof FunctionLiteralValueInstruction) {
|
else if (node instanceof LocalDeclarationInstruction) {
|
||||||
shape = "Mcircle";
|
shape = "Mcircle";
|
||||||
}
|
}
|
||||||
else if (node instanceof SubroutineEnterInstruction || node instanceof SubroutineExitInstruction) {
|
else if (node instanceof SubroutineEnterInstruction || node instanceof SubroutineExitInstruction) {
|
||||||
|
|||||||
Reference in New Issue
Block a user