Commit 4f5faf1f authored by Alexander Weigl's avatar Alexander Weigl

Fixing UI, tommorrow NPE hunting

parent c7ec5de9
Pipeline #15031 failed with stage
in 1 minute and 57 seconds
......@@ -24,7 +24,9 @@ package edu.kit.iti.formal.psdbg.parser;
import edu.kit.iti.formal.psdbg.parser.ast.ASTNode;
import edu.kit.iti.formal.psdbg.parser.ast.Expression;
import edu.kit.iti.formal.psdbg.parser.ast.ProofScript;
import lombok.val;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
......@@ -33,7 +35,6 @@ import org.antlr.v4.runtime.ParserRuleContext;
import java.io.File;
import java.io.IOException;
import java.util.List;
import edu.kit.iti.formal.psdbg.parser.ast.*;
/**
* This class captures high-level functions of this package.
......@@ -104,4 +105,9 @@ public abstract class Facade {
node.accept(prettyPrinter);
return prettyPrinter.toString();
}
public static Expression parseExpression(String condition) {
val ctx = getParser(CharStreams.fromString(condition)).expression();
return (Expression) ctx.accept(new TransformAst());
}
}
package edu.kit.iti.formal.psdbg;
import com.google.common.graph.MutableValueGraph;
import de.uka.ilkd.key.api.KeYApi;
import de.uka.ilkd.key.api.ProofManagementApi;
import de.uka.ilkd.key.proof.io.ProblemLoaderException;
......@@ -10,9 +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.KeyData;
import edu.kit.iti.formal.psdbg.interpreter.dbg.*;
import edu.kit.iti.formal.psdbg.interpreter.graphs.ControlFlowNode;
import edu.kit.iti.formal.psdbg.interpreter.graphs.ControlFlowTypes;
import edu.kit.iti.formal.psdbg.interpreter.graphs.ControlFlowVisitor;
import edu.kit.iti.formal.psdbg.parser.DefaultASTVisitor;
import edu.kit.iti.formal.psdbg.parser.Facade;
import edu.kit.iti.formal.psdbg.parser.ast.*;
......@@ -62,10 +58,10 @@ public class InteractiveCLIDebugger {
.scriptSearchPath(new File("."));
interpreter = ib.build();
ControlFlowVisitor cfgVistor = new ControlFlowVisitor(ib.getLookup());
MutableValueGraph<ControlFlowNode, ControlFlowTypes> cfg = cfgVistor.getGraph();
//ControlFlowVisitor cfgVistor = new ControlFlowVisitor(ib.getLookup());
//MutableValueGraph<ControlFlowNode, ControlFlowTypes> cfg = cfgVistor.getGraph();
df = new DebuggerFramework<>(interpreter, scripts.get(0), cfg);
df = new DebuggerFramework<>(interpreter, scripts.get(0), null);
df.getStatePointerListener().add(this::printNode);
//df.getBeforeExecutionListener().add(this::printNode);
//df.getAfterExecutionListener().add(this::end);
......
package edu.kit.iti.formal.psdbg.interpreter.dbg;
import edu.kit.iti.formal.psdbg.interpreter.Evaluator;
import edu.kit.iti.formal.psdbg.interpreter.Interpreter;
import edu.kit.iti.formal.psdbg.interpreter.exceptions.InterpreterRuntimeException;
import edu.kit.iti.formal.psdbg.parser.ast.ASTNode;
import lombok.Data;
import edu.kit.iti.formal.psdbg.parser.types.SimpleType;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.val;
import java.util.Set;
import java.util.TreeSet;
......@@ -15,24 +18,41 @@ public abstract class Blocker {
public interface BlockPredicate extends Predicate<ASTNode> {
}
@Data
public static class Breakpoint {
private int line;
private String source;
}
public static class BreakpointLine implements BlockPredicate {
@RequiredArgsConstructor
public static class BreakpointLine<T> implements BlockPredicate {
@Getter
private final Interpreter<T> interpreter;
@Getter
@Setter
private final Set<Integer> lines = new TreeSet<>();
private final Set<Breakpoint> breakpoints = new TreeSet<>();
private final Breakpoint cmp = new Breakpoint();
private final Breakpoint cmp = new Breakpoint(null, 0);
@Override
public boolean test(ASTNode node) {
cmp.line = node.getStartPosition().getLineNumber();
cmp.source = node.getOrigin();
return lines.contains(cmp);
Evaluator<T> evaluator = new Evaluator<>(interpreter.getSelectedNode().getAssignments(), interpreter.getSelectedNode());
for (Breakpoint brkpt : getBreakpoints()) {
// check file name
if (brkpt.getSourceName().equals(node.getOrigin())) {
// check line
if (brkpt.getLineNumber() == node.getStartPosition().getLineNumber()) {
// if there is no condition
if (brkpt.getConditionAst() == null) {
return true; // no condition ==> trigger
} else { // if there is a condition, we check:
val v = evaluator.eval(brkpt.getConditionAst());
if (v.getType() != SimpleType.BOOL)
throw new InterpreterRuntimeException(
String.format("Condition %s of breakpoint %s returned type %s",
brkpt.getCondition(), brkpt, v.getType()));
if (v.getData() == Boolean.TRUE)
return true;
}
}
}
}
return breakpoints.contains(cmp);
}
}
......@@ -46,10 +66,10 @@ public abstract class Blocker {
@Override
public boolean test(ASTNode astNode) {
if (stepUntilBlock.get() > 0) {
stepUntilBlock.decrementAndGet();
if (stepUntilBlock.get() >= 0) {
return 0 == stepUntilBlock.decrementAndGet();
}
return stepUntilBlock.get() == 0;
return false;
}
public void deactivate() {
......
package edu.kit.iti.formal.psdbg.gui.model;
package edu.kit.iti.formal.psdbg.interpreter.dbg;
import edu.kit.iti.formal.psdbg.parser.Facade;
import edu.kit.iti.formal.psdbg.parser.ast.Expression;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.antlr.v4.runtime.CharStreams;
import java.io.File;
/**
* @author Alexander Weigl
* @version 1 (21.06.17)
*/
@Data
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode
public class Breakpoint {
private File file;
private String sourceName;
private int lineNumber;
private boolean enabled;
private String condition;
public Breakpoint(File file, int lineNumber) {
this.file = file;
private Expression conditionAst;
public Breakpoint(String file, int lineNumber) {
sourceName = file;
this.lineNumber = lineNumber;
}
public boolean isConditional() {
return condition != null;
}
}
public void setCondition(String condition) {
this.condition = condition;
this.conditionAst = Facade.parseExpression(condition);
}
}
\ No newline at end of file
......@@ -42,16 +42,23 @@ public class DebuggerFramework<T> {
private final List<Consumer<PTreeNode<T>>> currentStatePointerListener = new LinkedList<>();
private final ProofTreeManager<T> ptreeManager;
private final Thread interpreterThread;
private final BlockListener<T> blocker;
private final StateWrapper<T> stateWrapper;
private Blocker.BreakpointLine<T> breakpointBlocker;
public DebuggerFramework(@Nonnull Interpreter<T> interpreter,
@Nonnull ProofScript main,
MutableValueGraph<ControlFlowNode, ControlFlowTypes> cfg) {
this.interpreter = interpreter;
blocker = new BlockListener<>(interpreter);
breakpointBlocker = new Blocker.BreakpointLine<>(interpreter);
blocker.getPredicates().add(breakpointBlocker);
stateWrapper = new StateWrapper<>(interpreter);
ptreeManager = new ProofTreeManager<>(cfg);
stateWrapper.setEmitNode(ptreeManager::receiveNode);
......@@ -116,7 +123,35 @@ public class DebuggerFramework<T> {
blocker.unlock();
}
/**
* Let the interpreter run, without adding any further blockers.
*/
public void release() {
blocker.unlock();
}
/**
* Let the interpreter run, without adding any further blockers.
*/
public void releaseForever() {
blocker.getPredicates().clear();
release();
}
public Set<PTreeNode<T>> getStates() {
return ptreeManager.getNodes();
}
/**
* Unregister all state pointer listeners.
*/
public void unregister() {
ptreeManager.getStatePointerListener().clear();
}
public Set<Breakpoint> getBreakpoints() {
return breakpointBlocker.getBreakpoints();
}
}
package edu.kit.iti.formal.psdbg.interpreter.graphs;
import edu.kit.iti.formal.psdbg.interpreter.data.InterpreterExtendedState;
import edu.kit.iti.formal.psdbg.interpreter.data.State;
import edu.kit.iti.formal.psdbg.parser.ast.ASTNode;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.util.Stack;
/**
* Inner class representing nodes in the stategraph graph
* A node contains a reference to the ASTNode and a reference to the corresponding interpreter state if this state is already interpreted, null otherwise.
*/
@Data
public class PTreeNode<T> {
/**
* State after statement
*/
//private State<T> state;
private InterpreterExtendedState<T> extendedState = new InterpreterExtendedState<>(null);
/**
* Statement
*/
private ASTNode scriptStmt;
/**
* Call context
*/
@Getter
@Setter
private Stack<ASTNode> context = new Stack<>();
private boolean root;
PTreeNode(ASTNode node) {
this.setScriptStmt(node);
}
public void setExtendedState(InterpreterExtendedState<T> extendedState) {
this.extendedState = extendedState;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Node {");
if (scriptStmt != null) {
sb.append(scriptStmt.getNodeName() + "\n");
} else {
sb.append("Root Node");
}
/* if (hasState()) {
sb.append("\nState " + state.getGoals() + "\n");
} else {
sb.append("No State yet");
}*/
if (extendedState != null) {
sb.append(extendedStateToString());
} else {
sb.append("No extended State yet");
}
sb.append("}");
return sb.toString();
}
public String extendedStateToString() {
return this.extendedState.toString();
}
}
package edu.kit.iti.formal.psdbg.interpreter;
import edu.kit.iti.formal.psdbg.interpreter.funchdl.DefaultLookup;
import edu.kit.iti.formal.psdbg.interpreter.graphs.ControlFlowVisitor;
import edu.kit.iti.formal.psdbg.parser.Facade;
import edu.kit.iti.formal.psdbg.parser.ScriptLanguageParser;
import edu.kit.iti.formal.psdbg.parser.TransformAst;
......@@ -22,9 +20,9 @@ public class ControlFlowVisitorTest {
getClass().getResourceAsStream("/edu/kit/iti/formal/psdbg/interpreter/simple1.txt")));
List<ProofScript> scripts = (List<ProofScript>) a.start().accept(new TransformAst());
ProofScript s = scripts.get(0);
ControlFlowVisitor pfv = new ControlFlowVisitor(new DefaultLookup());
s.accept(pfv);
System.out.println(pfv.asdot());
//ControlFlowVisitor pfv = new ControlFlowVisitor(new DefaultLookup());
//s.accept(pfv);
//System.out.println(pfv.asdot());
}
}
\ No newline at end of file
......@@ -83,7 +83,7 @@ public class InterpretingService extends Service<State<KeyData>> {
if (statusBar != null) {
statusBar.stopProgress();
}
blocker.publishState();
//blocker.publishState();
}
@Override
......
......@@ -18,6 +18,7 @@ import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.layout.BorderPane;
import javafx.util.StringConverter;
import lombok.AllArgsConstructor;
import lombok.val;
/**
......@@ -25,11 +26,14 @@ import lombok.val;
*/
public class ProofTree extends BorderPane {
private ObjectProperty<Proof> proof = new SimpleObjectProperty<>();
private ObjectProperty<Node> root = new SimpleObjectProperty<>();
private MapProperty colorOfNodes = new SimpleMapProperty<>(FXCollections.observableHashMap());
@FXML
private TreeView<Node> treeProof;
private TreeView<NodeOrString> treeProof;
private ProofTreeListener proofTreeListener = new ProofTreeListener() {
@Override
public void proofExpanded(ProofTreeEvent proofTreeEvent) {
......@@ -115,31 +119,35 @@ public class ProofTree extends BorderPane {
treeProof.refresh();
}
private TreeCell<Node> cellFactory(TreeView<Node> nodeTreeView) {
TextFieldTreeCell<Node> tftc = new TextFieldTreeCell<>();
tftc.setConverter(new StringConverter<Node>() {
private TreeCell<NodeOrString> cellFactory(TreeView<NodeOrString> nodeTreeView) {
TextFieldTreeCell<NodeOrString> tftc = new TextFieldTreeCell<>();
StringConverter<NodeOrString> stringConverter = new StringConverter<NodeOrString>() {
@Override
public String toString(Node object) {
/* if (object.getAppliedRuleApp() != null) {
return object.getAppliedRuleApp().rule().displayName();
} else {
return object.name();
}*/
String nodeLabel;
if (object.getAppliedRuleApp() != null) {
nodeLabel = object.getAppliedRuleApp().rule().displayName();
} else {
nodeLabel = object.isClosed() ? "Closed Goal" : "Open Goal";
public String toString(NodeOrString object) {
if (object instanceof TString) {
TString tString = (TString) object;
return tString.label;
}
if (object instanceof TNode) {
TNode tNode = (TNode) object;
String nodeLabel;
if (tNode.node.getAppliedRuleApp() != null) {
nodeLabel = tNode.node.getAppliedRuleApp().rule().displayName();
} else {
nodeLabel = tNode.node.isClosed() ? "Closed Goal" : "Open Goal";
}
return nodeLabel;
}
return nodeLabel;
// return object.sequent().toString();
return "";
}
@Override
public Node fromString(String string) {
public NodeOrString fromString(String string) {
return null;
}
});
};
tftc.setConverter(stringConverter);
tftc.itemProperty().addListener((p, o, n) -> repaint(tftc));
colorOfNodes.addListener((InvalidationListener) o -> repaint(tftc));
return tftc;
......@@ -149,8 +157,8 @@ public class ProofTree extends BorderPane {
* @param tftc
*/
private void repaint(TextFieldTreeCell<Node> tftc) {
Node n = tftc.getItem();
private void repaint(TextFieldTreeCell<NodeOrString> tftc) {
Node n = ((TNode) tftc.getItem()).node;
tftc.setStyle("");
if (n != null) {
if (n.isClosed()) {
......@@ -200,41 +208,58 @@ public class ProofTree extends BorderPane {
public ObjectProperty<Proof> proofProperty() {
return proof;
}
}
class TreeItemNode extends TreeItem<Node> {
static class NodeOrString {
}
@AllArgsConstructor
static class TNode extends NodeOrString {
Node node;
}
@AllArgsConstructor
static class TString extends NodeOrString {
String label;
}
}
class TreeItemNode extends TreeItem<Node> {
class TreeItemNode extends TreeItem<ProofTree.NodeOrString> {
public TreeItemNode(Node value) {
super(value);
super(new ProofTree.TNode(value));
}
@Override
public boolean isLeaf() {
return value.get().childrenCount() <= 1;
return ((ProofTree.TNode) getValue()).node.childrenCount() <= 1;
}
@Override
public ObservableList<TreeItem<Node>> getChildren() {
ObservableList<TreeItemNode> list = FXCollections.observableArrayList();
if (isLeaf())
return list;
public ObservableList<TreeItem<ProofTree.NodeOrString>> getChildren() {
ObservableList<TreeItem<ProofTree.NodeOrString>> list = FXCollections.observableArrayList();
Node n = ((ProofTree.TNode) getValue()).node;
if (value.get().childrenCount() == 1) {
val node = value.get().child(0);
if (isLeaf()) return list;
if (n.childrenCount() == 1) {
val node = n.child(0);
list.add(new TreeItemNode(node));
while (node.childrenCount() == 1) {
val node = node.child(0);
list.add(new TreeItemNode(node));
Node c = node.child(0);
list.add(new TreeItemNode(c));
}
} else {
for (Node child : value.get().children()) {
val ti = new TreeItem<String>(child.getNodeInfo().getBranchLabel());
for (Node child : n.children()) {
val ti = new TreeItemString(child.getNodeInfo().getBranchLabel());
list.add(ti);
ti.getChildren().add(new TreeItemNode(child));
}
}
return list;
}
}
class TreeItemString extends TreeItem<ProofTree.NodeOrString> {
public TreeItemString(String branchLabel) {
super(new ProofTree.TString(branchLabel));
}
}
\ No newline at end of file
......@@ -5,8 +5,8 @@ import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
import de.uka.ilkd.key.logic.SequentFormula;
import edu.kit.iti.formal.psdbg.gui.controller.Events;
import edu.kit.iti.formal.psdbg.gui.model.Breakpoint;
import edu.kit.iti.formal.psdbg.gui.model.MainScriptIdentifier;
import edu.kit.iti.formal.psdbg.interpreter.dbg.Breakpoint;
import edu.kit.iti.formal.psdbg.lint.LintProblem;
import edu.kit.iti.formal.psdbg.lint.LinterStrategy;
import edu.kit.iti.formal.psdbg.parser.Facade;
......@@ -63,6 +63,7 @@ import java.util.function.UnaryOperator;
*/
public class ScriptArea extends CodeArea {
public static final Logger LOGGER = LogManager.getLogger(ScriptArea.class);
public static final String EXECUTION_MARKER = "\u2316";
/**
......@@ -86,13 +87,18 @@ public class ScriptArea extends CodeArea {
private final ObjectProperty<MainScriptIdentifier> mainScript = new SimpleObjectProperty<>();
private GutterFactory gutter;
private ANTLR4LexerHighlighter highlighter;
private ListProperty<LintProblem> problems = new SimpleListProperty<>(FXCollections.observableArrayList());
private SimpleObjectProperty<CharacterHit> currentMouseOver = new SimpleObjectProperty<>();
private ScriptAreaContextMenu contextMenu = new ScriptAreaContextMenu();
private Consumer<Token> onPostMortem = token -> {
};
private int getTextWithoutMarker;
public ScriptArea() {
......@@ -124,7 +130,6 @@ public class ScriptArea extends CodeArea {
});
markedRegions.addListener((InvalidationListener) o -> updateHighlight());
/* .successionEnds(Duration.ofMillis(100))
......@@ -331,7 +336,7 @@ public class ScriptArea extends CodeArea {
int line = 1;
for (GutterAnnotation s : gutter.lineAnnotations) {
if (s.isBreakpoint()) {
Breakpoint b = new Breakpoint(filePath.get(), line);
Breakpoint b = new Breakpoint(filePath.get().toString(), line);
b.setCondition(s.getBreakpointCondition());
list.add(b);
}
......@@ -469,6 +474,7 @@ public class ScriptArea extends CodeArea {
private MaterialDesignIconView iconMainScript = new MaterialDesignIconView(
MaterialDesignIcon.SQUARE_INC, "12"
);
private MaterialDesignIconView iconBreakPoint = new MaterialDesignIconView(
MaterialDesignIcon.STOP_CIRCLE_OUTLINE, "12"
);
......@@ -516,6 +522,10 @@ public class ScriptArea extends CodeArea {
return annotation.get();
}
public void setAnnotation(GutterAnnotation annotation) {
this.annotation.set(annotation);
}
private void addPlaceholder() {
Label lbl = new Label();
lbl.setMinWidth(12);
......@@ -523,10 +533,6 @@ public class ScriptArea extends CodeArea {
getChildren().add(lbl);
}
public void setAnnotation(GutterAnnotation annotation) {
this.annotation.set(annotation);
}
public SimpleObjectProperty<GutterAnnotation> annotationProperty() {
return annotation;
}
......@@ -534,9 +540,13 @@ public class ScriptArea extends CodeArea {
private static class GutterAnnotation {
private StringProperty text = new SimpleStringProperty();
private SimpleBooleanProperty breakpoint = new SimpleBooleanProperty();
private StringProperty breakpointCondition = new SimpleStringProperty();
private BooleanBinding conditional = breakpointCondition.isNotNull().and(breakpointCondition.isNotEmpty());
private BooleanProperty mainScript = new SimpleBooleanProperty();
public String getText() {
......@@ -624,15 +634,20 @@ public class ScriptArea extends CodeArea {
@Data
public static class RegionStyle {
public final int start, stop;
public final String clazzName;
}
public class GutterFactory implements IntFunction<Node> {
private final Background defaultBackground =
new Background(new BackgroundFill(Color.web("#ddd"), null, null));
private final Val<Integer> nParagraphs;
private Insets defaultInsets = new Insets(0.0, 5.0, 0.0, 5.0);
private Paint defaultTextFill = Color.web("#666");
private Font defaultFont = Font.font("monospace", FontPosture.ITALIC, 13);
private ObservableList<GutterAnnotation> lineAnnotations =
......
......@@ -4,8 +4,8 @@ import com.google.common.eventbus.Subscribe;
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIcon;
import de.jensd.fx.glyphs.materialdesignicons.MaterialDesignIconView;
import edu.kit.iti.formal.psdbg.gui.controller.Events;
import edu.kit.iti.formal.psdbg.gui.model.Breakpoint;
import edu.kit.iti.formal.psdbg.gui.model.MainScriptIdentifier;
import edu.kit.iti.formal.psdbg.interpreter.dbg.Breakpoint;
import edu.kit.iti.formal.psdbg.parser.Facade;
import edu.kit.iti.formal.psdbg.parser.ast.ASTNode;
import edu.kit.iti.formal.psdbg.parser.ast.ProofScript;
......@@ -36,11 +36,17 @@ import java.util.*;
*/
public class ScriptController {
public static final String LINE_HIGHLIGHT_POSTMORTEM = "line-highlight-postmortem";
private static Logger logger = LogManager.getLogger(ScriptController.class);
private final DockPane parent;
private final ObservableMap<ScriptArea, DockNode> openScripts = FXCollections.observableMap(new HashMap<>());
private ObjectProperty<MainScriptIdentifier> mainScript = new SimpleObjectProperty<>();
private ScriptArea lastScriptArea;
private ASTNodeHighlighter postMortemHighlighter = new ASTNodeHighlighter(LINE_HIGHLIGHT_POSTMORTEM);
......@@ -49,7 +55,8 @@ public class ScriptController {
Events.register(this);
}
@Subscribe public void handle(Events.FocusScriptArea fsa) {
@Subscribe
public void handle(Events.FocusScriptArea fsa) {
logger.debug("FocusScriptArea handled!");
openScripts.get(fsa.getScriptArea()).focus();
fsa.getScriptArea().requestFocus();
......@@ -176,6 +183,7 @@ public class ScriptController {
/**
* Get all breakpoints in the current area
*