Commit 014a9c1a authored by Alexander Weigl's avatar Alexander Weigl
Browse files

it starts running, again!

* fixes of NPE
* connect UI to DebuggerFramework
* add frames combobox and context analysis
  * including bugs

Now, testing the big things!
parent 4f5faf1f
package edu.kit.iti.formal.psdbg;
import edu.kit.iti.formal.psdbg.parser.DefaultASTVisitor;
import edu.kit.iti.formal.psdbg.parser.Facade;
import edu.kit.iti.formal.psdbg.parser.ast.*;
/**
* Prints every command to a single line representation.
*
* @author Alexander Weigl
* @version 1
*/
public class ShortCommandPrinter extends DefaultASTVisitor<String> {
@Override
public String defaultVisit(ASTNode node) {
return (Facade.prettyPrint(node));
}
@Override
public String visit(ProofScript proofScript) {
return String.format("script %s (%s) {%n",
proofScript.getName(),
Facade.prettyPrint(proofScript.getSignature()));
}
@Override
public String visit(CasesStatement casesStatement) {
return "cases {";
}
@Override
public String visit(SimpleCaseStatement caseStatement) {
return "case " + Facade.prettyPrint(caseStatement.getGuard());
}
@Override
public String visit(TryCase tryCase) {
return "try " + Facade.prettyPrint(tryCase.getBody());
}
@Override
public String visit(ClosesCase closesCase) {
return "closes with {" + Facade.prettyPrint(closesCase.getClosesScript()) + "}";
}
@Override
public String visit(TheOnlyStatement theOnly) {
return "theonly {";
}
@Override
public String visit(ForeachStatement foreach) {
return "foreach {";
}
@Override
public String visit(RepeatStatement repeatStatement) {
return ("repeat {");
}
}
...@@ -41,12 +41,15 @@ import java.util.Map; ...@@ -41,12 +41,15 @@ import java.util.Map;
public class PrettyPrinter extends DefaultASTVisitor<Void> { public class PrettyPrinter extends DefaultASTVisitor<Void> {
private final StringBuilder s = new StringBuilder(); private final StringBuilder s = new StringBuilder();
@Getter @Getter
@Setter @Setter
private int maxWidth = 80; private int maxWidth = 80;
@Getter @Getter
@Setter @Setter
private boolean unicode = true; private boolean unicode = true;
private int indentation = 0; private int indentation = 0;
@Override @Override
...@@ -187,8 +190,11 @@ public class PrettyPrinter extends DefaultASTVisitor<Void> { ...@@ -187,8 +190,11 @@ public class PrettyPrinter extends DefaultASTVisitor<Void> {
@Override @Override
public Void visit(CallStatement call) { public Void visit(CallStatement call) {
s.append(call.getCommand()).append(' '); s.append(call.getCommand());
call.getParameters().accept(this); if (call.getParameters().size() != 0) {
s.append(' ');
call.getParameters().accept(this);
}
s.append(";"); s.append(";");
return null; return null;
} }
......
...@@ -9,7 +9,6 @@ import edu.kit.iti.formal.psdbg.interpreter.KeyInterpreter; ...@@ -9,7 +9,6 @@ import edu.kit.iti.formal.psdbg.interpreter.KeyInterpreter;
import edu.kit.iti.formal.psdbg.interpreter.data.GoalNode; import edu.kit.iti.formal.psdbg.interpreter.data.GoalNode;
import edu.kit.iti.formal.psdbg.interpreter.data.KeyData; import edu.kit.iti.formal.psdbg.interpreter.data.KeyData;
import edu.kit.iti.formal.psdbg.interpreter.dbg.*; import edu.kit.iti.formal.psdbg.interpreter.dbg.*;
import edu.kit.iti.formal.psdbg.parser.DefaultASTVisitor;
import edu.kit.iti.formal.psdbg.parser.Facade; import edu.kit.iti.formal.psdbg.parser.Facade;
import edu.kit.iti.formal.psdbg.parser.ast.*; import edu.kit.iti.formal.psdbg.parser.ast.*;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
...@@ -82,7 +81,7 @@ public class InteractiveCLIDebugger { ...@@ -82,7 +81,7 @@ public class InteractiveCLIDebugger {
System.out.println("digraph G {"); System.out.println("digraph G {");
for (PTreeNode<KeyData> n : df.getStates()) { for (PTreeNode<KeyData> n : df.getStates()) {
System.out.format("%d [label=\"%s@%s (G: %d)\"]%n", n.hashCode(), System.out.format("%d [label=\"%s@%s (G: %d)\"]%n", n.hashCode(),
n.getStatement().accept(new CommandPrinter()), n.getStatement().accept(new ShortCommandPrinter()),
n.getStatement().getStartPosition().getLineNumber(), n.getStatement().getStartPosition().getLineNumber(),
n.getStateBeforeStmt().getGoals().size() n.getStateBeforeStmt().getGoals().size()
); );
...@@ -154,7 +153,7 @@ public class InteractiveCLIDebugger { ...@@ -154,7 +153,7 @@ public class InteractiveCLIDebugger {
private void printNode(PTreeNode<KeyData> node) { private void printNode(PTreeNode<KeyData> node) {
System.out.format("%3d: %s%n", System.out.format("%3d: %s%n",
node.getStatement().getStartPosition().getLineNumber(), node.getStatement().getStartPosition().getLineNumber(),
node.getStatement().accept(new CommandPrinter()) node.getStatement().accept(new ShortCommandPrinter())
); );
for (GoalNode<KeyData> gn : node.getStateBeforeStmt().getGoals()) { for (GoalNode<KeyData> gn : node.getStateBeforeStmt().getGoals()) {
...@@ -171,52 +170,3 @@ public class InteractiveCLIDebugger { ...@@ -171,52 +170,3 @@ public class InteractiveCLIDebugger {
//df.addBreakpoint(breakpoint); //df.addBreakpoint(breakpoint);
} }
} }
class CommandPrinter extends DefaultASTVisitor<String> {
@Override
public String defaultVisit(ASTNode node) {
return (Facade.prettyPrint(node));
}
@Override
public String visit(ProofScript proofScript) {
return String.format("script %s (%s) {%n",
proofScript.getName(),
Facade.prettyPrint(proofScript.getSignature()));
}
@Override
public String visit(CasesStatement casesStatement) {
return "cases {";
}
@Override
public String visit(SimpleCaseStatement caseStatement) {
return "case " + Facade.prettyPrint(caseStatement.getGuard());
}
@Override
public String visit(TryCase tryCase) {
return "try " + Facade.prettyPrint(tryCase.getBody());
}
@Override
public String visit(ClosesCase closesCase) {
return "closes with {" + Facade.prettyPrint(closesCase.getClosesScript()) + "}";
}
@Override
public String visit(TheOnlyStatement theOnly) {
return "theonly {";
}
@Override
public String visit(ForeachStatement foreach) {
return "foreach {";
}
@Override
public String visit(RepeatStatement repeatStatement) {
return ("repeat {");
}
}
...@@ -50,9 +50,36 @@ public class KeYProofFacade { ...@@ -50,9 +50,36 @@ public class KeYProofFacade {
* BooleanProperty inidcating whether KeY finished loading * BooleanProperty inidcating whether KeY finished loading
*/ */
private BooleanBinding readyToExecute = proof.isNotNull(); private BooleanBinding readyToExecute = proof.isNotNull();
//Workaround until api is relaxed //Workaround until api is relaxed
private ProofManagementApi pma; private ProofManagementApi pma;
/**
*
*/
public ProofState getProofState() {
Proof p = proof.get();
if (p == null)
return ProofState.EMPTY;
if (p.root().childrenCount() == 0)
return ProofState.VIRGIN;
return ProofState.DIRTY;
}
/**
* reload the current proof. synchronously because only the first load is slow.
*/
public void reload() throws ProofInputException, ProblemLoaderException {
if (contract.get() != null) {// reinstante the contract
setProof(getEnvironment().createProof(
contract.get().getProofObl(getEnvironment().getServices())));
} else {
setProof(KeYApi.loadFromKeyFile(proof.get().getProofFile()).getLoadedProof().getProof());
}
}
//region loading //region loading
public Task<ProofApi> loadKeyFileTask(File keYFile) { public Task<ProofApi> loadKeyFileTask(File keYFile) {
Task<ProofApi> task = new Task<ProofApi>() { Task<ProofApi> task = new Task<ProofApi>() {
...@@ -117,14 +144,13 @@ public class KeYProofFacade { ...@@ -117,14 +144,13 @@ public class KeYProofFacade {
proof.set(pa.getProof()); proof.set(pa.getProof());
contract.set(null); contract.set(null);
} }
//endregion
/** /**
* Build the KeYInterpreter that handles the execution of the loaded key problem sourceName * Build the KeYInterpreter that handles the execution of the loaded key problem sourceName
*/ */
public InterpreterBuilder buildInterpreter() { public InterpreterBuilder buildInterpreter() {
assert readyToExecute.getValue(); assert readyToExecute.getValue();
assert getEnvironment() != null && getProof() != null : "No proof loaded";
InterpreterBuilder interpreterBuilder = new InterpreterBuilder(); InterpreterBuilder interpreterBuilder = new InterpreterBuilder();
interpreterBuilder interpreterBuilder
.proof(environment.get(), proof.get()) .proof(environment.get(), proof.get())
...@@ -136,7 +162,7 @@ public class KeYProofFacade { ...@@ -136,7 +162,7 @@ public class KeYProofFacade {
return interpreterBuilder; return interpreterBuilder;
} }
//endregion
/** /**
* Reload all KeY structure if proof should be reloaded * Reload all KeY structure if proof should be reloaded
...@@ -202,6 +228,10 @@ public class KeYProofFacade { ...@@ -202,6 +228,10 @@ public class KeYProofFacade {
KeyData data = new KeyData(proof.get().root(), getEnvironment(), getProof()); KeyData data = new KeyData(proof.get().root(), getEnvironment(), getProof());
return Collections.singleton(new GoalNode<>(null, data, data.getNode().isClosed())); return Collections.singleton(new GoalNode<>(null, data, data.getNode().isClosed()));
} }
public enum ProofState {
EMPTY, VIRGIN, DIRTY;
}
//endregion //endregion
} }
...@@ -9,8 +9,8 @@ import lombok.Getter; ...@@ -9,8 +9,8 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.val; import lombok.val;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate; import java.util.function.Predicate;
...@@ -25,7 +25,7 @@ public abstract class Blocker { ...@@ -25,7 +25,7 @@ public abstract class Blocker {
private final Interpreter<T> interpreter; private final Interpreter<T> interpreter;
@Getter @Getter
private final Set<Breakpoint> breakpoints = new TreeSet<>(); private final Set<Breakpoint> breakpoints = new HashSet<>();
private final Breakpoint cmp = new Breakpoint(null, 0); private final Breakpoint cmp = new Breakpoint(null, 0);
...@@ -52,7 +52,7 @@ public abstract class Blocker { ...@@ -52,7 +52,7 @@ public abstract class Blocker {
} }
} }
} }
return breakpoints.contains(cmp); return false;
} }
} }
...@@ -66,8 +66,9 @@ public abstract class Blocker { ...@@ -66,8 +66,9 @@ public abstract class Blocker {
@Override @Override
public boolean test(ASTNode astNode) { public boolean test(ASTNode astNode) {
if (stepUntilBlock.get() >= 0) { int value;
return 0 == stepUntilBlock.decrementAndGet(); if ((value = stepUntilBlock.decrementAndGet()) >= 0) {
return 0 == value;
} }
return false; return false;
} }
......
...@@ -3,9 +3,11 @@ package edu.kit.iti.formal.psdbg.interpreter.dbg; ...@@ -3,9 +3,11 @@ package edu.kit.iti.formal.psdbg.interpreter.dbg;
import edu.kit.iti.formal.psdbg.parser.Facade; import edu.kit.iti.formal.psdbg.parser.Facade;
import edu.kit.iti.formal.psdbg.parser.ast.Expression; import edu.kit.iti.formal.psdbg.parser.ast.Expression;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CharStreams;
@Data @Data
@EqualsAndHashCode(of = {"sourceName", "lineNumber"})
public class Breakpoint { public class Breakpoint {
private String sourceName; private String sourceName;
......
package edu.kit.iti.formal.psdbg.interpreter.dbg; package edu.kit.iti.formal.psdbg.interpreter.dbg;
import edu.kit.iti.formal.psdbg.ShortCommandPrinter;
import edu.kit.iti.formal.psdbg.interpreter.data.GoalNode; import edu.kit.iti.formal.psdbg.interpreter.data.GoalNode;
import edu.kit.iti.formal.psdbg.interpreter.data.State; import edu.kit.iti.formal.psdbg.interpreter.data.State;
import edu.kit.iti.formal.psdbg.parser.ast.ASTNode; import edu.kit.iti.formal.psdbg.parser.ast.ASTNode;
import edu.kit.iti.formal.psdbg.parser.ast.CaseStatement; import edu.kit.iti.formal.psdbg.parser.ast.CaseStatement;
import edu.kit.iti.formal.psdbg.parser.ast.Parameters; import lombok.Getter;
import lombok.*; import lombok.RequiredArgsConstructor;
import lombok.Setter;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Collections; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* PTreeNode represents a node in the state graph. * PTreeNode represents a node in the state graph.
...@@ -23,29 +22,34 @@ import java.util.Map; ...@@ -23,29 +22,34 @@ import java.util.Map;
*/ */
@Getter @Getter
@Setter @Setter
@ToString
@RequiredArgsConstructor @RequiredArgsConstructor
public class PTreeNode<T> { public class PTreeNode<T> {
private final ASTNode statement; private final ASTNode statement;
private Map<CaseStatement, List<GoalNode<T>>> mappingOfCaseToStates = new HashMap<>(); private Map<CaseStatement, List<GoalNode<T>>> mappingOfCaseToStates = new HashMap<>();
private State<T> stateBeforeStmt; private State<T> stateBeforeStmt;
private State<T> stateAfterStmt; private State<T> stateAfterStmt;
private ASTNode[] context; private ASTNode[] context;
private boolean atomic; private boolean atomic;
@Nullable @Nullable
private PTreeNode<T> stepInto; private PTreeNode<T> stepInto;
@Nullable @Nullable
private PTreeNode<T> stepOver; private PTreeNode<T> stepOver;
@Nullable @Nullable
private PTreeNode<T> stepInvOver; private PTreeNode<T> stepInvOver;
@Nullable @Nullable
private PTreeNode<T> stepInvInto; private PTreeNode<T> stepInvInto;
@Nullable @Nullable
private PTreeNode<T> stepReturn; private PTreeNode<T> stepReturn;
private Parameters goals;
public void connectStepOver(PTreeNode<T> jumpOverTo) { public void connectStepOver(PTreeNode<T> jumpOverTo) {
setStepOver(jumpOverTo); setStepOver(jumpOverTo);
...@@ -60,4 +64,36 @@ public class PTreeNode<T> { ...@@ -60,4 +64,36 @@ public class PTreeNode<T> {
public List<GoalNode<T>> getActiveGoalsForCase(CaseStatement caseStmt) { public List<GoalNode<T>> getActiveGoalsForCase(CaseStatement caseStmt) {
return mappingOfCaseToStates.getOrDefault(caseStmt, Collections.emptyList()); return mappingOfCaseToStates.getOrDefault(caseStmt, Collections.emptyList());
} }
public List<PTreeNode<T>> getContextNodes() {
List<PTreeNode<T>> contextNodes = new ArrayList<>(context.length);
PTreeNode<T> cur = this;
outer : do {
// add the current node, and every node that can be reached by an inverse into pointer.
contextNodes.add(cur);
// if the current node doesn't have an inverse into pointer, then trace
// inverse over pointer (same context)
while (cur.getStepInvInto() == null) {
cur = cur.getStepInvOver();
if (cur == null) break outer; // we could reach the beginning of execution
}
cur = cur.getStepInvInto();
} while (cur != null);
return contextNodes;
}
public String getSingleRepresentation() {
if (getStatement().getStartPosition() != null)
return String.format("%d: %s",
getStatement().getStartPosition().getLineNumber(),
getStatement().accept(new ShortCommandPrinter()));
else
return (String) getStatement().accept(new ShortCommandPrinter());
}
@Override
public String toString() {
return getSingleRepresentation();
}
} }
\ No newline at end of file
...@@ -159,4 +159,5 @@ public class ProofTreeManager<T> { ...@@ -159,4 +159,5 @@ public class ProofTreeManager<T> {
if (!suppressStatePointerListener) if (!suppressStatePointerListener)
statePointerListener.forEach(l -> l.accept(statePointer)); statePointerListener.forEach(l -> l.accept(statePointer));
} }
} }
...@@ -4,11 +4,14 @@ import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon; ...@@ -4,11 +4,14 @@ import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView; import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
import de.uka.ilkd.key.api.ProofApi; import de.uka.ilkd.key.api.ProofApi;
import de.uka.ilkd.key.proof.init.ProofInputException; import de.uka.ilkd.key.proof.init.ProofInputException;
import de.uka.ilkd.key.proof.io.ProblemLoaderException;
import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.speclang.Contract;
import edu.kit.iti.formal.psdbg.StepIntoCommand;
import edu.kit.iti.formal.psdbg.examples.Examples; import edu.kit.iti.formal.psdbg.examples.Examples;
import edu.kit.iti.formal.psdbg.gui.ProofScriptDebugger; import edu.kit.iti.formal.psdbg.gui.ProofScriptDebugger;
import edu.kit.iti.formal.psdbg.gui.controls.*; import edu.kit.iti.formal.psdbg.gui.controls.*;
import edu.kit.iti.formal.psdbg.gui.model.DebuggerMainModel; import edu.kit.iti.formal.psdbg.gui.model.DebuggerMainModel;
import edu.kit.iti.formal.psdbg.gui.model.InspectionModel;
import edu.kit.iti.formal.psdbg.interpreter.InterpreterBuilder; import edu.kit.iti.formal.psdbg.interpreter.InterpreterBuilder;
import edu.kit.iti.formal.psdbg.interpreter.KeYProofFacade; import edu.kit.iti.formal.psdbg.interpreter.KeYProofFacade;
import edu.kit.iti.formal.psdbg.interpreter.KeyInterpreter; import edu.kit.iti.formal.psdbg.interpreter.KeyInterpreter;
...@@ -105,19 +108,28 @@ public class DebuggerMain implements Initializable { ...@@ -105,19 +108,28 @@ public class DebuggerMain implements Initializable {
//register the welcome dock in the center //register the welcome dock in the center
welcomePaneDock.dock(dockStation, DockPos.LEFT); welcomePaneDock.dock(dockStation, DockPos.LEFT);
registerToolbarToStatusBar();
//statusBar.publishMessage("File: " + (newValue != null ? newValue.getAbsolutePath() : "n/a")); //statusBar.publishMessage("File: " + (newValue != null ? newValue.getAbsolutePath() : "n/a"));
marriageJavaCode(); marriageJavaCode();
//marriage key proof facade to proof tree //marriage key proof facade to proof tree
getFacade().proofProperty().addListener( getFacade().proofProperty().addListener(
(prop, o, n) -> { (prop, o, n) -> {
proofTree.setRoot(n.root()); if (n == null) {
proofTree.setRoot(null);
} else {
proofTree.setRoot(n.root());
getInspectionViewsController().getActiveInspectionViewTab()
.getModel().getGoals().setAll(FACADE.getPseudoGoals());
}
proofTree.setProof(n); proofTree.setProof(n);
getInspectionViewsController().getActiveInspectionViewTab().getModel().getGoals().setAll(FACADE.getPseudoGoals());
} }
); );
//
model.statePointerProperty().addListener((prop, o, n) -> {
this.handleStatePointerUI(n);
});
//Debugging //Debugging
Utils.addDebugListener(model.javaCodeProperty()); Utils.addDebugListener