Added local declaration instruction to pseudocode

This commit is contained in:
svtk
2011-10-21 15:39:52 +04:00
parent e5bd34c7b0
commit ee561708dd
5 changed files with 80 additions and 65 deletions
@@ -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) {
@@ -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));
@@ -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) {