Commit 61e259a6 authored by Alexander Weigl's avatar Alexander Weigl
Browse files

Taclet apps in rule context menu

parent f1bf6cce
...@@ -55,8 +55,8 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -55,8 +55,8 @@ public class DebuggerMainWindowController implements Initializable {
private final ProofTreeController proofTreeController = new ProofTreeController(); private final ProofTreeController proofTreeController = new ProofTreeController();
private final InspectionViewsController inspectionViewsController = new InspectionViewsController(); private final InspectionViewsController inspectionViewsController = new InspectionViewsController();
private final ExecutorService executorService = Executors.newFixedThreadPool(2); private final ExecutorService executorService = Executors.newFixedThreadPool(2);
private final KeYProofFacade facade = new KeYProofFacade(); public static final KeYProofFacade FACADE = new KeYProofFacade();
private final ContractLoaderService contractLoaderService = new ContractLoaderService(); public final ContractLoaderService contractLoaderService = new ContractLoaderService();
/** /**
* Property: current loaded javaFile * Property: current loaded javaFile
*/ */
...@@ -89,7 +89,7 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -89,7 +89,7 @@ public class DebuggerMainWindowController implements Initializable {
/** /**
* True, iff the execution is not possible * True, iff the execution is not possible
*/ */
private ObservableBooleanValue executeNotPossible = proofTreeController.executeNotPossibleProperty().or(facade.readyToExecuteProperty().not()); private ObservableBooleanValue executeNotPossible = proofTreeController.executeNotPossibleProperty().or(FACADE.readyToExecuteProperty().not());
/** /**
* *
...@@ -117,7 +117,6 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -117,7 +117,6 @@ public class DebuggerMainWindowController implements Initializable {
//statusBar.publishMessage("File: " + (newValue != null ? newValue.getAbsolutePath() : "n/a")); //statusBar.publishMessage("File: " + (newValue != null ? newValue.getAbsolutePath() : "n/a"));
//Debugging //Debugging
Utils.addDebugListener(javaCode); Utils.addDebugListener(javaCode);
Utils.addDebugListener(executeNotPossible, "executeNotPossible"); Utils.addDebugListener(executeNotPossible, "executeNotPossible");
...@@ -186,12 +185,12 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -186,12 +185,12 @@ public class DebuggerMainWindowController implements Initializable {
//region Actions: Execution //region Actions: Execution
@FXML @FXML
public void executeScript() { public void executeScript() {
executeScript(facade.buildInterpreter(), false); executeScript(FACADE.buildInterpreter(), false);
} }
@FXML @FXML
public void executeScriptFromCursor() { public void executeScriptFromCursor() {
InterpreterBuilder ib = facade.buildInterpreter(); InterpreterBuilder ib = FACADE.buildInterpreter();
// ib.inheritState(interpreterService.interpreterProperty().get()); // ib.inheritState(interpreterService.interpreterProperty().get());
///* ///*
// LineMapping lm = new LineMapping(scriptArea.getText()); // LineMapping lm = new LineMapping(scriptArea.getText());
...@@ -204,7 +203,7 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -204,7 +203,7 @@ public class DebuggerMainWindowController implements Initializable {
@FXML @FXML
public void executeInDebugMode() { public void executeInDebugMode() {
executeScript(facade.buildInterpreter(), true); executeScript(FACADE.buildInterpreter(), true);
} }
//endregion //endregion
...@@ -271,7 +270,7 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -271,7 +270,7 @@ public class DebuggerMainWindowController implements Initializable {
public void openScript(File scriptFile) { public void openScript(File scriptFile) {
assert scriptFile != null; assert scriptFile != null;
setInitialDirectory(scriptFile.getParentFile() ); setInitialDirectory(scriptFile.getParentFile());
try { try {
String code = FileUtils.readFileToString(scriptFile, Charset.defaultCharset()); String code = FileUtils.readFileToString(scriptFile, Charset.defaultCharset());
ScriptArea area = scriptController.createNewTab(scriptFile); ScriptArea area = scriptController.createNewTab(scriptFile);
...@@ -291,10 +290,10 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -291,10 +290,10 @@ public class DebuggerMainWindowController implements Initializable {
if (keyFile != null) { if (keyFile != null) {
setKeyFile(keyFile); setKeyFile(keyFile);
setInitialDirectory(keyFile.getParentFile()); setInitialDirectory(keyFile.getParentFile());
Task<Void> task = facade.loadKeyFileTask(keyFile); Task<Void> task = FACADE.loadKeyFileTask(keyFile);
task.setOnSucceeded(event -> { task.setOnSucceeded(event -> {
statusBar.publishMessage("Loaded key sourceName: %s", keyFile); statusBar.publishMessage("Loaded key sourceName: %s", keyFile);
getInspectionViewsController().getActiveInspectionViewTab().getModel().getGoals().setAll(facade.getPseudoGoals()); getInspectionViewsController().getActiveInspectionViewTab().getModel().getGoals().setAll(FACADE.getPseudoGoals());
}); });
task.setOnFailed(event -> { task.setOnFailed(event -> {
...@@ -335,6 +334,7 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -335,6 +334,7 @@ public class DebuggerMainWindowController implements Initializable {
loadJavaFile(); loadJavaFile();
showCodeDock(null); showCodeDock(null);
} }
/** /**
* Creates a filechooser dialog * Creates a filechooser dialog
* *
...@@ -385,7 +385,7 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -385,7 +385,7 @@ public class DebuggerMainWindowController implements Initializable {
public KeYProofFacade getFacade() { public KeYProofFacade getFacade() {
return facade; return FACADE;
} }
//region Property //region Property
...@@ -552,7 +552,7 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -552,7 +552,7 @@ public class DebuggerMainWindowController implements Initializable {
public class ContractLoaderService extends Service<List<Contract>> { public class ContractLoaderService extends Service<List<Contract>> {
@Override @Override
protected Task<List<Contract>> createTask() { protected Task<List<Contract>> createTask() {
return facade.getContractsForJavaFileTask(getJavaFile()); return FACADE.getContractsForJavaFileTask(getJavaFile());
} }
@Override @Override
...@@ -564,13 +564,13 @@ public class DebuggerMainWindowController implements Initializable { ...@@ -564,13 +564,13 @@ public class DebuggerMainWindowController implements Initializable {
protected void succeeded() { protected void succeeded() {
statusBar.publishMessage("Contract loaded"); statusBar.publishMessage("Contract loaded");
List<Contract> contracts = getValue(); List<Contract> contracts = getValue();
ContractChooser cc = new ContractChooser(facade.getService(), contracts); ContractChooser cc = new ContractChooser(FACADE.getService(), contracts);
cc.showAndWait().ifPresent(result -> { cc.showAndWait().ifPresent(result -> {
setChosenContract(result); setChosenContract(result);
try { try {
facade.activateContract(result); FACADE.activateContract(result);
getInspectionViewsController().getActiveInspectionViewTab().getModel().getGoals().setAll(facade.getPseudoGoals()); getInspectionViewsController().getActiveInspectionViewTab().getModel().getGoals().setAll(FACADE.getPseudoGoals());
} catch (ProofInputException e) { } catch (ProofInputException e) {
Utils.showExceptionDialog("", "", "", e); Utils.showExceptionDialog("", "", "", e);
} }
......
...@@ -43,7 +43,7 @@ public class InspectionView extends BorderPane { ...@@ -43,7 +43,7 @@ public class InspectionView extends BorderPane {
(observable, oldValue, newValue) -> { (observable, oldValue, newValue) -> {
goalView.getSelectionModel().select(newValue); goalView.getSelectionModel().select(newValue);
if (newValue != null && newValue.getData() != null) { if (newValue != null && newValue.getData() != null) {
getSequentView().setNode(newValue.getData().getNode()); getSequentView().setNode(newValue.getData().getGoal());
// TODO weigl: get marked lines of the program, and set it // TODO weigl: get marked lines of the program, and set it
model.get().highlightedJavaLinesProperty().get() model.get().highlightedJavaLinesProperty().get()
.clear(); .clear();
......
...@@ -4,10 +4,12 @@ import de.uka.ilkd.key.java.Services; ...@@ -4,10 +4,12 @@ import de.uka.ilkd.key.java.Services;
import de.uka.ilkd.key.logic.NamespaceSet; import de.uka.ilkd.key.logic.NamespaceSet;
import de.uka.ilkd.key.logic.Sequent; import de.uka.ilkd.key.logic.Sequent;
import de.uka.ilkd.key.pp.*; import de.uka.ilkd.key.pp.*;
import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Goal;
import de.uka.ilkd.key.settings.ProofIndependentSettings; import de.uka.ilkd.key.settings.ProofIndependentSettings;
import edu.kit.formal.interpreter.KeYProofFacade;
import javafx.beans.Observable; import javafx.beans.Observable;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
...@@ -26,7 +28,9 @@ public class SequentView extends CodeArea { ...@@ -26,7 +28,9 @@ public class SequentView extends CodeArea {
private LogicPrinter lp; private LogicPrinter lp;
private IdentitySequentPrintFilter filter; private IdentitySequentPrintFilter filter;
private LogicPrinter.PosTableStringBackend backend; private LogicPrinter.PosTableStringBackend backend;
private SimpleObjectProperty<de.uka.ilkd.key.proof.Node> node = new SimpleObjectProperty<>(); private SimpleObjectProperty<de.uka.ilkd.key.proof.Goal> node = new SimpleObjectProperty<>();
private KeYProofFacade keYProofFacade;
private TacletContextMenu menu;
public SequentView() { public SequentView() {
...@@ -34,11 +38,11 @@ public class SequentView extends CodeArea { ...@@ -34,11 +38,11 @@ public class SequentView extends CodeArea {
setEditable(false); setEditable(false);
node.addListener(this::update); node.addListener(this::update);
setOnMouseMoved(this::hightlight); setOnMouseMoved(this::hightlight);
setOnMouseClicked(this::onMouseClick);
} }
private void hightlight(MouseEvent mouseEvent) { private void hightlight(MouseEvent mouseEvent) {
if (backend == null) return; if (backend == null) return;
CharacterHit hit = hit(mouseEvent.getX(), mouseEvent.getY()); CharacterHit hit = hit(mouseEvent.getX(), mouseEvent.getY());
int insertionPoint = hit.getInsertionIndex(); int insertionPoint = hit.getInsertionIndex();
PosInSequent pis = backend.getInitialPositionTable().getPosInSequent(insertionPoint, filter); PosInSequent pis = backend.getInitialPositionTable().getPosInSequent(insertionPoint, filter);
...@@ -51,14 +55,26 @@ public class SequentView extends CodeArea { ...@@ -51,14 +55,26 @@ public class SequentView extends CodeArea {
mouseEvent.consume(); mouseEvent.consume();
} }
public void mouseClick(MouseEvent e) { public void onMouseClick(MouseEvent e) {
if (menu != null && menu.isShowing()) {
menu.hide();
}
if (backend == null) { if (backend == null) {
return; return;
} }
CharacterHit hit = hit(e.getX(), e.getY()); if (e.getButton() == MouseButton.SECONDARY) {
int insertionPoint = hit.getInsertionIndex(); CharacterHit hit = hit(e.getX(), e.getY());
PosInSequent pis = backend.getInitialPositionTable().getPosInSequent(insertionPoint, filter); int insertionPoint = hit.getInsertionIndex();
PosInSequent pis = backend.getInitialPositionTable().getPosInSequent(insertionPoint, filter);
if (pis == null) return;
menu = new TacletContextMenu(keYProofFacade, pis, node.get());
menu.setAutoFix(true);
menu.setAutoHide(true);
menu.show(this, e.getScreenX(), e.getScreenY());
e.consume();
}
/* /*
Goal g = new Goal(node, null); Goal g = new Goal(node, null);
ImmutableList<NoPosTacletApp> rules = g.ruleAppIndex().getFindTaclet(new TacletFilter() { ImmutableList<NoPosTacletApp> rules = g.ruleAppIndex().getFindTaclet(new TacletFilter() {
...@@ -109,21 +125,29 @@ public class SequentView extends CodeArea { ...@@ -109,21 +125,29 @@ public class SequentView extends CodeArea {
clear(); clear();
insertText(0, backend.getString()); insertText(0, backend.getString());
if (node.get().isClosed()) { if (node.get().node().isClosed()) {
this.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT))); this.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
this.getStyleClass().add("closed-sequent-view"); this.getStyleClass().add("closed-sequent-view");
} }
} }
public Node getNode() { public Goal getNode() {
return node.get(); return node.get();
} }
public void setNode(Node node) { public SimpleObjectProperty<Goal> nodeProperty() {
return node;
}
public void setNode(Goal node) {
this.node.set(node); this.node.set(node);
} }
public SimpleObjectProperty<Node> nodeProperty() { public KeYProofFacade getKeYProofFacade() {
return node; return keYProofFacade;
}
public void setKeYProofFacade(KeYProofFacade keYProofFacade) {
this.keYProofFacade = keYProofFacade;
} }
} }
package edu.kit.formal.gui.controls;
import de.uka.ilkd.key.control.ProofControl;
import de.uka.ilkd.key.gui.nodeviews.TacletMenu.TacletAppComparator;
import de.uka.ilkd.key.logic.Name;
import de.uka.ilkd.key.logic.PosInOccurrence;
import de.uka.ilkd.key.logic.Term;
import de.uka.ilkd.key.pp.AbbrevMap;
import de.uka.ilkd.key.pp.NotationInfo;
import de.uka.ilkd.key.pp.PosInSequent;
import de.uka.ilkd.key.proof.Goal;
import de.uka.ilkd.key.rule.*;
import edu.kit.formal.gui.controller.DebuggerMainWindowController;
import edu.kit.formal.interpreter.KeYProofFacade;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextInputDialog;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import org.key_project.util.collection.ImmutableList;
import org.key_project.util.collection.ImmutableSLList;
import java.util.*;
import java.util.stream.Collectors;
/**
* Copied from TacletMenu and adapted to JavaFX style. This is NOT a menu
* anymore but a view controller. There is a field rootMenu to access the actual
* menu.
*
* @author Victor Schuemmer
* @author Alexander Weigl
* @version 1.0
* @see de.uka.ilkd.key.gui.nodeviews.TacletMenu
*/
public class TacletContextMenu extends ContextMenu {
private static final Set<Name> CLUTTER_RULESETS = new LinkedHashSet<Name>();
static {
CLUTTER_RULESETS.add(new Name("notHumanReadable"));
CLUTTER_RULESETS.add(new Name("obsolete"));
CLUTTER_RULESETS.add(new Name("pullOutQuantifierAll"));
CLUTTER_RULESETS.add(new Name("pullOutQuantifierEx"));
}
private static final Set<Name> CLUTTER_RULES = new LinkedHashSet<Name>();
static {
CLUTTER_RULES.add(new Name("cut_direct_r"));
CLUTTER_RULES.add(new Name("cut_direct_l"));
CLUTTER_RULES.add(new Name("case_distinction_r"));
CLUTTER_RULES.add(new Name("case_distinction_l"));
CLUTTER_RULES.add(new Name("local_cut"));
CLUTTER_RULES.add(new Name("commute_and_2"));
CLUTTER_RULES.add(new Name("commute_or_2"));
CLUTTER_RULES.add(new Name("boxToDiamond"));
CLUTTER_RULES.add(new Name("pullOut"));
CLUTTER_RULES.add(new Name("typeStatic"));
CLUTTER_RULES.add(new Name("less_is_total"));
CLUTTER_RULES.add(new Name("less_zero_is_total"));
CLUTTER_RULES.add(new Name("applyEqReverse"));
// the following are used for drag'n'drop interactions
CLUTTER_RULES.add(new Name("eqTermCut"));
CLUTTER_RULES.add(new Name("instAll"));
CLUTTER_RULES.add(new Name("instEx"));
}
private PosInSequent pos;
@FXML
private ContextMenu rootMenu;
@FXML
private MenuItem noRules;
@FXML
private Menu moreRules;
@FXML
private Menu insertHidden;
@FXML
private MenuItem copyToClipboard;
@FXML
private MenuItem createAbbr;
@FXML
private MenuItem enableAbbr;
@FXML
private MenuItem disableAbbr;
@FXML
private MenuItem changeAbbr;
private Goal goal;
private PosInOccurrence occ;
private NotationInfo notationInfo = new NotationInfo();
public TacletContextMenu(KeYProofFacade keYProofFacade, PosInSequent pos, Goal goal) {
Utils.createWithFXML(this);
/*mediator = getContext().getKeYMediator();
comp = new TacletAppComparator();
insertHiddenController.initViewController(getMainApp(), getContext());
*/
if (pos == null)
throw new IllegalArgumentException(
"Argument pos must not be null.");
this.pos = pos;
this.goal = goal;
occ = pos.getPosInOccurrence();
//MediatorProofControl c = new MediatorProofControl(new DefaultAbstractMediatorUserInterfaceControlAdapter());
ProofControl c = DebuggerMainWindowController.FACADE.getEnvironment().getUi().getProofControl();
final ImmutableList<BuiltInRule> builtInRules = c.getBuiltInRule(goal, occ);
createTacletMenu(
removeRewrites(c.getFindTaclet(goal, occ))
.prepend(c.getRewriteTaclet(goal, occ)),
c.getNoFindTaclet(goal), builtInRules);
//proofMacroMenuController.initViewController(getMainApp(), getContext());
//proofMacroMenuController.init(occ);
}
/**
* Removes RewriteTaclet from the list.
*
* @param list the IList<Taclet> from where the RewriteTaclet are removed
* @return list without RewriteTaclets
*/
private static ImmutableList<TacletApp> removeRewrites(
ImmutableList<TacletApp> list) {
ImmutableList<TacletApp> result = ImmutableSLList.<TacletApp>nil();
Iterator<TacletApp> it = list.iterator();
while (it.hasNext()) {
TacletApp tacletApp = it.next();
Taclet taclet = tacletApp.taclet();
result = (taclet instanceof RewriteTaclet ? result
: result.prepend(tacletApp));
}
return result;
}
/**
* Creates the menu by adding all submenus and items.
*/
private void createTacletMenu(ImmutableList<TacletApp> find,
ImmutableList<TacletApp> noFind,
ImmutableList<BuiltInRule> builtInList) {
List<TacletApp> findTaclets = find.stream().collect(Collectors.toList());
List<TacletApp> noFindTaclets = noFind.stream().collect(Collectors.toList());
Collections.sort(findTaclets,
//compare by name
Comparator.comparing(o -> o.taclet().name())
);
List<TacletApp> toAdd = new ArrayList<>(findTaclets.size() + noFindTaclets.size());
toAdd.addAll(findTaclets);
boolean rulesAvailable = find.size() > 0;
if (pos.isSequent()) {
rulesAvailable |= noFind.size() > 0;
toAdd.addAll(noFindTaclets);
}
if (rulesAvailable) {
createMenuItems(toAdd);
} else {
noRules.setVisible(true);
}
if (occ != null)
createAbbrevSection(pos.getPosInOccurrence().subTerm());
}
/**
* Creates menu items for all given taclets. A submenu for insertion of
* hidden terms will be created if there are any, and rare rules will be in
* a 'More rules' submenu.
*
* @param taclets the list of taclets to create menu items for
*/
private void createMenuItems(List<TacletApp> taclets) {
int idx = 0;
for (final TacletApp app : taclets) {
final Taclet taclet = app.taclet();
/* if (!mediator.getFilterForInteractiveProving().filter(taclet)) {
continue;
}*/
final MenuItem item = new MenuItem(app.taclet().name().toString());
item.setOnAction(event -> {
handleRuleApplication(app);
});
// Items for insertion of hidden terms appear in a submenu.
/*if (insertHiddenController.isResponsible(item)) {
insertHiddenController.add(item);
} else */
{
// If one of the sets contains the rule it is considered rare
// and moved to a 'More rules' submenu.
boolean rareRule = false;
for (RuleSet rs : taclet.getRuleSets()) {
if (CLUTTER_RULESETS.contains(rs.name()))
rareRule = true;
}
if (CLUTTER_RULES.contains(taclet.name()))
rareRule = true;
if (rareRule)
moreRules.getItems().add(item);
else
rootMenu.getItems().add(idx++, item);
}
}
// Make submenus visible iff they are not empty.
if (moreRules.getItems().size() > 0)
moreRules.setVisible(true);
/*if (!insertHiddenController.isEmpty())
insertHiddenController.setVisible(true);
*/
}
/**
public TacletFilter getFilterForInteractiveProving() {
if(this.filterForInteractiveProving == null) {
this.filterForInteractiveProving = new TacletFilter() {
protected boolean filter(Taclet taclet) {
String[] var2 = JoinProcessor.SIMPLIFY_UPDATE;
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
String name = var2[var4];
if(name.equals(taclet.name().toString())) {
return false;
}
}
return true;
}
};
}
return this.filterForInteractiveProving;
}*/
/**
* Manages the visibility of all menu items dealing with abbreviations based
* on if the given term already is abbreviated and if the abbreviation is